diff options
Diffstat (limited to 'src')
627 files changed, 35222 insertions, 21704 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 94a582dfac..d6ac6e1277 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,9 +1,6 @@ +DIST_SUBDIRS = secp256k1 AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) -if USE_LIBSECP256K1 -secp256k1/libsecp256k1.la: $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) - @$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) -endif if EMBEDDED_LEVELDB LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include @@ -23,9 +20,7 @@ endif BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) -if USE_LIBSECP256K1 BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include -endif LIBBITCOIN_SERVER=libbitcoin_server.a LIBBITCOIN_WALLET=libbitcoin_wallet.a @@ -35,19 +30,32 @@ LIBBITCOIN_UTIL=libbitcoin_util.a LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a LIBBITCOIN_UNIVALUE=univalue/libbitcoin_univalue.a LIBBITCOINQT=qt/libbitcoinqt.a +LIBSECP256K1=secp256k1/libsecp256k1.la + +$(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) +# Make is not made aware of per-object dependencies to avoid limiting building parallelization +# But to build the less dependent modules first, we manually select their order here: noinst_LIBRARIES = \ - libbitcoin_server.a \ - libbitcoin_common.a \ - libbitcoin_cli.a \ + crypto/libbitcoin_crypto.a \ libbitcoin_util.a \ + libbitcoin_common.a \ univalue/libbitcoin_univalue.a \ - crypto/libbitcoin_crypto.a + libbitcoin_server.a \ + libbitcoin_cli.a if ENABLE_WALLET BITCOIN_INCLUDES += $(BDB_CPPFLAGS) noinst_LIBRARIES += libbitcoin_wallet.a endif +if BUILD_BITCOIN_LIBS +lib_LTLIBRARIES = libbitcoinconsensus.la +LIBBITCOIN_CONSENSUS=libbitcoinconsensus.la +else +LIBBITCOIN_CONSENSUS= +endif + bin_PROGRAMS = TESTS = @@ -65,8 +73,10 @@ BITCOIN_CORE_H = \ addrman.h \ alert.h \ allocators.h \ + amount.h \ base58.h \ bloom.h \ + chain.h \ chainparams.h \ chainparamsbase.h \ chainparamsseeds.h \ @@ -76,10 +86,14 @@ BITCOIN_CORE_H = \ coincontrol.h \ coins.h \ compat.h \ - core.h \ + compressor.h \ + primitives/block.h \ + primitives/transaction.h \ core_io.h \ crypter.h \ db.h \ + eccryptoverify.h \ + ecwrapper.h \ hash.h \ init.h \ key.h \ @@ -87,6 +101,7 @@ BITCOIN_CORE_H = \ leveldbwrapper.h \ limitedmap.h \ main.h \ + merkleblock.h \ miner.h \ mruset.h \ netbase.h \ @@ -94,16 +109,19 @@ BITCOIN_CORE_H = \ noui.h \ pow.h \ protocol.h \ + pubkey.h \ random.h \ rpcclient.h \ rpcprotocol.h \ rpcserver.h \ - script/compressor.h \ script/interpreter.h \ script/script.h \ + script/sigcache.h \ script/sign.h \ script/standard.h \ + script/script_error.h \ serialize.h \ + streams.h \ sync.h \ threadsafety.h \ timedata.h \ @@ -112,6 +130,7 @@ BITCOIN_CORE_H = \ txmempool.h \ ui_interface.h \ uint256.h \ + undo.h \ util.h \ utilstrencodings.h \ utilmoneystr.h \ @@ -137,7 +156,7 @@ obj/build.h: FORCE @$(MKDIR_P) $(builddir)/obj @$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \ $(abs_top_srcdir) -libbitcoin_util_a-version.$(OBJEXT): obj/build.h +libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h # server: shared between bitcoind and bitcoin-qt libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) @@ -145,20 +164,24 @@ libbitcoin_server_a_SOURCES = \ addrman.cpp \ alert.cpp \ bloom.cpp \ + chain.cpp \ checkpoints.cpp \ init.cpp \ leveldbwrapper.cpp \ main.cpp \ + merkleblock.cpp \ miner.cpp \ net.cpp \ noui.cpp \ pow.cpp \ + rest.cpp \ rpcblockchain.cpp \ rpcmining.cpp \ rpcmisc.cpp \ rpcnet.cpp \ rpcrawtransaction.cpp \ rpcserver.cpp \ + script/sigcache.cpp \ timedata.cpp \ txdb.cpp \ txmempool.cpp \ @@ -182,10 +205,18 @@ libbitcoin_wallet_a_SOURCES = \ crypto_libbitcoin_crypto_a_CPPFLAGS = $(BITCOIN_CONFIG_INCLUDES) crypto_libbitcoin_crypto_a_SOURCES = \ crypto/sha1.cpp \ - crypto/sha2.cpp \ + crypto/sha256.cpp \ + crypto/sha512.cpp \ + crypto/hmac_sha256.cpp \ + crypto/rfc6979_hmac_sha256.cpp \ + crypto/hmac_sha512.cpp \ crypto/ripemd160.cpp \ crypto/common.h \ - crypto/sha2.h \ + crypto/sha256.h \ + crypto/sha512.h \ + crypto/hmac_sha256.h \ + crypto/rfc6979_hmac_sha256.h \ + crypto/hmac_sha512.h \ crypto/sha1.h \ crypto/ripemd160.h @@ -201,22 +232,28 @@ univalue_libbitcoin_univalue_a_SOURCES = \ libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_common_a_SOURCES = \ allocators.cpp \ + amount.cpp \ base58.cpp \ chainparams.cpp \ coins.cpp \ - core.cpp \ + compressor.cpp \ + primitives/block.cpp \ + primitives/transaction.cpp \ core_read.cpp \ core_write.cpp \ + eccryptoverify.cpp \ + ecwrapper.cpp \ hash.cpp \ key.cpp \ keystore.cpp \ netbase.cpp \ protocol.cpp \ - script/compressor.cpp \ + pubkey.cpp \ script/interpreter.cpp \ script/script.cpp \ script/sign.cpp \ script/standard.cpp \ + script/script_error.cpp \ $(BITCOIN_CORE_H) # util: shared between all executables. @@ -224,9 +261,11 @@ libbitcoin_common_a_SOURCES = \ # backward-compatibility objects and their sanity checks are linked. libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_util_a_SOURCES = \ + compat/strnlen.cpp \ compat/glibc_sanity.cpp \ compat/glibcxx_sanity.cpp \ chainparamsbase.cpp \ + clientversion.cpp \ random.cpp \ rpcprotocol.cpp \ sync.cpp \ @@ -235,7 +274,6 @@ libbitcoin_util_a_SOURCES = \ utilstrencodings.cpp \ utilmoneystr.cpp \ utiltime.cpp \ - version.cpp \ $(BITCOIN_CORE_H) if GLIBC_BACK_COMPAT @@ -260,11 +298,8 @@ bitcoind_LDADD = \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) \ $(LIBLEVELDB) \ - $(LIBMEMENV) - -if USE_LIBSECP256K1 - bitcoind_LDADD += secp256k1/libsecp256k1.la -endif + $(LIBMEMENV) \ + $(LIBSECP256K1) if ENABLE_WALLET bitcoind_LDADD += libbitcoin_wallet.a @@ -276,16 +311,14 @@ if TARGET_WINDOWS bitcoind_SOURCES += bitcoind-res.rc endif -bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) +bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES) -bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) +bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) # bitcoin-cli binary # bitcoin_cli_LDADD = \ $(LIBBITCOIN_CLI) \ - $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ - $(LIBBITCOIN_CRYPTO) \ $(BOOST_LIBS) \ $(SSL_LIBS) \ $(CRYPTO_LIBS) @@ -293,9 +326,6 @@ bitcoin_cli_LDADD = \ bitcoin_cli_SOURCES = \ bitcoin-cli.cpp -if USE_LIBSECP256K1 - bitcoin_cli_LDADD += secp256k1/libsecp256k1.la -endif bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES) # @@ -304,40 +334,68 @@ bitcoin_tx_LDADD = \ $(LIBBITCOIN_UNIVALUE) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ - $(LIBBITCOIN_CRYPTO) - -if USE_LIBSECP256K1 - bitcoin_tx_LDADD += secp256k1/libsecp256k1.la -endif - - bitcoin_tx_LDADD += $(BOOST_LIBS) \ - $(SSL_LIBS) \ + $(LIBBITCOIN_CRYPTO) \ + $(LIBSECP256K1) \ + $(BOOST_LIBS) \ $(CRYPTO_LIBS) + bitcoin_tx_SOURCES = bitcoin-tx.cpp bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES) # -bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) +bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS bitcoin_cli_SOURCES += bitcoin-cli-res.rc endif -bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) +bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) + +if BUILD_BITCOIN_LIBS +include_HEADERS = script/bitcoinconsensus.h +libbitcoinconsensus_la_SOURCES = \ + primitives/transaction.cpp \ + crypto/hmac_sha512.cpp \ + crypto/sha1.cpp \ + crypto/sha256.cpp \ + crypto/sha512.cpp \ + crypto/ripemd160.cpp \ + eccryptoverify.cpp \ + ecwrapper.cpp \ + hash.cpp \ + pubkey.cpp \ + script/script.cpp \ + script/interpreter.cpp \ + script/bitcoinconsensus.cpp \ + uint256.cpp \ + utilstrencodings.cpp + +if GLIBC_BACK_COMPAT + libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp + libbitcoinconsensus_la_SOURCES += compat/glibcxx_compat.cpp +endif + +libbitcoinconsensus_la_LDFLAGS = -no-undefined $(RELDFLAGS) +libbitcoinconsensus_la_LIBADD = $(CRYPTO_LIBS) +libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BITCOIN_INTERNAL +if USE_LIBSECP256K1 +libbitcoinconsensus_la_LIBADD += secp256k1/libsecp256k1.la +endif +endif CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno DISTCLEANFILES = obj/build.h -EXTRA_DIST = leveldb secp256k1 +EXTRA_DIST = leveldb clean-local: -$(MAKE) -C leveldb clean - -$(MAKE) -C secp256k1 clean 2>/dev/null + -$(MAKE) -C secp256k1 clean rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno -rm -f config.h .rc.o: @test -f $(WINDRES) - $(AM_V_GEN) $(WINDRES) -i $< -o $@ + $(AM_V_GEN) $(WINDRES) -DWINDRES_PREPROC -i $< -o $@ .mm.o: $(AM_V_CXX) $(OBJCXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 1ea039adb3..f31f128319 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -110,7 +110,6 @@ QT_MOC_CPP = \ qt/moc_intro.cpp \ qt/moc_macdockiconhandler.cpp \ qt/moc_macnotificationhandler.cpp \ - qt/moc_monitoreddatamapper.cpp \ qt/moc_notificator.cpp \ qt/moc_openuridialog.cpp \ qt/moc_optionsdialog.cpp \ @@ -177,7 +176,7 @@ BITCOIN_QT_H = \ qt/intro.h \ qt/macdockiconhandler.h \ qt/macnotificationhandler.h \ - qt/monitoreddatamapper.h \ + qt/networkstyle.h \ qt/notificator.h \ qt/openuridialog.h \ qt/optionsdialog.h \ @@ -192,6 +191,7 @@ BITCOIN_QT_H = \ qt/receiverequestdialog.h \ qt/recentrequeststablemodel.h \ qt/rpcconsole.h \ + qt/scicon.h \ qt/sendcoinsdialog.h \ qt/sendcoinsentry.h \ qt/signverifymessagedialog.h \ @@ -213,21 +213,21 @@ BITCOIN_QT_H = \ RES_ICONS = \ qt/res/icons/add.png \ qt/res/icons/address-book.png \ + qt/res/icons/about.png \ + qt/res/icons/about_qt.png \ qt/res/icons/bitcoin.ico \ qt/res/icons/bitcoin.png \ - qt/res/icons/bitcoin_testnet.ico \ - qt/res/icons/bitcoin_testnet.png \ qt/res/icons/clock1.png \ qt/res/icons/clock2.png \ qt/res/icons/clock3.png \ qt/res/icons/clock4.png \ qt/res/icons/clock5.png \ qt/res/icons/configure.png \ - qt/res/icons/connect0_16.png \ - qt/res/icons/connect1_16.png \ - qt/res/icons/connect2_16.png \ - qt/res/icons/connect3_16.png \ - qt/res/icons/connect4_16.png \ + qt/res/icons/connect0.png \ + qt/res/icons/connect1.png \ + qt/res/icons/connect2.png \ + qt/res/icons/connect3.png \ + qt/res/icons/connect4.png \ qt/res/icons/debugwindow.png \ qt/res/icons/edit.png \ qt/res/icons/editcopy.png \ @@ -238,11 +238,12 @@ RES_ICONS = \ qt/res/icons/eye_plus.png \ qt/res/icons/filesave.png \ qt/res/icons/history.png \ + qt/res/icons/info.png \ qt/res/icons/key.png \ qt/res/icons/lock_closed.png \ qt/res/icons/lock_open.png \ + qt/res/icons/open.png \ qt/res/icons/overview.png \ - qt/res/icons/qrcode.png \ qt/res/icons/quit.png \ qt/res/icons/receive.png \ qt/res/icons/remove.png \ @@ -257,7 +258,8 @@ RES_ICONS = \ qt/res/icons/tx_mined.png \ qt/res/icons/unit_btc.png \ qt/res/icons/unit_mbtc.png \ - qt/res/icons/unit_ubtc.png + qt/res/icons/unit_ubtc.png \ + qt/res/icons/verify.png BITCOIN_QT_CPP = \ qt/bitcoinaddressvalidator.cpp \ @@ -268,7 +270,7 @@ BITCOIN_QT_CPP = \ qt/csvmodelwriter.cpp \ qt/guiutil.cpp \ qt/intro.cpp \ - qt/monitoreddatamapper.cpp \ + qt/networkstyle.cpp \ qt/notificator.cpp \ qt/optionsdialog.cpp \ qt/optionsmodel.cpp \ @@ -276,10 +278,14 @@ BITCOIN_QT_CPP = \ qt/qvalidatedlineedit.cpp \ qt/qvaluecombobox.cpp \ qt/rpcconsole.cpp \ + qt/scicon.cpp \ qt/splashscreen.cpp \ qt/trafficgraphwidget.cpp \ - qt/utilitydialog.cpp \ - qt/winshutdownmonitor.cpp + qt/utilitydialog.cpp + +if TARGET_WINDOWS +BITCOIN_QT_CPP += qt/winshutdownmonitor.cpp +endif if ENABLE_WALLET BITCOIN_QT_CPP += \ @@ -312,9 +318,7 @@ BITCOIN_QT_CPP += \ endif RES_IMAGES = \ - qt/res/images/about.png \ - qt/res/images/splash.png \ - qt/res/images/splash_testnet.png + qt/res/images/about.png RES_MOVIES = $(wildcard qt/res/movies/spinner-*.png) @@ -361,16 +365,14 @@ if ENABLE_WALLET qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET) 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) -if USE_LIBSECP256K1 - qt_bitcoin_qt_LDADD += secp256k1/libsecp256k1.la -endif -qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) + $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) +qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +qt_bitcoin_qt_LIBTOOLFLAGS = --tag CXX #locale/foo.ts -> locale/foo.qm QT_QM=$(QT_TS:.ts=.qm) -.SECONDARY: $(QT_QM) +SECONDARY: $(QT_QM) qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES) @test -n $(XGETTEXT) || echo "xgettext is required for updating translations" diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index 2cba5b7e1e..c5392cf307 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -13,7 +13,7 @@ TEST_QT_H = \ qt/test/paymentservertests.h qt_test_test_bitcoin_qt_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ - $(QT_INCLUDES) $(QT_TEST_INCLUDES) + $(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS) qt_test_test_bitcoin_qt_SOURCES = \ qt/test/test_main.cpp \ @@ -32,11 +32,8 @@ qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET) 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) -if USE_LIBSECP256K1 - qt_test_test_bitcoin_qt_LDADD += secp256k1/libsecp256k1.la -endif -qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) + $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) +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 ab449f3e71..c6bd0cf9c6 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -1,4 +1,4 @@ -TESTS += test/test_bitcoin test/bitcoin-util-test.py +TESTS += test/test_bitcoin bin_PROGRAMS += test/test_bitcoin TEST_SRCDIR = test TEST_BINARY=test/test_bitcoin$(EXEEXT) @@ -40,9 +40,9 @@ BITCOIN_TESTS =\ test/base58_tests.cpp \ test/base64_tests.cpp \ test/bloom_tests.cpp \ - test/canonical_tests.cpp \ test/checkblock_tests.cpp \ test/Checkpoints_tests.cpp \ + test/coins_tests.cpp \ test/compress_tests.cpp \ test/crypto_tests.cpp \ test/DoS_tests.cpp \ @@ -58,7 +58,9 @@ BITCOIN_TESTS =\ test/rpc_tests.cpp \ test/script_P2SH_tests.cpp \ test/script_tests.cpp \ + test/scriptnum_tests.cpp \ test/serialize_tests.cpp \ + test/sighash_tests.cpp \ test/sigopcount_tests.cpp \ test/skiplist_tests.cpp \ test/test_bitcoin.cpp \ @@ -66,9 +68,7 @@ BITCOIN_TESTS =\ test/transaction_tests.cpp \ test/uint256_tests.cpp \ test/univalue_tests.cpp \ - test/util_tests.cpp \ - test/scriptnum_tests.cpp \ - test/sighash_tests.cpp + test/util_tests.cpp if ENABLE_WALLET BITCOIN_TESTS += \ @@ -80,17 +80,13 @@ endif test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES) test_test_bitcoin_CPPFLAGS = $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ - $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) + $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) if ENABLE_WALLET test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET) endif -if USE_LIBSECP256K1 - test_test_bitcoin_LDADD += secp256k1/libsecp256k1.la -endif - -test_test_bitcoin_LDADD += $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) -test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) +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 nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES) @@ -108,6 +104,11 @@ bitcoin_test_check: $(TEST_BINARY) FORCE bitcoin_test_clean : FORCE rm -f $(CLEAN_BITCOIN_TEST) $(test_test_bitcoin_OBJECTS) $(TEST_BINARY) +check-local: + @echo "Running test/bitcoin-util-test.py..." + $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check + %.json.h: %.json @$(MKDIR_P) $(@D) @echo "namespace json_tests{" > $@ diff --git a/src/addrman.cpp b/src/addrman.cpp index 7b674a66e7..1982db52ae 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -1,11 +1,12 @@ // Copyright (c) 2012 Pieter Wuille -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "addrman.h" #include "hash.h" #include "serialize.h" +#include "streams.h" using namespace std; @@ -39,7 +40,7 @@ int CAddrInfo::GetNewBucket(const std::vector<unsigned char>& nKey, const CNetAd bool CAddrInfo::IsTerrible(int64_t nNow) const { - if (nLastTry && nLastTry >= nNow - 60) // never remove things tried the last minute + if (nLastTry && nLastTry >= nNow - 60) // never remove things tried in the last minute return false; if (nTime > nNow + 10 * 60) // came in a flying DeLorean @@ -131,7 +132,7 @@ int CAddrMan::SelectTried(int nKBucket) { std::vector<int>& vTried = vvTried[nKBucket]; - // random shuffle the first few elements (using the entire list) + // randomly shuffle the first few elements (using the entire list) // find the least recently tried among them int64_t nOldest = -1; int nOldestPos = -1; @@ -211,7 +212,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) assert(info.nRefCount == 0); - // what tried bucket to move the entry to + // which tried bucket to move the entry to int nKBucket = info.GetTriedBucket(nKey); std::vector<int>& vTried = vvTried[nKBucket]; diff --git a/src/addrman.h b/src/addrman.h index 5fd698f18a..d47217683c 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -1,9 +1,9 @@ // Copyright (c) 2012 Pieter Wuille -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef _BITCOIN_ADDRMAN -#define _BITCOIN_ADDRMAN +#ifndef BITCOIN_ADDRMAN_H +#define BITCOIN_ADDRMAN_H #include "netbase.h" #include "protocol.h" @@ -17,29 +17,31 @@ #include <stdint.h> #include <vector> -/** Extended statistics about a CAddress */ +/** + * Extended statistics about a CAddress + */ class CAddrInfo : public CAddress { private: - // where knowledge about this address first came from + //! where knowledge about this address first came from CNetAddr source; - // last successful connection by us + //! last successful connection by us int64_t nLastSuccess; - // last try whatsoever by us: + //! last try whatsoever by us: // int64_t CAddress::nLastTry - // connection attempts since last successful attempt + //! connection attempts since last successful attempt int nAttempts; - // reference count in new sets (memory only) + //! reference count in new sets (memory only) int nRefCount; - // in tried set? (memory only) + //! in tried set? (memory only) bool fInTried; - // position in vRandom + //! position in vRandom int nRandomPos; friend class CAddrMan; @@ -76,200 +78,205 @@ public: Init(); } - // Calculate in which "tried" bucket this entry belongs + //! Calculate in which "tried" bucket this entry belongs int GetTriedBucket(const std::vector<unsigned char> &nKey) const; - // Calculate in which "new" bucket this entry belongs, given a certain source + //! Calculate in which "new" bucket this entry belongs, given a certain source int GetNewBucket(const std::vector<unsigned char> &nKey, const CNetAddr& src) const; - // Calculate in which "new" bucket this entry belongs, using its default source + //! Calculate in which "new" bucket this entry belongs, using its default source int GetNewBucket(const std::vector<unsigned char> &nKey) const { return GetNewBucket(nKey, source); } - // Determine whether the statistics about this entry are bad enough so that it can just be deleted + //! Determine whether the statistics about this entry are bad enough so that it can just be deleted bool IsTerrible(int64_t nNow = GetAdjustedTime()) const; - // Calculate the relative chance this entry should be given when selecting nodes to connect to + //! Calculate the relative chance this entry should be given when selecting nodes to connect to double GetChance(int64_t nNow = GetAdjustedTime()) const; }; -// Stochastic address manager -// -// Design goals: -// * Only keep a limited number of addresses around, so that addr.dat and memory requirements do not grow without bound. -// * Keep the address tables in-memory, and asynchronously dump the entire to able in addr.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 256 "new" buckets. -// * Based on the address range (/16 for IPv4) of source of the information, 32 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 4 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. -// * Addresses of nodes that are known to be accessible go into 64 "tried" buckets. -// * Each address range selects at random 4 of these buckets. -// * The actual bucket is chosen from one of these, based on the full address. -// * When adding a new good address to a full bucket, a randomly chosen entry (with a bias favoring less recently -// tried ones) is evicted from it, back to the "new" buckets. -// * Bucket selection is based on cryptographic hashing, using a randomly-generated 256-bit key, which should not -// be observable by adversaries. -// * Several indexes are kept for high performance. Defining DEBUG_ADDRMAN will introduce frequent (and expensive) -// consistency checks for the entire data structure. - -// total number of buckets for tried addresses +/** Stochastic address manager + * + * Design goals: + * * Keep the address tables in-memory, and asynchronously dump the entire to able in 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 256 "new" buckets. + * * Based on the address range (/16 for IPv4) of source of the information, 32 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 4 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. + * * Addresses of nodes that are known to be accessible go into 64 "tried" buckets. + * * Each address range selects at random 4 of these buckets. + * * The actual bucket is chosen from one of these, based on the full address. + * * When adding a new good address to a full bucket, a randomly chosen entry (with a bias favoring less recently + * tried ones) is evicted from it, back to the "new" buckets. + * * Bucket selection is based on cryptographic hashing, using a randomly-generated 256-bit key, which should not + * be observable by adversaries. + * * Several indexes are kept for high performance. Defining DEBUG_ADDRMAN will introduce frequent (and expensive) + * consistency checks for the entire data structure. + */ + +//! total number of buckets for tried addresses #define ADDRMAN_TRIED_BUCKET_COUNT 64 -// maximum allowed number of entries in buckets for tried addresses +//! maximum allowed number of entries in buckets for tried addresses #define ADDRMAN_TRIED_BUCKET_SIZE 64 -// total number of buckets for new addresses +//! total number of buckets for new addresses #define ADDRMAN_NEW_BUCKET_COUNT 256 -// maximum allowed number of entries in buckets for new addresses +//! maximum allowed number of entries in buckets for new addresses #define ADDRMAN_NEW_BUCKET_SIZE 64 -// over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread +//! over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread #define ADDRMAN_TRIED_BUCKETS_PER_GROUP 4 -// over how many buckets entries with new addresses originating from a single group are spread +//! over how many buckets entries with new addresses originating from a single group are spread #define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 32 -// in how many buckets for entries with new addresses a single address may occur +//! in how many buckets for entries with new addresses a single address may occur #define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 4 -// how many entries in a bucket with tried addresses are inspected, when selecting one to replace +//! how many entries in a bucket with tried addresses are inspected, when selecting one to replace #define ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT 4 -// how old addresses can maximally be +//! how old addresses can maximally be #define ADDRMAN_HORIZON_DAYS 30 -// after how many failed attempts we give up on a new node +//! after how many failed attempts we give up on a new node #define ADDRMAN_RETRIES 3 -// how many successive failures are allowed ... +//! how many successive failures are allowed ... #define ADDRMAN_MAX_FAILURES 10 -// ... in at least this many days +//! ... in at least this many days #define ADDRMAN_MIN_FAIL_DAYS 7 -// the maximum percentage of nodes to return in a getaddr call +//! the maximum percentage of nodes to return in a getaddr call #define ADDRMAN_GETADDR_MAX_PCT 23 -// the maximum number of nodes to return in a getaddr call +//! the maximum number of nodes to return in a getaddr call #define ADDRMAN_GETADDR_MAX 2500 -/** Stochastical (IP) address manager */ +/** + * Stochastical (IP) address manager + */ class CAddrMan { private: - // critical section to protect the inner data structures + //! critical section to protect the inner data structures mutable CCriticalSection cs; - // secret key to randomize bucket select with + //! secret key to randomize bucket select with std::vector<unsigned char> nKey; - // last used nId + //! last used nId int nIdCount; - // table with information about all nIds + //! table with information about all nIds std::map<int, CAddrInfo> mapInfo; - // find an nId based on its network address + //! find an nId based on its network address std::map<CNetAddr, int> mapAddr; - // randomly-ordered vector of all nIds + //! randomly-ordered vector of all nIds std::vector<int> vRandom; // number of "tried" entries int nTried; - // list of "tried" buckets + //! list of "tried" buckets std::vector<std::vector<int> > vvTried; - // number of (unique) "new" entries + //! number of (unique) "new" entries int nNew; - // list of "new" buckets + //! list of "new" buckets std::vector<std::set<int> > vvNew; protected: - // Find an entry. + //! Find an entry. CAddrInfo* Find(const CNetAddr& addr, int *pnId = NULL); - // find an entry, creating it if necessary. - // nTime and nServices of found node is updated, if necessary. + //! find an entry, creating it if necessary. + //! nTime and nServices of the found node are updated, if necessary. CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = NULL); - // Swap two elements in vRandom. + //! Swap two elements in vRandom. void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2); - // Return position in given bucket to replace. + //! Return position in given bucket to replace. int SelectTried(int nKBucket); - // Remove an element from a "new" bucket. - // This is the only place where actual deletes occur. - // They are never deleted while in the "tried" table, only possibly evicted back to the "new" table. + //! Remove an element from a "new" bucket. + //! This is the only place where actual deletions occur. + //! Elements are never deleted while in the "tried" table, only possibly evicted back to the "new" table. int ShrinkNew(int nUBucket); - // Move an entry from the "new" table(s) to the "tried" table - // @pre vvUnkown[nOrigin].count(nId) != 0 + //! Move an entry from the "new" table(s) to the "tried" table + //! @pre vvUnkown[nOrigin].count(nId) != 0 void MakeTried(CAddrInfo& info, int nId, int nOrigin); - // Mark an entry "good", possibly moving it from "new" to "tried". + //! Mark an entry "good", possibly moving it from "new" to "tried". void Good_(const CService &addr, int64_t nTime); - // Add an entry to the "new" table. + //! Add an entry to the "new" table. bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty); - // Mark an entry as attempted to connect. + //! Mark an entry as attempted to connect. 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) + //! Select an address to connect to. + //! nUnkBias determines how much to favor new addresses over tried ones (min=0, max=100) CAddress Select_(int nUnkBias); #ifdef DEBUG_ADDRMAN - // Perform consistency check. Returns an error code or zero. + //! Perform consistency check. Returns an error code or zero. int Check_(); #endif - // Select several addresses at once. + //! Select several addresses at once. void GetAddr_(std::vector<CAddress> &vAddr); - // Mark an entry as currently-connected-to. + //! Mark an entry as currently-connected-to. void Connected_(const CService &addr, int64_t nTime); public: - // serialized format: - // * version byte (currently 0) - // * nKey - // * nNew - // * nTried - // * number of "new" buckets - // * all nNew addrinfos in vvNew - // * all nTried addrinfos in vvTried - // * for each bucket: - // * number of elements - // * for each element: index - // - // 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, - // otherwise it is reconstructed as well. - // - // This format is more complex, but significantly smaller (at most 1.5 MiB), and supports - // changes to the ADDRMAN_ parameters without breaking the on-disk structure. - // - // We don't use ADD_SERIALIZE_METHODS since the serialization and deserialization code has - // very little in common. + /** + * serialized format: + * * version byte (currently 0) + * * nKey + * * nNew + * * nTried + * * number of "new" buckets + * * all nNew addrinfos in vvNew + * * all nTried addrinfos in vvTried + * * for each bucket: + * * number of elements + * * for each element: index + * + * 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, + * otherwise it is reconstructed as well. + * + * This format is more complex, but significantly smaller (at most 1.5 MiB), and supports + * changes to the ADDRMAN_ parameters without breaking the on-disk structure. + * + * We don't use ADD_SERIALIZE_METHODS since the serialization and deserialization code has + * very little in common. + * + */ template<typename Stream> void Serialize(Stream &s, int nType, int nVersionDummy) const { @@ -394,13 +401,13 @@ public: nNew = 0; } - // Return the number of (unique) addresses in all tables. + //! Return the number of (unique) addresses in all tables. int size() { return vRandom.size(); } - // Consistency check + //! Consistency check void Check() { #ifdef DEBUG_ADDRMAN @@ -413,7 +420,7 @@ public: #endif } - // Add a single address. + //! Add a single address. bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0) { bool fRet = false; @@ -428,7 +435,7 @@ public: return fRet; } - // Add multiple addresses. + //! Add multiple addresses. bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0) { int nAdd = 0; @@ -444,7 +451,7 @@ public: return nAdd > 0; } - // Mark an entry as accessible. + //! Mark an entry as accessible. void Good(const CService &addr, int64_t nTime = GetAdjustedTime()) { { @@ -455,7 +462,7 @@ public: } } - // Mark an entry as connection attempted to. + //! Mark an entry as connection attempted to. void Attempt(const CService &addr, int64_t nTime = GetAdjustedTime()) { { @@ -466,8 +473,10 @@ public: } } - // Choose an address to connect to. - // nUnkBias determines how much "new" entries are favored over "tried" ones (0-100). + /** + * Choose an address to connect to. + * nUnkBias determines how much "new" entries are favored over "tried" ones (0-100). + */ CAddress Select(int nUnkBias = 50) { CAddress addrRet; @@ -480,7 +489,7 @@ public: return addrRet; } - // Return a bunch of addresses, selected at random. + //! Return a bunch of addresses, selected at random. std::vector<CAddress> GetAddr() { Check(); @@ -493,7 +502,7 @@ public: return vAddr; } - // Mark an entry as currently-connected-to. + //! Mark an entry as currently-connected-to. void Connected(const CService &addr, int64_t nTime = GetAdjustedTime()) { { @@ -505,4 +514,4 @@ public: } }; -#endif // _BITCOIN_ADDRMAN +#endif // BITCOIN_ADDRMAN_H diff --git a/src/alert.cpp b/src/alert.cpp index 3271ecfbfd..370d0cecc6 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -1,13 +1,14 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "alert.h" #include "chainparams.h" -#include "key.h" +#include "clientversion.h" #include "net.h" +#include "pubkey.h" #include "timedata.h" #include "ui_interface.h" #include "util.h" @@ -127,6 +128,9 @@ bool CAlert::RelayTo(CNode* pnode) const { if (!IsInEffect()) return false; + // don't relay to nodes which haven't sent their version message + if (pnode->nVersion == 0) + return false; // returns true if wasn't already contained in the set if (pnode->setKnown.insert(GetHash()).second) { @@ -233,25 +237,30 @@ bool CAlert::ProcessAlert(bool fThread) if(AppliesToMe()) { uiInterface.NotifyAlertChanged(GetHash(), CT_NEW); - std::string strCmd = GetArg("-alertnotify", ""); - if (!strCmd.empty()) - { - // Alert text should be plain ascii coming from a trusted source, but to - // be safe we first strip anything not in safeChars, then add single quotes around - // the whole string before passing it to the shell: - std::string singleQuote("'"); - std::string safeStatus = SanitizeString(strStatusBar); - safeStatus = singleQuote+safeStatus+singleQuote; - boost::replace_all(strCmd, "%s", safeStatus); - - if (fThread) - boost::thread t(runCommand, strCmd); // thread runs free - else - runCommand(strCmd); - } + Notify(strStatusBar, fThread); } } LogPrint("alert", "accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe()); return true; } + +void +CAlert::Notify(const std::string& strMessage, bool fThread) +{ + std::string strCmd = GetArg("-alertnotify", ""); + if (strCmd.empty()) return; + + // Alert text should be plain ascii coming from a trusted source, but to + // be safe we first strip anything not in safeChars, then add single quotes around + // the whole string before passing it to the shell: + std::string singleQuote("'"); + std::string safeStatus = SanitizeString(strMessage); + safeStatus = singleQuote+safeStatus+singleQuote; + boost::replace_all(strCmd, "%s", safeStatus); + + if (fThread) + boost::thread t(runCommand, strCmd); // thread runs free + else + runCommand(strCmd); +} diff --git a/src/alert.h b/src/alert.h index 5ecf94cea8..af42171af5 100644 --- a/src/alert.h +++ b/src/alert.h @@ -1,10 +1,10 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-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 _BITCOINALERT_H_ -#define _BITCOINALERT_H_ +#ifndef BITCOIN_ALERT_H +#define BITCOIN_ALERT_H #include "serialize.h" #include "sync.h" @@ -101,7 +101,8 @@ public: bool AppliesToMe() const; bool RelayTo(CNode* pnode) const; bool CheckSignature() const; - bool ProcessAlert(bool fThread = true); + bool ProcessAlert(bool fThread = true); // fThread means run -alertnotify in a free-running thread + static void Notify(const std::string& strMessage, bool fThread); /* * Get copy of (active) alert object by hash. Returns a null alert if it is not found. @@ -109,4 +110,4 @@ public: static CAlert getAlertByHash(const uint256 &hash); }; -#endif // _BITCOINALERT_H_ +#endif // BITCOIN_ALERT_H diff --git a/src/allocators.cpp b/src/allocators.cpp index dfe26f1b1e..d3958aa4d7 100644 --- a/src/allocators.cpp +++ b/src/allocators.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-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 "allocators.h" diff --git a/src/allocators.h b/src/allocators.h index 6b69e7ae69..6a131c3517 100644 --- a/src/allocators.h +++ b/src/allocators.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-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_ALLOCATORS_H @@ -9,6 +9,7 @@ #include <map> #include <string> #include <string.h> +#include <vector> #include <boost/thread/mutex.hpp> #include <boost/thread/once.hpp> @@ -261,4 +262,7 @@ struct zero_after_free_allocator : public std::allocator<T> { // This is exactly like std::string, but with a custom allocator. typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString; +// Byte-vector that clears its contents before deletion. +typedef std::vector<char, zero_after_free_allocator<char> > CSerializeData; + #endif // BITCOIN_ALLOCATORS_H diff --git a/src/amount.cpp b/src/amount.cpp new file mode 100644 index 0000000000..0a394c96fc --- /dev/null +++ b/src/amount.cpp @@ -0,0 +1,31 @@ +// 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. + +#include "amount.h" + +#include "tinyformat.h" + +CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nSize) +{ + if (nSize > 0) + nSatoshisPerK = nFeePaid*1000/nSize; + else + nSatoshisPerK = 0; +} + +CAmount CFeeRate::GetFee(size_t nSize) const +{ + CAmount nFee = nSatoshisPerK*nSize / 1000; + + if (nFee == 0 && nSatoshisPerK > 0) + nFee = nSatoshisPerK; + + return nFee; +} + +std::string CFeeRate::ToString() const +{ + return strprintf("%d.%08d BTC/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN); +} diff --git a/src/amount.h b/src/amount.h new file mode 100644 index 0000000000..9212244a88 --- /dev/null +++ b/src/amount.h @@ -0,0 +1,54 @@ +// 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_AMOUNT_H +#define BITCOIN_AMOUNT_H + +#include "serialize.h" + +#include <stdlib.h> +#include <string> + +typedef int64_t CAmount; + +static const CAmount COIN = 100000000; +static const CAmount CENT = 1000000; + +/** No amount larger than this (in satoshi) is valid */ +static const CAmount MAX_MONEY = 21000000 * COIN; +inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } + +/** Type-safe wrapper class to for fee rates + * (how much to pay based on transaction size) + */ +class CFeeRate +{ +private: + CAmount nSatoshisPerK; // unit is satoshis-per-1,000-bytes +public: + CFeeRate() : nSatoshisPerK(0) { } + explicit CFeeRate(const CAmount& _nSatoshisPerK): nSatoshisPerK(_nSatoshisPerK) { } + CFeeRate(const CAmount& nFeePaid, size_t nSize); + CFeeRate(const CFeeRate& other) { nSatoshisPerK = other.nSatoshisPerK; } + + CAmount GetFee(size_t size) const; // unit returned is satoshis + CAmount GetFeePerK() const { return GetFee(1000); } // satoshis-per-1000-bytes + + friend bool operator<(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK < b.nSatoshisPerK; } + friend bool operator>(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK > b.nSatoshisPerK; } + friend bool operator==(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK == b.nSatoshisPerK; } + friend bool operator<=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK <= b.nSatoshisPerK; } + friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; } + std::string ToString() const; + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(nSatoshisPerK); + } +}; + +#endif // BITCOIN_AMOUNT_H diff --git a/src/base58.cpp b/src/base58.cpp index 9750f0a161..980d3cbf42 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" @@ -15,7 +15,7 @@ #include <boost/variant/apply_visitor.hpp> #include <boost/variant/static_visitor.hpp> -/* All alphanumeric characters except for "0", "I", "O", and "l" */ +/** All alphanumeric characters except for "0", "I", "O", and "l" */ static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch) @@ -288,7 +288,8 @@ void CBitcoinSecret::SetKey(const CKey& vchSecret) CKey CBitcoinSecret::GetKey() { CKey ret; - ret.Set(&vchData[0], &vchData[32], vchData.size() > 32 && vchData[32] == 1); + assert(vchData.size() >= 32); + ret.Set(vchData.begin(), vchData.begin() + 32, vchData.size() > 32 && vchData[32] == 1); return ret; } diff --git a/src/base58.h b/src/base58.h index c5e230c72e..ed134e6e77 100644 --- a/src/base58.h +++ b/src/base58.h @@ -1,21 +1,22 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. -// -// 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. -// - 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. -// +/** + * 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. + * - 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. + */ #ifndef BITCOIN_BASE58_H #define BITCOIN_BASE58_H #include "chainparams.h" #include "key.h" +#include "pubkey.h" #include "script/script.h" #include "script/standard.h" @@ -69,10 +70,10 @@ inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char> class CBase58Data { protected: - // the version byte(s) + //! the version byte(s) std::vector<unsigned char> vchVersion; - // the actually encoded data + //! the actually encoded data typedef std::vector<unsigned char, zero_after_free_allocator<unsigned char> > vector_uchar; vector_uchar vchData; diff --git a/src/bitcoin-cli-res.rc b/src/bitcoin-cli-res.rc index b1aa1b0e16..4ea1f38e47 100644 --- a/src/bitcoin-cli-res.rc +++ b/src/bitcoin-cli-res.rc @@ -21,7 +21,7 @@ BEGIN VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoin-cli" VALUE "LegalCopyright", COPYRIGHT_STR - VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." + 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 "ProductVersion", VER_PRODUCTVERSION_STR diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index badb376cb3..668d492d6b 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -1,15 +1,14 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-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 "chainparamsbase.h" -#include "init.h" +#include "clientversion.h" #include "rpcclient.h" #include "rpcprotocol.h" #include "util.h" #include "utilstrencodings.h" -#include "version.h" #include <boost/filesystem/operations.hpp> @@ -25,13 +24,13 @@ std::string HelpMessageCli() string strUsage; strUsage += _("Options:") + "\n"; strUsage += " -? " + _("This help message") + "\n"; - strUsage += " -conf=<file> " + _("Specify configuration file (default: bitcoin.conf)") + "\n"; + strUsage += " -conf=<file> " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n"; strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n"; strUsage += " -testnet " + _("Use the test network") + "\n"; strUsage += " -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.") + "\n"; - strUsage += " -rpcconnect=<ip> " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n"; - strUsage += " -rpcport=<port> " + _("Connect to JSON-RPC on <port> (default: 8332 or testnet: 18332)") + "\n"; + strUsage += " -rpcconnect=<ip> " + strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1") + "\n"; + strUsage += " -rpcport=<port> " + strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n"; strUsage += " -rpcwait " + _("Wait for RPC server to start") + "\n"; strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n"; strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n"; @@ -46,27 +45,27 @@ std::string HelpMessageCli() // // Start // + +// +// Exception thrown on connection error. This error is used to determine +// when to wait if -rpcwait is given. +// +class CConnectionFailed : public std::runtime_error +{ +public: + + explicit inline CConnectionFailed(const std::string& msg) : + std::runtime_error(msg) + {} + +}; + static bool AppInitRPC(int argc, char* argv[]) { // // Parameters // ParseParameters(argc, argv); - if (!boost::filesystem::is_directory(GetDataDir(false))) { - fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); - return false; - } - try { - ReadConfigFile(mapArgs, mapMultiArgs); - } catch(std::exception &e) { - fprintf(stderr,"Error reading configuration file: %s\n", e.what()); - return false; - } - // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause) - if (!SelectBaseParamsFromCommandLine()) { - fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n"); - return false; - } if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version")) { std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n"; if (!mapArgs.count("-version")) { @@ -81,6 +80,21 @@ static bool AppInitRPC(int argc, char* argv[]) fprintf(stdout, "%s", strUsage.c_str()); return false; } + if (!boost::filesystem::is_directory(GetDataDir(false))) { + fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); + return false; + } + try { + ReadConfigFile(mapArgs, mapMultiArgs); + } catch (const std::exception& e) { + fprintf(stderr,"Error reading configuration file: %s\n", e.what()); + return false; + } + // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause) + if (!SelectBaseParamsFromCommandLine()) { + fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n"); + return false; + } return true; } @@ -96,20 +110,14 @@ Object CallRPC(const string& strMethod, const Array& params) bool fUseSSL = GetBoolArg("-rpcssl", false); asio::io_service io_service; ssl::context context(io_service, ssl::context::sslv23); - context.set_options(ssl::context::no_sslv2); + context.set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3); asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context); SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL); iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d); - bool fWait = GetBoolArg("-rpcwait", false); // -rpcwait means try until server has started - do { - bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort()))); - if (fConnected) break; - if (fWait) - MilliSleep(1000); - else - throw runtime_error("couldn't connect to server"); - } while (fWait); + 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"); // HTTP basic authentication string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]); @@ -168,32 +176,48 @@ int CommandLineRPC(int argc, char *argv[]) std::vector<std::string> strParams(&argv[2], &argv[argc]); Array params = RPCConvertValues(strMethod, strParams); - // Execute - Object reply = CallRPC(strMethod, params); - - // Parse reply - const Value& result = find_value(reply, "result"); - const Value& error = find_value(reply, "error"); - - if (error.type() != null_type) { - // Error - strPrint = "error: " + write_string(error, false); - int code = find_value(error.get_obj(), "code").get_int(); - nRet = abs(code); - } else { - // Result - if (result.type() == null_type) - strPrint = ""; - else if (result.type() == str_type) - strPrint = result.get_str(); - else - strPrint = write_string(result, true); - } + // Execute and handle connection failures with -rpcwait + const bool fWait = GetBoolArg("-rpcwait", false); + do { + try { + const Object reply = CallRPC(strMethod, params); + + // Parse reply + const Value& result = find_value(reply, "result"); + const Value& error = find_value(reply, "error"); + + if (error.type() != null_type) { + // Error + const int code = find_value(error.get_obj(), "code").get_int(); + if (fWait && code == RPC_IN_WARMUP) + throw CConnectionFailed("server in warmup"); + strPrint = "error: " + write_string(error, false); + nRet = abs(code); + } else { + // Result + if (result.type() == null_type) + strPrint = ""; + else if (result.type() == str_type) + strPrint = result.get_str(); + else + strPrint = write_string(result, true); + } + + // Connection succeeded, no need to retry. + break; + } + catch (const CConnectionFailed&) { + if (fWait) + MilliSleep(1000); + else + throw; + } + } while (fWait); } - catch (boost::thread_interrupted) { + catch (const boost::thread_interrupted&) { throw; } - catch (std::exception& e) { + catch (const std::exception& e) { strPrint = string("error: ") + e.what(); nRet = EXIT_FAILURE; } @@ -216,7 +240,7 @@ int main(int argc, char* argv[]) if(!AppInitRPC(argc, argv)) return EXIT_FAILURE; } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInitRPC()"); return EXIT_FAILURE; } catch (...) { @@ -228,7 +252,7 @@ int main(int argc, char* argv[]) try { ret = CommandLineRPC(argc, argv); } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, "CommandLineRPC()"); } catch (...) { PrintExceptionContinue(NULL, "CommandLineRPC()"); diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index b6e7a6c540..337cd44cd9 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -1,17 +1,20 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "base58.h" -#include "core.h" +#include "clientversion.h" +#include "primitives/block.h" // for MAX_BLOCK_SIZE +#include "primitives/transaction.h" #include "core_io.h" +#include "coins.h" #include "keystore.h" -#include "main.h" // for MAX_BLOCK_SIZE #include "script/script.h" #include "script/sign.h" #include "ui_interface.h" // for _(...) #include "univalue/univalue.h" #include "util.h" +#include "utilstrencodings.h" #include "utilmoneystr.h" #include <stdio.h> @@ -56,6 +59,7 @@ static bool AppInitRawTx(int argc, char* argv[]) strUsage += " -? " + _("This help message") + "\n"; strUsage += " -create " + _("Create new, empty TX.") + "\n"; strUsage += " -json " + _("Select JSON output") + "\n"; + strUsage += " -txid " + _("Output only the hex-encoded transaction id of the resultant transaction.") + "\n"; strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n"; strUsage += " -testnet " + _("Use the test network") + "\n"; strUsage += "\n"; @@ -214,7 +218,7 @@ static void MutateTxAddOutAddr(CMutableTransaction& tx, const string& strInput) // extract and validate VALUE string strValue = strInput.substr(0, pos); - int64_t value; + CAmount value; if (!ParseMoney(strValue, value)) throw runtime_error("invalid TX output value"); @@ -242,7 +246,7 @@ static void MutateTxAddOutScript(CMutableTransaction& tx, const string& strInput // extract and validate VALUE string strValue = strInput.substr(0, pos); - int64_t value; + CAmount value; if (!ParseMoney(strValue, value)) throw runtime_error("invalid TX output value"); @@ -340,7 +344,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) CMutableTransaction mergedTx(txVariants[0]); bool fComplete = true; CCoinsView viewDummy; - CCoinsViewCache view(viewDummy); + CCoinsViewCache view(&viewDummy); if (!registers.count("privatekeys")) throw runtime_error("privatekeys register variable must be set."); @@ -384,21 +388,19 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) vector<unsigned char> pkData(ParseHexUV(prevOut, "scriptPubKey")); CScript scriptPubKey(pkData.begin(), pkData.end()); - CCoins coins; - if (view.GetCoins(txid, coins)) { - if (coins.IsAvailable(nOut) && coins.vout[nOut].scriptPubKey != scriptPubKey) { + { + 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"+ + err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+ scriptPubKey.ToString(); throw runtime_error(err); } - // what todo if txid is known, but the actual output isn't? + if ((unsigned int)nOut >= coins->vout.size()) + coins->vout.resize(nOut+1); + coins->vout[nOut].scriptPubKey = scriptPubKey; + coins->vout[nOut].nValue = 0; // we don't know the actual output value } - if ((unsigned int)nOut >= coins.vout.size()) - coins.vout.resize(nOut+1); - coins.vout[nOut].scriptPubKey = scriptPubKey; - coins.vout[nOut].nValue = 0; // we don't know the actual output value - view.SetCoins(txid, coins); // if redeemScript given and private keys given, // add redeemScript to the tempKeystore so it can be signed: @@ -435,7 +437,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) BOOST_FOREACH(const CTransaction& txv, txVariants) { txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); } - if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, STANDARD_SCRIPT_VERIFY_FLAGS)) + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i))) fComplete = false; } @@ -489,6 +491,13 @@ static void OutputTxJSON(const CTransaction& tx) fprintf(stdout, "%s\n", jsonOutput.c_str()); } +static void OutputTxHash(const CTransaction& tx) +{ + string strHexHash = tx.GetHash().GetHex(); // the hex-encoded transaction hash (aka the transaction id) + + fprintf(stdout, "%s\n", strHexHash.c_str()); +} + static void OutputTxHex(const CTransaction& tx) { string strHex = EncodeHexTx(tx); @@ -500,6 +509,8 @@ static void OutputTx(const CTransaction& tx) { if (GetBoolArg("-json", false)) OutputTxJSON(tx); + else if (GetBoolArg("-txid", false)) + OutputTxHash(tx); else OutputTxHex(tx); } @@ -575,10 +586,10 @@ static int CommandLineRawTx(int argc, char* argv[]) OutputTx(tx); } - catch (boost::thread_interrupted) { + catch (const boost::thread_interrupted&) { throw; } - catch (std::exception& e) { + catch (const std::exception& e) { strPrint = string("error: ") + e.what(); nRet = EXIT_FAILURE; } @@ -601,7 +612,7 @@ int main(int argc, char* argv[]) if(!AppInitRawTx(argc, argv)) return EXIT_FAILURE; } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInitRawTx()"); return EXIT_FAILURE; } catch (...) { @@ -613,7 +624,7 @@ int main(int argc, char* argv[]) try { ret = CommandLineRawTx(argc, argv); } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, "CommandLineRawTx()"); } catch (...) { PrintExceptionContinue(NULL, "CommandLineRawTx()"); diff --git a/src/bitcoind-res.rc b/src/bitcoind-res.rc index 2e6d754495..d183179b17 100644 --- a/src/bitcoind-res.rc +++ b/src/bitcoind-res.rc @@ -21,7 +21,7 @@ BEGIN VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoind" VALUE "LegalCopyright", COPYRIGHT_STR - VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." + 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 "ProductVersion", VER_PRODUCTVERSION_STR diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 0737b5a83d..8a1745b50d 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -1,8 +1,9 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-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 "clientversion.h" #include "rpcserver.h" #include "init.h" #include "main.h" @@ -58,13 +59,36 @@ bool AppInit(int argc, char* argv[]) boost::thread* detectShutdownThread = NULL; bool fRet = false; + + // + // Parameters + // + // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main() + ParseParameters(argc, argv); + + // Process help and version before taking care about datadir + if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version")) + { + std::string strUsage = _("Bitcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n"; + + if (mapArgs.count("-version")) + { + strUsage += LicenseInfo(); + } + else + { + strUsage += "\n" + _("Usage:") + "\n" + + " bitcoind [options] " + _("Start Bitcoin Core Daemon") + "\n"; + + strUsage += "\n" + HelpMessage(HMM_BITCOIND); + } + + fprintf(stdout, "%s", strUsage.c_str()); + return false; + } + try { - // - // Parameters - // - // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main() - ParseParameters(argc, argv); if (!boost::filesystem::is_directory(GetDataDir(false))) { fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); @@ -73,7 +97,7 @@ bool AppInit(int argc, char* argv[]) try { ReadConfigFile(mapArgs, mapMultiArgs); - } catch(std::exception &e) { + } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); return false; } @@ -83,26 +107,6 @@ bool AppInit(int argc, char* argv[]) return false; } - if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version")) - { - std::string strUsage = _("Bitcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n"; - - if (mapArgs.count("-version")) - { - strUsage += LicenseInfo(); - } - else - { - strUsage += "\n" + _("Usage:") + "\n" + - " bitcoind [options] " + _("Start Bitcoin Core Daemon") + "\n"; - - strUsage += "\n" + HelpMessage(HMM_BITCOIND); - } - - fprintf(stdout, "%s", strUsage.c_str()); - return false; - } - // Command-line RPC bool fCommandLine = false; for (int i = 1; i < argc; i++) @@ -143,7 +147,7 @@ bool AppInit(int argc, char* argv[]) detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup)); fRet = AppInit2(threadGroup); } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInit()"); } catch (...) { PrintExceptionContinue(NULL, "AppInit()"); diff --git a/src/bloom.cpp b/src/bloom.cpp index cef74a3a54..e60576f4b4 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -1,12 +1,14 @@ -// Copyright (c) 2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-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 "bloom.h" -#include "core.h" +#include "primitives/transaction.h" +#include "hash.h" #include "script/script.h" #include "script/standard.h" +#include "streams.h" #include <math.h> #include <stdlib.h> @@ -19,13 +21,17 @@ using namespace std; CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn, unsigned char nFlagsIn) : -// The ideal size for a bloom filter with a given number of elements and false positive rate is: -// - nElements * log(fp rate) / ln(2)^2 -// We ignore filter parameters which will create a bloom filter larger than the protocol limits +/** + * The ideal size for a bloom filter with a given number of elements and false positive rate is: + * - nElements * log(fp rate) / ln(2)^2 + * We ignore filter parameters which will create a bloom filter larger than the protocol limits + */ vData(min((unsigned int)(-1 / LN2SQUARED * nElements * log(nFPRate)), MAX_BLOOM_FILTER_SIZE * 8) / 8), -// The ideal number of hash functions is filter size * ln(2) / number of elements -// Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits -// See http://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas +/** + * The ideal number of hash functions is filter size * ln(2) / number of elements + * Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits + * See https://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas + */ isFull(false), isEmpty(false), nHashFuncs(min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)), diff --git a/src/bloom.h b/src/bloom.h index 143e3b4c79..191ffa19b3 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -1,5 +1,5 @@ -// Copyright (c) 2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-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_BLOOM_H @@ -13,12 +13,14 @@ class COutPoint; class CTransaction; class uint256; -// 20,000 items with fp rate < 0.1% or 10,000 items and <0.0001% +//! 20,000 items with fp rate < 0.1% or 10,000 items and <0.0001% static const unsigned int MAX_BLOOM_FILTER_SIZE = 36000; // bytes static const unsigned int MAX_HASH_FUNCS = 50; -// First two bits of nFlags control how much IsRelevantAndUpdate actually updates -// The remaining bits are reserved +/** + * First two bits of nFlags control how much IsRelevantAndUpdate actually updates + * The remaining bits are reserved + */ enum bloomflags { BLOOM_UPDATE_NONE = 0, @@ -52,13 +54,15 @@ private: unsigned int Hash(unsigned int nHashNum, const std::vector<unsigned char>& vDataToHash) const; public: - // Creates a new bloom filter which will provide the given fp rate when filled with the given number of elements - // Note that if the given parameters will result in a filter outside the bounds of the protocol limits, - // the filter created will be as close to the given parameters as possible within the protocol limits. - // This will apply if nFPRate is very low or nElements is unreasonably high. - // nTweak is a constant which is added to the seed value passed to the hash function - // It should generally always be a random value (and is largely only exposed for unit testing) - // nFlags should be one of the BLOOM_UPDATE_* enums (not _MASK) + /** + * Creates a new bloom filter which will provide the given fp rate when filled with the given number of elements + * Note that if the given parameters will result in a filter outside the bounds of the protocol limits, + * the filter created will be as close to the given parameters as possible within the protocol limits. + * This will apply if nFPRate is very low or nElements is unreasonably high. + * nTweak is a constant which is added to the seed value passed to the hash function + * It should generally always be a random value (and is largely only exposed for unit testing) + * nFlags should be one of the BLOOM_UPDATE_* enums (not _MASK) + */ CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak, unsigned char nFlagsIn); CBloomFilter() : isFull(true), isEmpty(false), nHashFuncs(0), nTweak(0), nFlags(0) {} @@ -82,14 +86,14 @@ public: void clear(); - // 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) + //! 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) bool IsWithinSizeConstraints() const; - // Also adds any outputs which match the filter to the filter (to match their spending txes) + //! Also adds any outputs which match the filter to the filter (to match their spending txes) bool IsRelevantAndUpdate(const CTransaction& tx); - // Checks for empty and full filters to avoid wasting cpu + //! Checks for empty and full filters to avoid wasting cpu void UpdateEmptyFull(); }; diff --git a/src/chain.cpp b/src/chain.cpp new file mode 100644 index 0000000000..719256106e --- /dev/null +++ b/src/chain.cpp @@ -0,0 +1,108 @@ +// 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. + +#include "chain.h" + +using namespace std; + +/** + * CChain implementation + */ +void CChain::SetTip(CBlockIndex *pindex) { + if (pindex == NULL) { + vChain.clear(); + return; + } + vChain.resize(pindex->nHeight + 1); + while (pindex && vChain[pindex->nHeight] != pindex) { + vChain[pindex->nHeight] = pindex; + pindex = pindex->pprev; + } +} + +CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { + int nStep = 1; + std::vector<uint256> vHave; + vHave.reserve(32); + + if (!pindex) + pindex = Tip(); + while (pindex) { + vHave.push_back(pindex->GetBlockHash()); + // Stop when we have added the genesis block. + if (pindex->nHeight == 0) + break; + // Exponentially larger steps back, plus the genesis block. + int nHeight = std::max(pindex->nHeight - nStep, 0); + if (Contains(pindex)) { + // Use O(1) CChain index if possible. + pindex = (*this)[nHeight]; + } else { + // Otherwise, use O(log n) skiplist. + pindex = pindex->GetAncestor(nHeight); + } + if (vHave.size() > 10) + nStep *= 2; + } + + return CBlockLocator(vHave); +} + +const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { + if (pindex->nHeight > Height()) + pindex = pindex->GetAncestor(Height()); + while (pindex && !Contains(pindex)) + pindex = pindex->pprev; + return pindex; +} + +/** Turn the lowest '1' bit in the binary representation of a number into a '0'. */ +int static inline InvertLowestOne(int n) { return n & (n - 1); } + +/** Compute what height to jump back to with the CBlockIndex::pskip pointer. */ +int static inline GetSkipHeight(int height) { + if (height < 2) + return 0; + + // Determine which height to jump back to. Any number strictly lower than height is acceptable, + // but the following expression seems to perform well in simulations (max 110 steps to go back + // up to 2**18 blocks). + return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 : InvertLowestOne(height); +} + +CBlockIndex* CBlockIndex::GetAncestor(int height) +{ + if (height > nHeight || height < 0) + return NULL; + + CBlockIndex* pindexWalk = this; + int heightWalk = nHeight; + while (heightWalk > height) { + int heightSkip = GetSkipHeight(heightWalk); + int heightSkipPrev = GetSkipHeight(heightWalk - 1); + if (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; + } else { + pindexWalk = pindexWalk->pprev; + heightWalk--; + } + } + return pindexWalk; +} + +const CBlockIndex* CBlockIndex::GetAncestor(int height) const +{ + return const_cast<CBlockIndex*>(this)->GetAncestor(height); +} + +void CBlockIndex::BuildSkip() +{ + if (pprev) + pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); +} diff --git a/src/chain.h b/src/chain.h new file mode 100644 index 0000000000..b459c975f8 --- /dev/null +++ b/src/chain.h @@ -0,0 +1,399 @@ +// 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_CHAIN_H +#define BITCOIN_CHAIN_H + +#include "primitives/block.h" +#include "pow.h" +#include "tinyformat.h" +#include "uint256.h" + +#include <vector> + +#include <boost/foreach.hpp> + +struct CDiskBlockPos +{ + int nFile; + unsigned int nPos; + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(VARINT(nFile)); + READWRITE(VARINT(nPos)); + } + + CDiskBlockPos() { + SetNull(); + } + + CDiskBlockPos(int nFileIn, unsigned int nPosIn) { + nFile = nFileIn; + nPos = nPosIn; + } + + friend bool operator==(const CDiskBlockPos &a, const CDiskBlockPos &b) { + return (a.nFile == b.nFile && a.nPos == b.nPos); + } + + friend bool operator!=(const CDiskBlockPos &a, const CDiskBlockPos &b) { + return !(a == b); + } + + void SetNull() { nFile = -1; nPos = 0; } + bool IsNull() const { return (nFile == -1); } +}; + +enum BlockStatus { + //! Unused. + BLOCK_VALID_UNKNOWN = 0, + + //! Parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future + BLOCK_VALID_HEADER = 1, + + //! All parent headers found, difficulty matches, timestamp >= median previous, checkpoint. Implies all parents + //! are also at least TREE. + BLOCK_VALID_TREE = 2, + + /** + * Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids, + * sigops, size, merkle root. Implies all parents are at least TREE but not necessarily TRANSACTIONS. When all + * parent blocks also have TRANSACTIONS, CBlockIndex::nChainTx will be set. + */ + BLOCK_VALID_TRANSACTIONS = 3, + + //! Outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30. + //! Implies all parents are also at least CHAIN. + BLOCK_VALID_CHAIN = 4, + + //! Scripts & signatures ok. Implies all parents are also at least SCRIPTS. + BLOCK_VALID_SCRIPTS = 5, + + //! All validity bits. + BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS | + BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS, + + BLOCK_HAVE_DATA = 8, //! full block available in blk*.dat + BLOCK_HAVE_UNDO = 16, //! undo data available in rev*.dat + BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO, + + BLOCK_FAILED_VALID = 32, //! stage after last reached validness failed + BLOCK_FAILED_CHILD = 64, //! descends from failed block + BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, +}; + +/** The block chain is a tree shaped structure starting with the + * genesis block at the root, with each block potentially having multiple + * candidates to be the next block. A blockindex may have multiple pprev pointing + * to it, but at most one of them can be part of the currently active branch. + */ +class CBlockIndex +{ +public: + //! pointer to the hash of the block, if any. Memory is owned by this CBlockIndex + const uint256* phashBlock; + + //! pointer to the index of the predecessor of this block + CBlockIndex* pprev; + + //! pointer to the index of some further predecessor of this block + CBlockIndex* pskip; + + //! height of the entry in the chain. The genesis block has height 0 + int nHeight; + + //! Which # file this block is stored in (blk?????.dat) + int nFile; + + //! Byte offset within blk?????.dat where this block's data is stored + unsigned int nDataPos; + + //! Byte offset within rev?????.dat where this block's undo data is stored + unsigned int nUndoPos; + + //! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block + uint256 nChainWork; + + //! Number of transactions in this block. + //! Note: in a potential headers-first mode, this number cannot be relied upon + unsigned int nTx; + + //! (memory only) Number of transactions in the chain up to and including this block. + //! This value will be non-zero only if and only if transactions for this block and all its parents are available. + //! Change to 64-bit type when necessary; won't happen before 2030 + unsigned int nChainTx; + + //! Verification status of this block. See enum BlockStatus + unsigned int nStatus; + + //! block header + int nVersion; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + + //! (memory only) Sequential id assigned to distinguish order in which blocks are received. + uint32_t nSequenceId; + + void SetNull() + { + phashBlock = NULL; + pprev = NULL; + pskip = NULL; + nHeight = 0; + nFile = 0; + nDataPos = 0; + nUndoPos = 0; + nChainWork = 0; + nTx = 0; + nChainTx = 0; + nStatus = 0; + nSequenceId = 0; + + nVersion = 0; + hashMerkleRoot = 0; + nTime = 0; + nBits = 0; + nNonce = 0; + } + + CBlockIndex() + { + SetNull(); + } + + CBlockIndex(const CBlockHeader& block) + { + SetNull(); + + nVersion = block.nVersion; + hashMerkleRoot = block.hashMerkleRoot; + nTime = block.nTime; + nBits = block.nBits; + nNonce = block.nNonce; + } + + CDiskBlockPos GetBlockPos() const { + CDiskBlockPos ret; + if (nStatus & BLOCK_HAVE_DATA) { + ret.nFile = nFile; + ret.nPos = nDataPos; + } + return ret; + } + + CDiskBlockPos GetUndoPos() const { + CDiskBlockPos ret; + if (nStatus & BLOCK_HAVE_UNDO) { + ret.nFile = nFile; + ret.nPos = nUndoPos; + } + return ret; + } + + CBlockHeader GetBlockHeader() const + { + CBlockHeader block; + block.nVersion = nVersion; + if (pprev) + block.hashPrevBlock = pprev->GetBlockHash(); + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + return block; + } + + uint256 GetBlockHash() const + { + return *phashBlock; + } + + int64_t GetBlockTime() const + { + return (int64_t)nTime; + } + + enum { nMedianTimeSpan=11 }; + + int64_t GetMedianTimePast() const + { + int64_t pmedian[nMedianTimeSpan]; + int64_t* pbegin = &pmedian[nMedianTimeSpan]; + int64_t* pend = &pmedian[nMedianTimeSpan]; + + const CBlockIndex* pindex = this; + for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) + *(--pbegin) = pindex->GetBlockTime(); + + std::sort(pbegin, pend); + return pbegin[(pend - pbegin)/2]; + } + + std::string ToString() const + { + return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", + pprev, nHeight, + hashMerkleRoot.ToString(), + GetBlockHash().ToString()); + } + + //! Check whether this block index entry is valid up to the passed validity level. + bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const + { + assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed. + if (nStatus & BLOCK_FAILED_MASK) + return false; + return ((nStatus & BLOCK_VALID_MASK) >= nUpTo); + } + + //! Raise the validity level of this block index entry. + //! Returns true if the validity was changed. + bool RaiseValidity(enum BlockStatus nUpTo) + { + assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed. + if (nStatus & BLOCK_FAILED_MASK) + return false; + if ((nStatus & BLOCK_VALID_MASK) < nUpTo) { + nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo; + return true; + } + return false; + } + + //! Build the skiplist pointer for this entry. + void BuildSkip(); + + //! Efficiently find an ancestor of this block. + CBlockIndex* GetAncestor(int height); + const CBlockIndex* GetAncestor(int height) const; +}; + +/** Used to marshal pointers into hashes for db storage. */ +class CDiskBlockIndex : public CBlockIndex +{ +public: + uint256 hashPrev; + + CDiskBlockIndex() { + hashPrev = 0; + } + + explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) { + hashPrev = (pprev ? pprev->GetBlockHash() : 0); + } + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + if (!(nType & SER_GETHASH)) + READWRITE(VARINT(nVersion)); + + READWRITE(VARINT(nHeight)); + READWRITE(VARINT(nStatus)); + READWRITE(VARINT(nTx)); + if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO)) + READWRITE(VARINT(nFile)); + if (nStatus & BLOCK_HAVE_DATA) + READWRITE(VARINT(nDataPos)); + if (nStatus & BLOCK_HAVE_UNDO) + READWRITE(VARINT(nUndoPos)); + + // block header + READWRITE(this->nVersion); + READWRITE(hashPrev); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + } + + uint256 GetBlockHash() const + { + CBlockHeader block; + block.nVersion = nVersion; + block.hashPrevBlock = hashPrev; + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + return block.GetHash(); + } + + + std::string ToString() const + { + std::string str = "CDiskBlockIndex("; + str += CBlockIndex::ToString(); + str += strprintf("\n hashBlock=%s, hashPrev=%s)", + GetBlockHash().ToString(), + hashPrev.ToString()); + return str; + } +}; + +/** An in-memory indexed chain of blocks. */ +class CChain { +private: + std::vector<CBlockIndex*> vChain; + +public: + /** Returns the index entry for the genesis block of this chain, or NULL if none. */ + CBlockIndex *Genesis() const { + return vChain.size() > 0 ? vChain[0] : NULL; + } + + /** Returns the index entry for the tip of this chain, or NULL if none. */ + CBlockIndex *Tip() const { + return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL; + } + + /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */ + CBlockIndex *operator[](int nHeight) const { + if (nHeight < 0 || nHeight >= (int)vChain.size()) + return NULL; + return vChain[nHeight]; + } + + /** Compare two chains efficiently. */ + friend bool operator==(const CChain &a, const CChain &b) { + return a.vChain.size() == b.vChain.size() && + a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1]; + } + + /** Efficiently check whether a block is present in this chain. */ + bool Contains(const CBlockIndex *pindex) const { + return (*this)[pindex->nHeight] == pindex; + } + + /** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */ + CBlockIndex *Next(const CBlockIndex *pindex) const { + if (Contains(pindex)) + return (*this)[pindex->nHeight + 1]; + else + return NULL; + } + + /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */ + int Height() const { + return vChain.size() - 1; + } + + /** Set/initialize a chain with a given tip. */ + void SetTip(CBlockIndex *pindex); + + /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */ + CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const; + + /** Find the last common block between this chain and a block index entry. */ + const CBlockIndex *FindFork(const CBlockIndex *pindex) const; +}; + +#endif // BITCOIN_CHAIN_H diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 179db5a818..f4bc6e1d70 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -1,12 +1,13 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "chainparams.h" #include "random.h" #include "util.h" +#include "utilstrencodings.h" #include <assert.h> @@ -22,11 +23,11 @@ struct SeedSpec6 { #include "chainparamsseeds.h" -// -// Main network -// +/** + * Main network + */ -// Convert the pnSeeds6 array into usable address objects. +//! Convert the pnSeeds6 array into usable address objects. static void convertSeed6(std::vector<CAddress> &vSeedsOut, const SeedSpec6 *data, unsigned int count) { // It'll only connect to one or two seed nodes because once it connects, @@ -44,14 +45,69 @@ static void convertSeed6(std::vector<CAddress> &vSeedsOut, const SeedSpec6 *data } } +/** + * What makes a good checkpoint block? + * + Is surrounded by blocks with reasonable timestamps + * (no blocks before with a timestamp after, none after with + * timestamp before) + * + Contains no strange transactions + */ +static Checkpoints::MapCheckpoints mapCheckpoints = + boost::assign::map_list_of + ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) + ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) + ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) + (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) + (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) + (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")) + (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")) + (210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")) + (216116, uint256("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")) + (225430, uint256("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")) + (250000, uint256("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")) + (279000, uint256("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")) + (295000, uint256("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, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")) + ; +static const Checkpoints::CCheckpointData dataTestnet = { + &mapCheckpointsTestnet, + 1337966069, + 1488, + 300 + }; + +static Checkpoints::MapCheckpoints mapCheckpointsRegtest = + boost::assign::map_list_of + ( 0, uint256("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")) + ; +static const Checkpoints::CCheckpointData dataRegtest = { + &mapCheckpointsRegtest, + 0, + 0, + 0 + }; + class CMainParams : public CChainParams { public: CMainParams() { networkID = CBaseChainParams::MAIN; strNetworkID = "main"; - // 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. + /** + * 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. + */ pchMessageStart[0] = 0xf9; pchMessageStart[1] = 0xbe; pchMessageStart[2] = 0xb4; @@ -67,14 +123,16 @@ public: nTargetTimespan = 14 * 24 * 60 * 60; // two weeks nTargetSpacing = 10 * 60; - // 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 + /** + * 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); @@ -98,7 +156,6 @@ public: vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me")); vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com")); - vSeeds.push_back(CDNSSeedData("bitnodes.io", "seed.bitnodes.io")); vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org")); base58Prefixes[PUBKEY_ADDRESS] = list_of(0); @@ -115,22 +172,25 @@ public: fAllowMinDifficultyBlocks = false; fRequireStandard = true; fMineBlocksOnDemand = false; + fSkipProofOfWorkCheck = false; + fTestnetToBeDeprecatedFieldRPC = false; + } + + const Checkpoints::CCheckpointData& Checkpoints() const + { + return data; } }; static CMainParams mainParams; -// -// Testnet (v3) -// - +/** + * Testnet (v3) + */ class CTestNetParams : public CMainParams { public: CTestNetParams() { networkID = CBaseChainParams::TESTNET; strNetworkID = "test"; - // 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. pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; @@ -141,10 +201,10 @@ public: nRejectBlockOutdatedMajority = 75; nToCheckBlockUpgradeMajority = 100; nMinerThreads = 0; - nTargetTimespan = 14 * 24 * 60 * 60; // two weeks + nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks nTargetSpacing = 10 * 60; - // Modify the testnet genesis block so the timestamp is valid for a later start. + //! Modify the testnet genesis block so the timestamp is valid for a later start. genesis.nTime = 1296688602; genesis.nNonce = 414098458; hashGenesisBlock = genesis.GetHash(); @@ -171,13 +231,18 @@ public: fAllowMinDifficultyBlocks = true; fRequireStandard = false; fMineBlocksOnDemand = false; + fTestnetToBeDeprecatedFieldRPC = true; + } + const Checkpoints::CCheckpointData& Checkpoints() const + { + return dataTestnet; } }; static CTestNetParams testNetParams; -// -// Regression test -// +/** + * Regression test + */ class CRegTestParams : public CTestNetParams { public: CRegTestParams() { @@ -192,7 +257,7 @@ public: nRejectBlockOutdatedMajority = 950; nToCheckBlockUpgradeMajority = 1000; nMinerThreads = 1; - nTargetTimespan = 14 * 24 * 60 * 60; // two weeks + nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks nTargetSpacing = 10 * 60; bnProofOfWorkLimit = ~uint256(0) >> 1; genesis.nTime = 1296688602; @@ -202,7 +267,8 @@ public: nDefaultPort = 18444; assert(hashGenesisBlock == uint256("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); - vSeeds.clear(); // Regtest mode doesn't have any DNS seeds. + vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds. + vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds. fRequireRPCPassword = false; fMiningRequiresPeers = false; @@ -210,12 +276,61 @@ public: fAllowMinDifficultyBlocks = true; fRequireStandard = false; fMineBlocksOnDemand = true; + fTestnetToBeDeprecatedFieldRPC = false; + } + const Checkpoints::CCheckpointData& Checkpoints() const + { + return dataRegtest; } }; static CRegTestParams regTestParams; +/** + * Unit test + */ +class CUnitTestParams : public CMainParams, public CModifiableParams { +public: + CUnitTestParams() { + networkID = CBaseChainParams::UNITTEST; + strNetworkID = "unittest"; + nDefaultPort = 18445; + vFixedSeeds.clear(); //! Unit test mode doesn't have any fixed seeds. + vSeeds.clear(); //! Unit test mode doesn't have any DNS seeds. + + fRequireRPCPassword = false; + fMiningRequiresPeers = false; + fDefaultCheckMemPool = true; + fAllowMinDifficultyBlocks = false; + fMineBlocksOnDemand = true; + } + + const Checkpoints::CCheckpointData& Checkpoints() const + { + // UnitTest share the same checkpoints as MAIN + return data; + } + + //! Published setters to allow changing values in unit test cases + virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) { nSubsidyHalvingInterval=anSubsidyHalvingInterval; } + virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) { nEnforceBlockUpgradeMajority=anEnforceBlockUpgradeMajority; } + virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) { nRejectBlockOutdatedMajority=anRejectBlockOutdatedMajority; } + virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) { nToCheckBlockUpgradeMajority=anToCheckBlockUpgradeMajority; } + virtual void setDefaultCheckMemPool(bool afDefaultCheckMemPool) { fDefaultCheckMemPool=afDefaultCheckMemPool; } + virtual void setAllowMinDifficultyBlocks(bool afAllowMinDifficultyBlocks) { fAllowMinDifficultyBlocks=afAllowMinDifficultyBlocks; } + virtual void setSkipProofOfWorkCheck(bool afSkipProofOfWorkCheck) { fSkipProofOfWorkCheck = afSkipProofOfWorkCheck; } +}; +static CUnitTestParams unitTestParams; + + static CChainParams *pCurrentParams = 0; +CModifiableParams *ModifiableParams() +{ + assert(pCurrentParams); + assert(pCurrentParams==&unitTestParams); + return (CModifiableParams*)&unitTestParams; +} + const CChainParams &Params() { assert(pCurrentParams); return *pCurrentParams; @@ -229,6 +344,8 @@ CChainParams &Params(CBaseChainParams::Network network) { return testNetParams; case CBaseChainParams::REGTEST: return regTestParams; + case CBaseChainParams::UNITTEST: + return unitTestParams; default: assert(false && "Unimplemented network"); return mainParams; @@ -240,10 +357,12 @@ void SelectParams(CBaseChainParams::Network network) { pCurrentParams = &Params(network); } -bool SelectParamsFromCommandLine() { - if (!SelectBaseParamsFromCommandLine()) +bool SelectParamsFromCommandLine() +{ + CBaseChainParams::Network network = NetworkIdFromCommandLine(); + if (network == CBaseChainParams::MAX_NETWORK_TYPES) return false; - SelectParams(BaseParams().NetworkID()); + SelectParams(network); return true; } diff --git a/src/chainparams.h b/src/chainparams.h index e5dfc87c6d..60c7b47585 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -1,13 +1,14 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_CHAIN_PARAMS_H -#define BITCOIN_CHAIN_PARAMS_H +#ifndef BITCOIN_CHAINPARAMS_H +#define BITCOIN_CHAINPARAMS_H -#include "core.h" #include "chainparamsbase.h" +#include "checkpoints.h" +#include "primitives/block.h" #include "protocol.h" #include "uint256.h" @@ -46,41 +47,44 @@ public: int GetDefaultPort() const { return nDefaultPort; } const uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; } int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; } - /* Used to check majorities for block version upgrade */ + /** Used to check majorities for block version upgrade */ int EnforceBlockUpgradeMajority() const { return nEnforceBlockUpgradeMajority; } int RejectBlockOutdatedMajority() const { return nRejectBlockOutdatedMajority; } int ToCheckBlockUpgradeMajority() const { return nToCheckBlockUpgradeMajority; } - /* Used if GenerateBitcoins is called with a negative number of threads */ + /** 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 */ + /** Make miner wait to have peers to avoid wasting work */ bool MiningRequiresPeers() const { return fMiningRequiresPeers; } - /* Default value for -checkmempool argument */ + /** Default value for -checkmempool argument */ bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; } - /* Allow mining of a min-difficulty block */ + /** Allow mining of a min-difficulty block */ bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; } - /* Make standard checks */ + /** Skip proof-of-work check: allow mining of any difficulty block */ + bool SkipProofOfWorkCheck() const { return fSkipProofOfWorkCheck; } + /** Make standard checks */ bool RequireStandard() const { return fRequireStandard; } int64_t TargetTimespan() const { return nTargetTimespan; } int64_t TargetSpacing() const { return nTargetSpacing; } int64_t Interval() const { return nTargetTimespan / nTargetSpacing; } - /* Make miner stop after a block is found. In RPC, don't return - * until nGenProcLimit blocks are generated */ + /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } - CBaseChainParams::Network NetworkID() const { return networkID; } - /* Return the BIP70 network string (main, test or regtest) */ + /** In the future use NetworkIDString() for RPC fields */ + bool TestnetToBeDeprecatedFieldRPC() const { return fTestnetToBeDeprecatedFieldRPC; } + /** Return the BIP70 network string (main, test or regtest) */ std::string NetworkIDString() const { return strNetworkID; } const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; } const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } const std::vector<CAddress>& FixedSeeds() const { return vFixedSeeds; } + virtual const Checkpoints::CCheckpointData& Checkpoints() const = 0; protected: CChainParams() {} uint256 hashGenesisBlock; MessageStartChars pchMessageStart; - // Raw pub key bytes for the broadcast alert signing key. + //! Raw pub key bytes for the broadcast alert signing key. std::vector<unsigned char> vAlertPubKey; int nDefaultPort; uint256 bnProofOfWorkLimit; @@ -103,8 +107,29 @@ protected: bool fAllowMinDifficultyBlocks; bool fRequireStandard; bool fMineBlocksOnDemand; + bool fSkipProofOfWorkCheck; + bool fTestnetToBeDeprecatedFieldRPC; }; +/** + * Modifiable parameters interface is used by test cases to adapt the parameters in order + * to test specific features more easily. Test cases should always restore the previous + * values after finalization. + */ + +class CModifiableParams { +public: + //! Published setters to allow changing values in unit test cases + virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) =0; + virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority)=0; + virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority)=0; + virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority)=0; + virtual void setDefaultCheckMemPool(bool aDefaultCheckMemPool)=0; + virtual void setAllowMinDifficultyBlocks(bool aAllowMinDifficultyBlocks)=0; + virtual void setSkipProofOfWorkCheck(bool aSkipProofOfWorkCheck)=0; +}; + + /** * Return the currently selected parameters. This won't change after app startup * outside of the unit tests. @@ -114,6 +139,9 @@ const CChainParams &Params(); /** Return parameters for the given network. */ CChainParams &Params(CBaseChainParams::Network network); +/** Get modifiable network parameters (UNITTEST only) */ +CModifiableParams *ModifiableParams(); + /** Sets the params returned by Params() to those for the given network. */ void SelectParams(CBaseChainParams::Network network); @@ -123,4 +151,4 @@ void SelectParams(CBaseChainParams::Network network); */ bool SelectParamsFromCommandLine(); -#endif // BITCOIN_CHAIN_PARAMS_H +#endif // BITCOIN_CHAINPARAMS_H diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 98bb5b855f..e45536ce71 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "chainparamsbase.h" @@ -13,10 +13,9 @@ using namespace boost::assign; -// -// Main network -// - +/** + * Main network + */ class CBaseMainParams : public CBaseChainParams { public: @@ -28,9 +27,9 @@ public: }; static CBaseMainParams mainParams; -// -// Testnet (v3) -// +/** + * Testnet (v3) + */ class CBaseTestNetParams : public CBaseMainParams { public: @@ -43,9 +42,9 @@ public: }; static CBaseTestNetParams testNetParams; -// -// Regression test -// +/* + * Regression test + */ class CBaseRegTestParams : public CBaseTestNetParams { public: @@ -57,6 +56,20 @@ public: }; static CBaseRegTestParams regTestParams; +/* + * Unit test + */ +class CBaseUnitTestParams : public CBaseMainParams +{ +public: + CBaseUnitTestParams() + { + networkID = CBaseChainParams::UNITTEST; + strDataDir = "unittest"; + } +}; +static CBaseUnitTestParams unitTestParams; + static CBaseChainParams* pCurrentBaseParams = 0; const CBaseChainParams& BaseParams() @@ -77,28 +90,36 @@ void SelectBaseParams(CBaseChainParams::Network network) case CBaseChainParams::REGTEST: pCurrentBaseParams = ®TestParams; break; + case CBaseChainParams::UNITTEST: + pCurrentBaseParams = &unitTestParams; + break; default: assert(false && "Unimplemented network"); return; } } -bool SelectBaseParamsFromCommandLine() +CBaseChainParams::Network NetworkIdFromCommandLine() { bool fRegTest = GetBoolArg("-regtest", false); bool fTestNet = GetBoolArg("-testnet", false); - if (fTestNet && fRegTest) { + if (fTestNet && fRegTest) + return CBaseChainParams::MAX_NETWORK_TYPES; + if (fRegTest) + return CBaseChainParams::REGTEST; + if (fTestNet) + return CBaseChainParams::TESTNET; + return CBaseChainParams::MAIN; +} + +bool SelectBaseParamsFromCommandLine() +{ + CBaseChainParams::Network network = NetworkIdFromCommandLine(); + if (network == CBaseChainParams::MAX_NETWORK_TYPES) return false; - } - if (fRegTest) { - SelectBaseParams(CBaseChainParams::REGTEST); - } else if (fTestNet) { - SelectBaseParams(CBaseChainParams::TESTNET); - } else { - SelectBaseParams(CBaseChainParams::MAIN); - } + SelectBaseParams(network); return true; } diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index c054f03f17..24db9b2840 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -1,9 +1,9 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_CHAIN_PARAMS_BASE_H -#define BITCOIN_CHAIN_PARAMS_BASE_H +#ifndef BITCOIN_CHAINPARAMSBASE_H +#define BITCOIN_CHAINPARAMSBASE_H #include <string> #include <vector> @@ -19,13 +19,13 @@ public: MAIN, TESTNET, REGTEST, + UNITTEST, MAX_NETWORK_TYPES }; const std::string& DataDir() const { return strDataDir; } int RPCPort() const { return nRPCPort; } - Network NetworkID() const { return networkID; } protected: CBaseChainParams() {} @@ -45,7 +45,13 @@ const CBaseChainParams& BaseParams(); void SelectBaseParams(CBaseChainParams::Network network); /** - * Looks for -regtest or -testnet and then calls SelectParams as appropriate. + * Looks for -regtest or -testnet and returns the appropriate Network ID. + * Returns MAX_NETWORK_TYPES if an invalid combination is given. + */ +CBaseChainParams::Network NetworkIdFromCommandLine(); + +/** + * Calls NetworkIdFromCommandLine() and then calls SelectParams as appropriate. * Returns false if an invalid combination is given. */ bool SelectBaseParamsFromCommandLine(); @@ -56,4 +62,4 @@ bool SelectBaseParamsFromCommandLine(); */ bool AreBaseParamsConfigured(); -#endif // BITCOIN_CHAIN_PARAMS_BASE_H +#endif // BITCOIN_CHAINPARAMSBASE_H diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 3f3278361e..575e129334 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -1,10 +1,12 @@ -#ifndef H_CHAINPARAMSSEEDS -#define H_CHAINPARAMSSEEDS -// List of fixed seed nodes for the bitcoin network -// AUTOGENERATED by contrib/devtools/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. +#ifndef BITCOIN_CHAINPARAMSSEEDS_H +#define BITCOIN_CHAINPARAMSSEEDS_H +/** + * List of fixed seed nodes for the bitcoin network + * AUTOGENERATED by share/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,0x2e,0x69,0x6a,0x7e}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x04,0x7d}, 8333}, @@ -635,4 +637,4 @@ 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} }; -#endif +#endif // BITCOIN_CHAINPARAMSSEEDS_H diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index c41deea7ce..71579bb309 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -1,110 +1,43 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "checkpoints.h" +#include "chainparams.h" #include "main.h" #include "uint256.h" #include <stdint.h> -#include <boost/assign/list_of.hpp> // for 'map_list_of()' #include <boost/foreach.hpp> namespace Checkpoints { - typedef std::map<int, uint256> MapCheckpoints; - - // 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 - // 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. + /** + * 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 + * 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; - struct CCheckpointData { - const MapCheckpoints *mapCheckpoints; - int64_t nTimeLastCheckpoint; - int64_t nTransactionsLastCheckpoint; - double fTransactionsPerDay; - }; - bool fEnabled = true; - // What makes a good checkpoint block? - // + Is surrounded by blocks with reasonable timestamps - // (no blocks before with a timestamp after, none after with - // timestamp before) - // + Contains no strange transactions - static MapCheckpoints mapCheckpoints = - boost::assign::map_list_of - ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) - ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) - ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) - (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) - (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) - (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")) - (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")) - (210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")) - (216116, uint256("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")) - (225430, uint256("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")) - (250000, uint256("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")) - (279000, uint256("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")) - (295000, uint256("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")) - ; - static const 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 MapCheckpoints mapCheckpointsTestnet = - boost::assign::map_list_of - ( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")) - ; - static const CCheckpointData dataTestnet = { - &mapCheckpointsTestnet, - 1337966069, - 1488, - 300 - }; - - static MapCheckpoints mapCheckpointsRegtest = - boost::assign::map_list_of - ( 0, uint256("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")) - ; - static const CCheckpointData dataRegtest = { - &mapCheckpointsRegtest, - 0, - 0, - 0 - }; - - const CCheckpointData &Checkpoints() { - if (Params().NetworkID() == CBaseChainParams::TESTNET) - return dataTestnet; - else if (Params().NetworkID() == CBaseChainParams::MAIN) - return data; - else - return dataRegtest; - } - bool CheckBlock(int nHeight, const uint256& hash) { if (!fEnabled) return true; - const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints; + 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 + //! Guess how far we are in the verification process at the given block index double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks) { if (pindex==NULL) return 0.0; @@ -117,7 +50,7 @@ namespace Checkpoints { // Work is defined as: 1.0 per transaction before the last checkpoint, and // fSigcheckVerificationFactor per transaction after. - const CCheckpointData &data = Checkpoints(); + const CCheckpointData &data = Params().Checkpoints(); if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) { double nCheapBefore = pindex->nChainTx; @@ -141,7 +74,7 @@ namespace Checkpoints { if (!fEnabled) return 0; - const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints; + const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints; return checkpoints.rbegin()->first; } @@ -151,7 +84,7 @@ namespace Checkpoints { if (!fEnabled) return NULL; - const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints; + const MapCheckpoints& checkpoints = *Params().Checkpoints().mapCheckpoints; BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints) { diff --git a/src/checkpoints.h b/src/checkpoints.h index fca046559a..29dc5f83a9 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -1,27 +1,38 @@ -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_CHECKPOINT_H -#define BITCOIN_CHECKPOINT_H +#ifndef BITCOIN_CHECKPOINTS_H +#define BITCOIN_CHECKPOINTS_H + +#include "uint256.h" #include <map> class CBlockIndex; -class uint256; -/** Block-chain checkpoints are compiled-in sanity checks. +/** + * Block-chain checkpoints are compiled-in sanity checks. * They are updated every release or three. */ namespace Checkpoints { -// Returns true if block passes checkpoint checks +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 +//! Return conservative estimate of total number of blocks, 0 if unknown int GetTotalBlocksEstimate(); -// Returns last CBlockIndex* in mapBlockIndex that is a checkpoint +//! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint CBlockIndex* GetLastCheckpoint(); double GuessVerificationProgress(CBlockIndex* pindex, bool fSigchecks = true); @@ -30,4 +41,4 @@ extern bool fEnabled; } //namespace Checkpoints -#endif // BITCOIN_CHECKPOINT_H +#endif // BITCOIN_CHECKPOINTS_H diff --git a/src/checkqueue.h b/src/checkqueue.h index b2a713e646..b8e2a17c76 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -1,9 +1,9 @@ -// Copyright (c) 2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-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 CHECKQUEUE_H -#define CHECKQUEUE_H +#ifndef BITCOIN_CHECKQUEUE_H +#define BITCOIN_CHECKQUEUE_H #include <algorithm> #include <vector> @@ -16,7 +16,8 @@ template <typename T> class CCheckQueueControl; -/** Queue for verifications that have to be performed. +/** + * Queue for verifications that have to be performed. * The verifications are represented by a type T, which must provide an * operator(), returning a bool. * @@ -29,40 +30,42 @@ template <typename T> class CCheckQueue { private: - // Mutex to protect the inner state + //! Mutex to protect the inner state boost::mutex mutex; - // Worker threads block on this when out of work + //! Worker threads block on this when out of work boost::condition_variable condWorker; - // Master thread blocks on this when out of work + //! Master thread blocks on this when out of work boost::condition_variable condMaster; - // The queue of elements to be processed. - // As the order of booleans doesn't matter, it is used as a LIFO (stack) + //! The queue of elements to be processed. + //! As the order of booleans doesn't matter, it is used as a LIFO (stack) std::vector<T> queue; - // The number of workers (including the master) that are idle. + //! The number of workers (including the master) that are idle. int nIdle; - // The total number of workers (including the master). + //! The total number of workers (including the master). int nTotal; - // The temporary evaluation result. + //! The temporary evaluation result. bool fAllOk; - // Number of verifications that haven't completed yet. - // This includes elements that are not anymore in queue, but still in - // worker's own batches. + /** + * Number of verifications that haven't completed yet. + * This includes elements that are not anymore in queue, but still in + * worker's own batches. + */ unsigned int nTodo; - // Whether we're shutting down. + //! Whether we're shutting down. bool fQuit; - // The maximum number of elements to be processed in one batch + //! The maximum number of elements to be processed in one batch unsigned int nBatchSize; - // Internal function that does bulk of the verification work. + /** Internal function that does bulk of the verification work. */ bool Loop(bool fMaster = false) { boost::condition_variable& cond = fMaster ? condMaster : condWorker; @@ -124,22 +127,22 @@ private: } public: - // Create a new check queue + //! Create a new check queue CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {} - // Worker thread + //! Worker thread void Thread() { Loop(); } - // Wait until execution finishes, and return whether all evaluations where succesful. + //! Wait until execution finishes, and return whether all evaluations where successful. bool Wait() { return Loop(true); } - // Add a batch of checks to the queue + //! Add a batch of checks to the queue void Add(std::vector<T>& vChecks) { boost::unique_lock<boost::mutex> lock(mutex); @@ -161,8 +164,9 @@ public: friend class CCheckQueueControl<T>; }; -/** RAII-style controller object for a CCheckQueue that guarantees the passed - * queue is finished before continuing. +/** + * RAII-style controller object for a CCheckQueue that guarantees the passed + * queue is finished before continuing. */ template <typename T> class CCheckQueueControl @@ -204,4 +208,4 @@ public: } }; -#endif // CHECKQUEUE_H +#endif // BITCOIN_CHECKQUEUE_H diff --git a/src/version.cpp b/src/clientversion.cpp index 95632fdab7..aae0569bba 100644 --- a/src/version.cpp +++ b/src/clientversion.cpp @@ -1,44 +1,48 @@ -// Copyright (c) 2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-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 "version.h" +#include "clientversion.h" #include "tinyformat.h" #include <string> -#include <boost/algorithm/string/join.hpp> - -// Name of client reported in the 'version' message. Report the same name -// for both bitcoind and bitcoin-qt, to make it harder for attackers to -// target servers or GUI users specifically. +/** + * Name of client reported in the 'version' message. Report the same name + * for both bitcoind and bitcoin-core, to make it harder for attackers to + * target servers or GUI users specifically. + */ const std::string CLIENT_NAME("Satoshi"); -// Client version number +/** + * Client version number + */ #define CLIENT_VERSION_SUFFIX "" -// The following part of the code determines the CLIENT_BUILD variable. -// Several mechanisms are used for this: -// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is -// generated by the build environment, possibly containing the output -// of git-describe in a macro called BUILD_DESC -// * secondly, if this is an exported version of the code, GIT_ARCHIVE will -// be defined (automatically using the export-subst git attribute), and -// GIT_COMMIT will contain the commit id. -// * then, three options exist for determining CLIENT_BUILD: -// * if BUILD_DESC is defined, use that literally (output of git-describe) -// * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit] -// * otherwise, use v[maj].[min].[rev].[build]-unk -// finally CLIENT_VERSION_SUFFIX is added - -// First, include build.h if requested +/** + * The following part of the code determines the CLIENT_BUILD variable. + * Several mechanisms are used for this: + * * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is + * generated by the build environment, possibly containing the output + * of git-describe in a macro called BUILD_DESC + * * secondly, if this is an exported version of the code, GIT_ARCHIVE will + * be defined (automatically using the export-subst git attribute), and + * GIT_COMMIT will contain the commit id. + * * then, three options exist for determining CLIENT_BUILD: + * * if BUILD_DESC is defined, use that literally (output of git-describe) + * * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit] + * * otherwise, use v[maj].[min].[rev].[build]-unk + * finally CLIENT_VERSION_SUFFIX is added + */ + +//! First, include build.h if requested #ifdef HAVE_BUILD_INFO #include "build.h" #endif -// git will put "#define GIT_ARCHIVE 1" on the next line inside archives. $Format:%n#define GIT_ARCHIVE 1$ +//! git will put "#define GIT_ARCHIVE 1" on the next line inside archives. $Format:%n#define GIT_ARCHIVE 1$ #ifdef GIT_ARCHIVE #define GIT_COMMIT_ID "$Format:%h$" #define GIT_COMMIT_DATE "$Format:%cD$" @@ -87,14 +91,22 @@ std::string FormatFullVersion() return CLIENT_BUILD; } -// Format the subversion field according to BIP 14 spec (https://en.bitcoin.it/wiki/BIP_0014) +/** + * Format the subversion field according to BIP 14 spec (https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki) + */ std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments) { std::ostringstream ss; ss << "/"; ss << name << ":" << FormatVersion(nClientVersion); if (!comments.empty()) - ss << "(" << boost::algorithm::join(comments, "; ") << ")"; + { + std::vector<std::string>::const_iterator it(comments.begin()); + ss << "(" << *it; + for(++it; it != comments.end(); ++it) + ss << "; " << *it; + ss << ")"; + } ss << "/"; return ss.str(); } diff --git a/src/clientversion.h b/src/clientversion.h index cd7ceb78f0..40de7837aa 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -1,38 +1,70 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 CLIENTVERSION_H -#define CLIENTVERSION_H +#ifndef BITCOIN_CLIENTVERSION_H +#define BITCOIN_CLIENTVERSION_H #if defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" #else -// -// client versioning and copyright year -// -// These need to be macros, as version.cpp's and bitcoin*-res.rc's voodoo requires it +/** + * client versioning and copyright year + */ + +//! 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 9 +#define CLIENT_VERSION_MINOR 10 #define CLIENT_VERSION_REVISION 99 #define CLIENT_VERSION_BUILD 0 -// Set to true for release, false for prerelease or test build +//! Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE false -// Copyright year (2009-this) -// Todo: update this when changing our copyright comments in the source +/** + * Copyright year (2009-this) + * Todo: update this when changing our copyright comments in the source + */ #define COPYRIGHT_YEAR 2014 #endif //HAVE_CONFIG_H -// Converts the parameter X to a string after macro replacement on X has been performed. -// Don't merge these into one macro! +/** + * Converts the parameter X to a string after macro replacement on X has been performed. + * Don't merge these into one macro! + */ #define STRINGIZE(X) DO_STRINGIZE(X) #define DO_STRINGIZE(X) #X -// Copyright string used in Windows .rc files +//! Copyright string used in Windows .rc files #define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core Developers" -#endif // CLIENTVERSION_H +/** + * bitcoind-res.rc includes this file, but it cannot cope with real c++ code. + * WINDRES_PREPROC is defined to indicate that its pre-processor is running. + * Anything other than a define should be guarded below. + */ + +#if !defined(WINDRES_PREPROC) + +#include <string> +#include <vector> + +static const int CLIENT_VERSION = + 1000000 * CLIENT_VERSION_MAJOR + + 10000 * CLIENT_VERSION_MINOR + + 100 * CLIENT_VERSION_REVISION + + 1 * CLIENT_VERSION_BUILD; + +extern const std::string CLIENT_NAME; +extern const std::string CLIENT_BUILD; +extern const std::string CLIENT_DATE; + + +std::string FormatFullVersion(); +std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments); + +#endif // WINDRES_PREPROC + +#endif // BITCOIN_CLIENTVERSION_H diff --git a/src/coincontrol.h b/src/coincontrol.h index 033092c019..92fae9847c 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -1,11 +1,11 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 COINCONTROL_H -#define COINCONTROL_H +#ifndef BITCOIN_COINCONTROL_H +#define BITCOIN_COINCONTROL_H -#include "core.h" +#include "primitives/transaction.h" /** Coin Control Features. */ class CCoinControl @@ -35,12 +35,12 @@ public: return (setSelected.count(outpt) > 0); } - void Select(COutPoint& output) + void Select(const COutPoint& output) { setSelected.insert(output); } - void UnSelect(COutPoint& output) + void UnSelect(const COutPoint& output) { setSelected.erase(output); } @@ -59,4 +59,4 @@ private: std::set<COutPoint> setSelected; }; -#endif // COINCONTROL_H +#endif // BITCOIN_COINCONTROL_H diff --git a/src/coins.cpp b/src/coins.cpp index 34485db2bd..f4599ff39d 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2012-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-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 "coins.h" @@ -8,9 +8,11 @@ #include <assert.h> -// calculate number of bytes for the bitmask, and its number of non-zero bytes -// each bit in the bitmask represents the availability of one output, but the -// availabilities of the first two outputs are encoded separately +/** + * calculate number of bytes for the bitmask, and its number of non-zero bytes + * each bit in the bitmask represents the availability of one output, but the + * availabilities of the first two outputs are encoded separately + */ void CCoins::CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) const { unsigned int nLastUsedByte = 0; for (unsigned int b = 0; 2+b*8 < vout.size(); b++) { @@ -29,85 +31,82 @@ void CCoins::CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) con nBytes += nLastUsedByte; } -bool CCoins::Spend(const COutPoint &out, CTxInUndo &undo) { - if (out.n >= vout.size()) - return false; - if (vout[out.n].IsNull()) +bool CCoins::Spend(uint32_t nPos) +{ + if (nPos >= vout.size() || vout[nPos].IsNull()) return false; - undo = CTxInUndo(vout[out.n]); - vout[out.n].SetNull(); + vout[nPos].SetNull(); Cleanup(); - if (vout.size() == 0) { - undo.nHeight = nHeight; - undo.fCoinBase = fCoinBase; - undo.nVersion = this->nVersion; - } return true; } -bool CCoins::Spend(int nPos) { - CTxInUndo undo; - COutPoint out(0, nPos); - return Spend(out, undo); -} - - bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; } -bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return false; } bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; } uint256 CCoinsView::GetBestBlock() const { return uint256(0); } -bool CCoinsView::SetBestBlock(const uint256 &hashBlock) { return false; } bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; } bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; } -CCoinsViewBacked::CCoinsViewBacked(CCoinsView &viewIn) : base(&viewIn) { } +CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { } bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); } -bool CCoinsViewBacked::SetCoins(const uint256 &txid, const CCoins &coins) { return base->SetCoins(txid, coins); } bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); } uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); } -bool CCoinsViewBacked::SetBestBlock(const uint256 &hashBlock) { return base->SetBestBlock(hashBlock); } void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); } bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStats(stats); } CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {} -CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), hashBlock(0) { } +CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), hashBlock(0) { } -bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const { - if (cacheCoins.count(txid)) { - coins = cacheCoins[txid]; - return true; - } - if (base->GetCoins(txid, coins)) { - cacheCoins[txid] = coins; - return true; - } - return false; +CCoinsViewCache::~CCoinsViewCache() +{ + assert(!hasModifier); } -CCoinsMap::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) { +CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const { CCoinsMap::iterator it = cacheCoins.find(txid); if (it != cacheCoins.end()) return it; CCoins tmp; - if (!base->GetCoins(txid,tmp)) + if (!base->GetCoins(txid, tmp)) return cacheCoins.end(); - CCoinsMap::iterator ret = cacheCoins.insert(it, std::make_pair(txid, CCoins())); - tmp.swap(ret->second); + CCoinsMap::iterator ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())).first; + tmp.swap(ret->second.coins); + if (ret->second.coins.IsPruned()) { + // The parent only has an empty entry for this txid; we can consider our + // version as fresh. + ret->second.flags = CCoinsCacheEntry::FRESH; + } return ret; } -CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const { - /* Avoid redundant implementation with the const-cast. */ - return const_cast<CCoinsViewCache*>(this)->FetchCoins(txid); +bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const { + CCoinsMap::const_iterator it = FetchCoins(txid); + if (it != cacheCoins.end()) { + coins = it->second.coins; + return true; + } + return false; } -CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) { - CCoinsMap::iterator it = FetchCoins(txid); - assert(it != cacheCoins.end()); - return it->second; +CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) { + assert(!hasModifier); + hasModifier = true; + std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())); + if (ret.second) { + if (!base->GetCoins(txid, ret.first->second.coins)) { + // The parent view does not have this entry; mark it as fresh. + ret.first->second.coins.Clear(); + ret.first->second.flags = CCoinsCacheEntry::FRESH; + } else if (ret.first->second.coins.IsPruned()) { + // The parent view only has a pruned entry for this; mark it as fresh. + ret.first->second.flags = CCoinsCacheEntry::FRESH; + } + } + // Assume that whenever ModifyCoins is called, the entry will be modified. + ret.first->second.flags |= CCoinsCacheEntry::DIRTY; + return CCoinsModifier(*this, ret.first); } const CCoins* CCoinsViewCache::AccessCoins(const uint256 &txid) const { @@ -115,22 +114,17 @@ const CCoins* CCoinsViewCache::AccessCoins(const uint256 &txid) const { if (it == cacheCoins.end()) { return NULL; } else { - return &it->second; + return &it->second.coins; } } -bool CCoinsViewCache::SetCoins(const uint256 &txid, const CCoins &coins) { - cacheCoins[txid] = coins; - return true; -} - bool CCoinsViewCache::HaveCoins(const uint256 &txid) const { CCoinsMap::const_iterator it = FetchCoins(txid); // We're using vtx.empty() instead of IsPruned here for performance reasons, - // as we only care about the case where an transaction was replaced entirely + // as we only care about the case where a transaction was replaced entirely // in a reorganization (which wipes vout entirely, as opposed to spending // which just cleans individual outputs). - return (it != cacheCoins.end() && !it->second.vout.empty()); + return (it != cacheCoins.end() && !it->second.coins.vout.empty()); } uint256 CCoinsViewCache::GetBestBlock() const { @@ -139,14 +133,39 @@ uint256 CCoinsViewCache::GetBestBlock() const { return hashBlock; } -bool CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) { +void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) { hashBlock = hashBlockIn; - return true; } bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) { + assert(!hasModifier); for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) { - cacheCoins[it->first].swap(it->second); + if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization). + CCoinsMap::iterator itUs = cacheCoins.find(it->first); + if (itUs == cacheCoins.end()) { + if (!it->second.coins.IsPruned()) { + // The parent cache does not have an entry, while the child + // cache does have (a non-pruned) one. Move the data up, and + // mark it as fresh (if the grandparent did have it, we + // would have pulled it in at first GetCoins). + assert(it->second.flags & CCoinsCacheEntry::FRESH); + CCoinsCacheEntry& entry = cacheCoins[it->first]; + entry.coins.swap(it->second.coins); + entry.flags = CCoinsCacheEntry::DIRTY | CCoinsCacheEntry::FRESH; + } + } else { + if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) { + // 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. + cacheCoins.erase(itUs); + } else { + // A normal modification. + itUs->second.coins.swap(it->second.coins); + itUs->second.flags |= CCoinsCacheEntry::DIRTY; + } + } + } CCoinsMap::iterator itOld = it++; mapCoins.erase(itOld); } @@ -171,12 +190,12 @@ const CTxOut &CCoinsViewCache::GetOutputFor(const CTxIn& input) const return coins->vout[input.prevout.n]; } -int64_t CCoinsViewCache::GetValueIn(const CTransaction& tx) const +CAmount CCoinsViewCache::GetValueIn(const CTransaction& tx) const { if (tx.IsCoinBase()) return 0; - int64_t nResult = 0; + CAmount nResult = 0; for (unsigned int i = 0; i < tx.vin.size(); i++) nResult += GetOutputFor(tx.vin[i]).nValue; @@ -213,3 +232,15 @@ 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() +{ + assert(cache.hasModifier); + cache.hasModifier = false; + it->second.coins.Cleanup(); + if ((it->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) { + cache.cacheCoins.erase(it); + } +} diff --git a/src/coins.h b/src/coins.h index bf61f55aac..2be52ad171 100644 --- a/src/coins.h +++ b/src/coins.h @@ -1,12 +1,12 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_COINS_H #define BITCOIN_COINS_H -#include "core.h" +#include "compressor.h" #include "serialize.h" #include "uint256.h" @@ -16,7 +16,8 @@ #include <boost/foreach.hpp> #include <boost/unordered_map.hpp> -/** pruned version of CTransaction: only retains metadata and unspent transaction outputs +/** + * Pruned version of CTransaction: only retains metadata and unspent transaction outputs * * Serialized format: * - VARINT(nVersion) @@ -70,28 +71,43 @@ class CCoins { public: - // whether transaction is a coinbase + //! whether transaction is a coinbase bool fCoinBase; - // unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are dropped + //! unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are dropped std::vector<CTxOut> vout; - // at which height this transaction was included in the active block chain + //! at which height this transaction was included in the active block chain int nHeight; - // version of the CTransaction; accesses to this value should probably check for nHeight as well, - // as new tx version will probably only be introduced at certain heights + //! version of the CTransaction; accesses to this value should probably check for nHeight as well, + //! as new tx version will probably only be introduced at certain heights int nVersion; - // construct a CCoins from a CTransaction, at a given height - CCoins(const CTransaction &tx, int nHeightIn) : fCoinBase(tx.IsCoinBase()), vout(tx.vout), nHeight(nHeightIn), nVersion(tx.nVersion) { + void FromTx(const CTransaction &tx, int nHeightIn) { + fCoinBase = tx.IsCoinBase(); + vout = tx.vout; + nHeight = nHeightIn; + nVersion = tx.nVersion; ClearUnspendable(); } - // empty constructor + //! construct a CCoins from a CTransaction, at a given height + CCoins(const CTransaction &tx, int nHeightIn) { + FromTx(tx, nHeightIn); + } + + void Clear() { + fCoinBase = false; + std::vector<CTxOut>().swap(vout); + nHeight = 0; + nVersion = 0; + } + + //! empty constructor CCoins() : fCoinBase(false), vout(0), nHeight(0), nVersion(0) { } - // remove spent outputs at the end of vout + //!remove spent outputs at the end of vout void Cleanup() { while (vout.size() > 0 && vout.back().IsNull()) vout.pop_back(); @@ -114,7 +130,7 @@ public: std::swap(to.nVersion, nVersion); } - // equality test + //! equality test friend bool operator==(const CCoins &a, const CCoins &b) { // Empty CCoins objects are always equal. if (a.IsPruned() && b.IsPruned()) @@ -220,19 +236,16 @@ public: Cleanup(); } - // mark an outpoint spent, and construct undo information - bool Spend(const COutPoint &out, CTxInUndo &undo); + //! mark a vout spent + bool Spend(uint32_t nPos); - // mark a vout spent - bool Spend(int nPos); - - // check whether a particular output is still available + //! check whether a particular output is still available bool IsAvailable(unsigned int nPos) const { return (nPos < vout.size() && !vout[nPos].IsNull()); } - // check whether the entire CCoins is spent - // note that only !IsPruned() CCoins can be serialized + //! check whether the entire CCoins is spent + //! note that only !IsPruned() CCoins can be serialized bool IsPruned() const { BOOST_FOREACH(const CTxOut &out, vout) if (!out.IsNull()) @@ -248,15 +261,31 @@ private: public: CCoinsKeyHasher(); - // This *must* return size_t. With Boost 1.46 on 32-bit systems the - // unordered_map will behave unpredictably if the custom hasher returns a - // uint64_t, resulting in failures when syncing the chain (#4634). + + /** + * This *must* return size_t. With Boost 1.46 on 32-bit systems the + * unordered_map will behave unpredictably if the custom hasher returns a + * uint64_t, resulting in failures when syncing the chain (#4634). + */ size_t operator()(const uint256& key) const { return key.GetHash(salt); } }; -typedef boost::unordered_map<uint256, CCoins, CCoinsKeyHasher> CCoinsMap; +struct CCoinsCacheEntry +{ + CCoins coins; // The actual cached data. + unsigned char flags; + + enum Flags { + DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view. + FRESH = (1 << 1), // The parent view does not have this entry (or it is pruned). + }; + + CCoinsCacheEntry() : coins(), flags(0) {} +}; + +typedef boost::unordered_map<uint256, CCoinsCacheEntry, CCoinsKeyHasher> CCoinsMap; struct CCoinsStats { @@ -266,7 +295,7 @@ struct CCoinsStats uint64_t nTransactionOutputs; uint64_t nSerializedSize; uint256 hashSerialized; - int64_t nTotalAmount; + CAmount nTotalAmount; CCoinsStats() : nHeight(0), hashBlock(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), hashSerialized(0), nTotalAmount(0) {} }; @@ -276,30 +305,24 @@ struct CCoinsStats class CCoinsView { public: - // Retrieve the CCoins (unspent transaction outputs) for a given txid + //! Retrieve the CCoins (unspent transaction outputs) for a given txid virtual bool GetCoins(const uint256 &txid, CCoins &coins) const; - // Modify the CCoins for a given txid - virtual bool SetCoins(const uint256 &txid, const CCoins &coins); - - // Just check whether we have data for a given txid. - // This may (but cannot always) return true for fully spent transactions + //! Just check whether we have data for a given txid. + //! This may (but cannot always) return true for fully spent transactions virtual bool HaveCoins(const uint256 &txid) const; - // Retrieve the block hash whose state this CCoinsView currently represents + //! Retrieve the block hash whose state this CCoinsView currently represents virtual uint256 GetBestBlock() const; - // Modify the currently active block hash - virtual bool SetBestBlock(const uint256 &hashBlock); - - // Do a bulk modification (multiple SetCoins + one SetBestBlock). - // The passed mapCoins can be modified. + //! Do a bulk modification (multiple CCoins changes + BestBlock change). + //! The passed mapCoins can be modified. virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); - // Calculate statistics about the unspent transaction output set + //! Calculate statistics about the unspent transaction output set virtual bool GetStats(CCoinsStats &stats) const; - // As we use CCoinsViews polymorphically, have a virtual destructor + //! As we use CCoinsViews polymorphically, have a virtual destructor virtual ~CCoinsView() {} }; @@ -311,72 +334,106 @@ protected: CCoinsView *base; public: - CCoinsViewBacked(CCoinsView &viewIn); + CCoinsViewBacked(CCoinsView *viewIn); bool GetCoins(const uint256 &txid, CCoins &coins) const; - bool SetCoins(const uint256 &txid, const CCoins &coins); bool HaveCoins(const uint256 &txid) const; uint256 GetBestBlock() const; - bool SetBestBlock(const uint256 &hashBlock); void SetBackend(CCoinsView &viewIn); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); bool GetStats(CCoinsStats &stats) const; }; +class CCoinsViewCache; + +/** + * A reference to a mutable cache entry. Encapsulating it allows us to run + * cleanup code after the modification is finished, and keeping track of + * concurrent modifications. + */ +class CCoinsModifier +{ +private: + CCoinsViewCache& cache; + CCoinsMap::iterator it; + CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_); + +public: + CCoins* operator->() { return &it->second.coins; } + CCoins& operator*() { return it->second.coins; } + ~CCoinsModifier(); + friend class CCoinsViewCache; +}; + /** CCoinsView that adds a memory cache for transactions to another CCoinsView */ class CCoinsViewCache : public CCoinsViewBacked { 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". */ + /** + * Make mutable so that we can "fill the cache" even from Get-methods + * declared as "const". + */ mutable uint256 hashBlock; mutable CCoinsMap cacheCoins; public: - CCoinsViewCache(CCoinsView &baseIn, bool fDummy = false); + CCoinsViewCache(CCoinsView *baseIn); + ~CCoinsViewCache(); // Standard CCoinsView methods bool GetCoins(const uint256 &txid, CCoins &coins) const; - bool SetCoins(const uint256 &txid, const CCoins &coins); bool HaveCoins(const uint256 &txid) const; uint256 GetBestBlock() const; - bool SetBestBlock(const uint256 &hashBlock); + void SetBestBlock(const uint256 &hashBlock); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); - // Return a pointer to CCoins in the cache, or NULL if not found. This is - // more efficient than GetCoins. Modifications to other cache entries are - // allowed while accessing the returned pointer. + /** + * Return a pointer to CCoins in the cache, or NULL if not found. This is + * more efficient than GetCoins. Modifications to other cache entries are + * allowed while accessing the returned pointer. + */ const CCoins* AccessCoins(const uint256 &txid) const; - // Return a modifiable reference to a CCoins. Check HaveCoins first. - CCoins &GetCoins(const uint256 &txid); + /** + * Return a modifiable reference to a CCoins. If no entry with the given + * txid exists, a new one is created. Simultaneous modifications are not + * allowed. + */ + CCoinsModifier ModifyCoins(const uint256 &txid); - // Push the modifications applied to this cache to its base. - // Failure to call this method before destruction will cause the changes to be forgotten. - // If false is returned, the state of this cache (and its backing view) will be undefined. + /** + * Push the modifications applied to this cache to its base. + * Failure to call this method before destruction will cause the changes to be forgotten. + * If false is returned, the state of this cache (and its backing view) will be undefined. + */ bool Flush(); - // Calculate the size of the cache (in number of transactions) + //! Calculate the size of the cache (in number of transactions) unsigned int GetCacheSize() const; - /** Amount of bitcoins coming in to a transaction - Note that lightweight clients may not know anything besides the hash of previous transactions, - so may not be able to calculate this. - - @param[in] tx transaction for which we are checking input total - @return Sum of value of all inputs (scriptSigs) + /** + * Amount of bitcoins coming in to a transaction + * Note that lightweight clients may not know anything besides the hash of previous transactions, + * so may not be able to calculate this. + * + * @param[in] tx transaction for which we are checking input total + * @return Sum of value of all inputs (scriptSigs) */ - int64_t GetValueIn(const CTransaction& tx) const; + CAmount GetValueIn(const CTransaction& tx) const; - // Check whether all prevouts of the transaction are present in the UTXO set represented by this view + //! Check whether all prevouts of the transaction are present in the UTXO set represented by this view bool HaveInputs(const CTransaction& tx) const; - // Return priority of tx at height nHeight + //! Return priority of tx at height nHeight double GetPriority(const CTransaction &tx, int nHeight) const; const CTxOut &GetOutputFor(const CTxIn& input) const; + friend class CCoinsModifier; + private: CCoinsMap::iterator FetchCoins(const uint256 &txid); CCoinsMap::const_iterator FetchCoins(const uint256 &txid) const; diff --git a/src/compat.h b/src/compat.h index 4fc28a36e0..7a5438a11e 100644 --- a/src/compat.h +++ b/src/compat.h @@ -1,10 +1,14 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_COMPAT_H -#define _BITCOIN_COMPAT_H +#ifndef BITCOIN_COMPAT_H +#define BITCOIN_COMPAT_H + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif #ifdef WIN32 #ifdef _WIN32_WINNT @@ -84,4 +88,8 @@ typedef u_int SOCKET; #define THREAD_PRIORITY_ABOVE_NORMAL (-2) #endif -#endif // _BITCOIN_COMPAT_H +#if HAVE_DECL_STRNLEN == 0 +size_t strnlen( const char *start, size_t max_len); +#endif // HAVE_DECL_STRNLEN + +#endif // BITCOIN_COMPAT_H diff --git a/src/compat/glibc_compat.cpp b/src/compat/glibc_compat.cpp index 22f82e4259..3b9c70df7f 100644 --- a/src/compat/glibc_compat.cpp +++ b/src/compat/glibc_compat.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #if defined(HAVE_CONFIG_H) @@ -7,6 +7,7 @@ #endif #include <cstddef> + #if defined(HAVE_SYS_SELECT_H) #include <sys/select.h> #endif @@ -18,11 +19,11 @@ extern "C" void* memcpy(void* a, const void* b, size_t c) return memmove(a, b, c); } -extern "C" void __chk_fail (void) __attribute__((__noreturn__)); +extern "C" void __chk_fail(void) __attribute__((__noreturn__)); extern "C" FDELT_TYPE __fdelt_warn(FDELT_TYPE a) { if (a >= FD_SETSIZE) - __chk_fail (); + __chk_fail(); return a / __NFDBITS; } extern "C" FDELT_TYPE __fdelt_chk(FDELT_TYPE) __attribute__((weak, alias("__fdelt_warn"))); diff --git a/src/compat/glibc_sanity.cpp b/src/compat/glibc_sanity.cpp index d93602e0fe..d62d74d462 100644 --- a/src/compat/glibc_sanity.cpp +++ b/src/compat/glibc_sanity.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #if defined(HAVE_CONFIG_H) @@ -7,6 +7,7 @@ #endif #include <cstddef> + #if defined(HAVE_SYS_SELECT_H) #include <sys/select.h> #endif @@ -14,10 +15,11 @@ extern "C" void* memcpy(void* a, const void* b, size_t c); void* memcpy_int(void* a, const void* b, size_t c) { - return memcpy(a,b,c); + return memcpy(a, b, c); } -namespace { +namespace +{ // trigger: Use the memcpy_int wrapper which calls our internal memcpy. // A direct call to memcpy may be optimized away by the compiler. // test: Fill an array with a sequence of integers. memcpy to a new empty array. @@ -31,11 +33,10 @@ bool sanity_test_memcpy() for (unsigned int i = 0; i != T; ++i) memcpy_test[i] = i; - memcpy_int(memcpy_verify,memcpy_test,sizeof(memcpy_test)); + memcpy_int(memcpy_verify, memcpy_test, sizeof(memcpy_test)); - for (unsigned int i = 0; i != T; ++i) - { - if(memcpy_verify[i] != i) + for (unsigned int i = 0; i != T; ++i) { + if (memcpy_verify[i] != i) return false; } return true; @@ -51,7 +52,7 @@ bool sanity_test_fdelt() fd_set fds; FD_ZERO(&fds); FD_SET(0, &fds); - return FD_ISSET(0,&fds); + return FD_ISSET(0, &fds); } #endif diff --git a/src/compat/glibcxx_compat.cpp b/src/compat/glibcxx_compat.cpp index cbe059735b..4f2771e57a 100644 --- a/src/compat/glibcxx_compat.cpp +++ b/src/compat/glibcxx_compat.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include <cstddef> @@ -11,8 +11,8 @@ #define _GLIBCXX_USE_NOEXCEPT throw() #endif -namespace std { - +namespace std +{ const char* bad_exception::what() const throw() { return "std::bad_exception"; @@ -30,9 +30,8 @@ const char* bad_alloc::what() const throw() namespace __detail { -struct _List_node_base -{ - void _M_hook(std::__detail::_List_node_base* const __position) throw () __attribute__((used)) +struct _List_node_base { + void _M_hook(std::__detail::_List_node_base* const __position) throw() __attribute__((used)) { _M_next = __position; _M_prev = __position->_M_prev; @@ -62,9 +61,9 @@ template ostream& __ostream_insert(ostream&, const char*, streamsize); template istream& istream::_M_extract(long&); template istream& istream::_M_extract(unsigned short&); -out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { } +out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT {} -length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { } +length_error::~length_error() _GLIBCXX_USE_NOEXCEPT {} // Used with permission. // See: https://github.com/madlib/madlib/commit/c3db418c0d34d6813608f2137fef1012ce03043d @@ -85,11 +84,11 @@ void ctype<char>::_M_widen_init() const } } -void __throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__)); -void __throw_out_of_range_fmt(const char* err, ...) +void __throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__)); +void __throw_out_of_range_fmt(const char* err, ...) { // Safe and over-simplified version. Ignore the format and print it as-is. __throw_out_of_range(err); } -}// namespace std +} // namespace std diff --git a/src/compat/glibcxx_sanity.cpp b/src/compat/glibcxx_sanity.cpp index cd8da4fd67..cee8a98c7f 100644 --- a/src/compat/glibcxx_sanity.cpp +++ b/src/compat/glibcxx_sanity.cpp @@ -1,20 +1,20 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include <list> #include <locale> #include <stdexcept> -namespace{ - +namespace +{ // trigger: use ctype<char>::widen to trigger ctype<char>::_M_widen_init(). // test: convert a char from narrow to wide and back. Verify that the result // matches the original. bool sanity_test_widen(char testchar) { - const std::ctype<char>& test(std::use_facet< std::ctype<char> >(std::locale())); - return test.narrow(test.widen(testchar),'b') == testchar; + const std::ctype<char>& test(std::use_facet<std::ctype<char> >(std::locale())); + return test.narrow(test.widen(testchar), 'b') == testchar; } // trigger: use list::push_back and list::pop_back to trigger _M_hook and @@ -25,14 +25,13 @@ bool sanity_test_list(unsigned int size) { std::list<unsigned int> test; for (unsigned int i = 0; i != size; ++i) - test.push_back(i+1); + test.push_back(i + 1); if (test.size() != size) return false; - while (!test.empty()) - { - if(test.back() != test.size()) + while (!test.empty()) { + if (test.back() != test.size()) return false; test.pop_back(); } @@ -47,15 +46,12 @@ bool sanity_test_list(unsigned int size) bool sanity_test_range_fmt() { std::string test; - try - { + try { test.at(1); - } - catch (const std::out_of_range&) - { + } catch (const std::out_of_range&) { return true; + } catch (...) { } - catch (...){} return false; } diff --git a/src/compat/sanity.h b/src/compat/sanity.h index e7df44307a..909c4f6da8 100644 --- a/src/compat/sanity.h +++ b/src/compat/sanity.h @@ -1,11 +1,11 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 BITCON_COMPAT_SANITY_H -#define BITCON_COMPAT_SANITY_H +#ifndef BITCOIN_COMPAT_SANITY_H +#define BITCOIN_COMPAT_SANITY_H bool glibc_sanity_test(); bool glibcxx_sanity_test(); -#endif // BITCON_COMPAT_SANITY_H +#endif // BITCOIN_COMPAT_SANITY_H diff --git a/src/compat/strnlen.cpp b/src/compat/strnlen.cpp new file mode 100644 index 0000000000..1ac266c2d1 --- /dev/null +++ b/src/compat/strnlen.cpp @@ -0,0 +1,18 @@ +// 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. + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include <cstring> + +#if HAVE_DECL_STRNLEN == 0 +size_t strnlen( const char *start, size_t max_len) +{ + const char *end = (const char *)memchr(start, '\0', max_len); + + return end ? (size_t)(end - start) : max_len; +} +#endif // HAVE_DECL_STRNLEN diff --git a/src/script/compressor.cpp b/src/compressor.cpp index 51a3cf6025..20c154fc1e 100644 --- a/src/script/compressor.cpp +++ b/src/compressor.cpp @@ -1,10 +1,14 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "compressor.h" +#include "hash.h" +#include "pubkey.h" +#include "script/standard.h" + bool CScriptCompressor::IsToKeyID(CKeyID &hash) const { if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 @@ -125,3 +129,57 @@ bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector<unsigne } return false; } + +// Amount compression: +// * If the amount is 0, output 0 +// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9) +// * if e<9, the last digit of the resulting number cannot be 0; store it as d, and drop it (divide by 10) +// * call the result n +// * output 1 + 10*(9*n + d - 1) + e +// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9 +// (this is decodable, as d is in [1-9] and e is in [0-9]) + +uint64_t CTxOutCompressor::CompressAmount(uint64_t n) +{ + if (n == 0) + return 0; + int e = 0; + while (((n % 10) == 0) && e < 9) { + n /= 10; + e++; + } + if (e < 9) { + int d = (n % 10); + assert(d >= 1 && d <= 9); + n /= 10; + return 1 + (n*9 + d - 1)*10 + e; + } else { + return 1 + (n - 1)*10 + 9; + } +} + +uint64_t CTxOutCompressor::DecompressAmount(uint64_t x) +{ + // x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9 + if (x == 0) + return 0; + x--; + // x = 10*(9*n + d - 1) + e + int e = x % 10; + x /= 10; + uint64_t n = 0; + if (e < 9) { + // x = 9*n + d - 1 + int d = (x % 9) + 1; + x /= 9; + // x = n + n = x*10 + d; + } else { + n = x+1; + } + while (e) { + n *= 10; + e--; + } + return n; +} diff --git a/src/script/compressor.h b/src/compressor.h index 53c6bf3ecc..4a72090830 100644 --- a/src/script/compressor.h +++ b/src/compressor.h @@ -1,12 +1,18 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef H_BITCOIN_SCRIPT_COMPRESSOR -#define H_BITCOIN_SCRIPT_COMPRESSOR +#ifndef BITCOIN_COMPRESSOR_H +#define BITCOIN_COMPRESSOR_H +#include "primitives/transaction.h" #include "script/script.h" +#include "serialize.h" + +class CKeyID; +class CPubKey; +class CScriptID; /** Compact serializer for scripts. * @@ -22,19 +28,23 @@ class CScriptCompressor { private: - // make this static for now (there are only 6 special scripts defined) - // this can potentially be extended together with a new nVersion for - // transactions, in which case this value becomes dependent on nVersion - // and nHeight of the enclosing transaction. + /** + * make this static for now (there are only 6 special scripts defined) + * this can potentially be extended together with a new nVersion for + * transactions, in which case this value becomes dependent on nVersion + * and nHeight of the enclosing transaction. + */ static const unsigned int nSpecialScripts = 6; CScript &script; protected: - // These check for scripts for which a special case with a shorter encoding is defined. - // They are implemented separately from the CScript test, as these test for exact byte - // sequence correspondences, and are more strict. For example, IsToPubKey also verifies - // whether the public key is valid (as invalid ones cannot be represented in compressed - // form). + /** + * These check for scripts for which a special case with a shorter encoding is defined. + * They are implemented separately from the CScript test, as these test for exact byte + * sequence correspondences, and are more strict. For example, IsToPubKey also verifies + * whether the public key is valid (as invalid ones cannot be represented in compressed + * form). + */ bool IsToKeyID(CKeyID &hash) const; bool IsToScriptID(CScriptID &hash) const; bool IsToPubKey(CPubKey &pubkey) const; @@ -81,4 +91,33 @@ public: } }; -#endif // H_BITCOIN_SCRIPT_COMPRESSOR +/** wrapper for CTxOut that provides a more compact serialization */ +class CTxOutCompressor +{ +private: + CTxOut &txout; + +public: + static uint64_t CompressAmount(uint64_t nAmount); + static uint64_t DecompressAmount(uint64_t nAmount); + + CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + if (!ser_action.ForRead()) { + uint64_t nVal = CompressAmount(txout.nValue); + READWRITE(VARINT(nVal)); + } else { + uint64_t nVal = 0; + READWRITE(VARINT(nVal)); + txout.nValue = DecompressAmount(nVal); + } + CScriptCompressor cscript(REF(txout.scriptPubKey)); + READWRITE(cscript); + } +}; + +#endif // BITCOIN_COMPRESSOR_H diff --git a/src/core.cpp b/src/core.cpp deleted file mode 100644 index e52327ba8e..0000000000 --- a/src/core.cpp +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "core.h" - -#include "tinyformat.h" - -#include <boost/foreach.hpp> - -std::string COutPoint::ToString() const -{ - return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n); -} - -CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn) -{ - prevout = prevoutIn; - scriptSig = scriptSigIn; - nSequence = nSequenceIn; -} - -CTxIn::CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn) -{ - prevout = COutPoint(hashPrevTx, nOut); - scriptSig = scriptSigIn; - nSequence = nSequenceIn; -} - -std::string CTxIn::ToString() const -{ - std::string str; - str += "CTxIn("; - str += prevout.ToString(); - if (prevout.IsNull()) - str += strprintf(", coinbase %s", HexStr(scriptSig)); - else - str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24)); - if (nSequence != std::numeric_limits<unsigned int>::max()) - str += strprintf(", nSequence=%u", nSequence); - str += ")"; - return str; -} - -CTxOut::CTxOut(int64_t nValueIn, CScript scriptPubKeyIn) -{ - nValue = nValueIn; - scriptPubKey = scriptPubKeyIn; -} - -uint256 CTxOut::GetHash() const -{ - return SerializeHash(*this); -} - -std::string CTxOut::ToString() const -{ - return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30)); -} - -CFeeRate::CFeeRate(int64_t nFeePaid, size_t nSize) -{ - if (nSize > 0) - nSatoshisPerK = nFeePaid*1000/nSize; - else - nSatoshisPerK = 0; -} - -int64_t CFeeRate::GetFee(size_t nSize) const -{ - int64_t nFee = nSatoshisPerK*nSize / 1000; - - if (nFee == 0 && nSatoshisPerK > 0) - nFee = nSatoshisPerK; - - return nFee; -} - -std::string CFeeRate::ToString() const -{ - return strprintf("%d.%08d BTC/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN); -} - -CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {} -CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {} - -uint256 CMutableTransaction::GetHash() const -{ - return SerializeHash(*this); -} - -void CTransaction::UpdateHash() const -{ - *const_cast<uint256*>(&hash) = SerializeHash(*this); -} - -CTransaction::CTransaction() : hash(0), nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { } - -CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) { - UpdateHash(); -} - -CTransaction& CTransaction::operator=(const CTransaction &tx) { - *const_cast<int*>(&nVersion) = tx.nVersion; - *const_cast<std::vector<CTxIn>*>(&vin) = tx.vin; - *const_cast<std::vector<CTxOut>*>(&vout) = tx.vout; - *const_cast<unsigned int*>(&nLockTime) = tx.nLockTime; - *const_cast<uint256*>(&hash) = tx.hash; - return *this; -} - -int64_t CTransaction::GetValueOut() const -{ - int64_t nValueOut = 0; - BOOST_FOREACH(const CTxOut& txout, vout) - { - nValueOut += txout.nValue; - if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut)) - throw std::runtime_error("CTransaction::GetValueOut() : value out of range"); - } - return nValueOut; -} - -double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const -{ - nTxSize = CalculateModifiedSize(nTxSize); - if (nTxSize == 0) return 0.0; - - return dPriorityInputs / nTxSize; -} - -unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const -{ - // In order to avoid disincentivizing cleaning up the UTXO set we don't count - // the constant overhead for each txin and up to 110 bytes of scriptSig (which - // is enough to cover a compressed pubkey p2sh redemption) for priority. - // Providing any more cleanup incentive than making additional inputs free would - // risk encouraging people to create junk outputs to redeem later. - if (nTxSize == 0) - nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); - - BOOST_FOREACH(const CTxIn& txin, vin) - { - unsigned int offset = 41U + std::min(110U, (unsigned int)txin.scriptSig.size()); - if (nTxSize > offset) - nTxSize -= offset; - } - return nTxSize; -} - -std::string CTransaction::ToString() const -{ - std::string str; - str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n", - GetHash().ToString().substr(0,10), - nVersion, - vin.size(), - vout.size(), - nLockTime); - for (unsigned int i = 0; i < vin.size(); i++) - str += " " + vin[i].ToString() + "\n"; - for (unsigned int i = 0; i < vout.size(); i++) - str += " " + vout[i].ToString() + "\n"; - return str; -} - -// Amount compression: -// * If the amount is 0, output 0 -// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9) -// * if e<9, the last digit of the resulting number cannot be 0; store it as d, and drop it (divide by 10) -// * call the result n -// * output 1 + 10*(9*n + d - 1) + e -// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9 -// (this is decodable, as d is in [1-9] and e is in [0-9]) - -uint64_t CTxOutCompressor::CompressAmount(uint64_t n) -{ - if (n == 0) - return 0; - int e = 0; - while (((n % 10) == 0) && e < 9) { - n /= 10; - e++; - } - if (e < 9) { - int d = (n % 10); - assert(d >= 1 && d <= 9); - n /= 10; - return 1 + (n*9 + d - 1)*10 + e; - } else { - return 1 + (n - 1)*10 + 9; - } -} - -uint64_t CTxOutCompressor::DecompressAmount(uint64_t x) -{ - // x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9 - if (x == 0) - return 0; - x--; - // x = 10*(9*n + d - 1) + e - int e = x % 10; - x /= 10; - uint64_t n = 0; - if (e < 9) { - // x = 9*n + d - 1 - int d = (x % 9) + 1; - x /= 9; - // x = n - n = x*10 + d; - } else { - n = x+1; - } - while (e) { - n *= 10; - e--; - } - return n; -} - -uint256 CBlockHeader::GetHash() const -{ - return Hash(BEGIN(nVersion), END(nNonce)); -} - -uint256 CBlock::BuildMerkleTree() 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 - // that the following merkle tree algorithm has a serious flaw related to - // duplicate txids, resulting in a vulnerability. (CVE-2012-2459) Bitcoin - // has since worked around the flaw, but for new applications you should - // use something different; don't just copy-and-paste this code without - // understanding the problem first. - vMerkleTree.clear(); - BOOST_FOREACH(const CTransaction& tx, vtx) - vMerkleTree.push_back(tx.GetHash()); - int j = 0; - for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) - { - for (int i = 0; i < nSize; i += 2) - { - int i2 = std::min(i+1, nSize-1); - vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), - BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); - } - j += nSize; - } - return (vMerkleTree.empty() ? 0 : 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 0; - BOOST_FOREACH(const uint256& otherside, vMerkleBranch) - { - if (nIndex & 1) - hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); - else - hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); - nIndex >>= 1; - } - return hash; -} - -std::string CBlock::ToString() const -{ - std::stringstream s; - s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n", - GetHash().ToString(), - nVersion, - hashPrevBlock.ToString(), - hashMerkleRoot.ToString(), - nTime, nBits, nNonce, - vtx.size()); - for (unsigned int i = 0; i < vtx.size(); i++) - { - 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/core.h b/src/core.h deleted file mode 100644 index 9a2ac47487..0000000000 --- a/src/core.h +++ /dev/null @@ -1,574 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_CORE_H -#define BITCOIN_CORE_H - -#include "script/compressor.h" -#include "script/script.h" -#include "serialize.h" -#include "uint256.h" - -#include <stdint.h> - -class CTransaction; - -static const int64_t COIN = 100000000; -static const int64_t CENT = 1000000; - -/** No amount larger than this (in satoshi) is valid */ -static const int64_t MAX_MONEY = 21000000 * COIN; -inline bool MoneyRange(int64_t nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } - -/** An outpoint - a combination of a transaction hash and an index n into its vout */ -class COutPoint -{ -public: - uint256 hash; - uint32_t n; - - COutPoint() { SetNull(); } - COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; } - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(FLATDATA(*this)); - } - - void SetNull() { hash = 0; n = (uint32_t) -1; } - bool IsNull() const { return (hash == 0 && n == (uint32_t) -1); } - - friend bool operator<(const COutPoint& a, const COutPoint& b) - { - return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n)); - } - - friend bool operator==(const COutPoint& a, const COutPoint& b) - { - return (a.hash == b.hash && a.n == b.n); - } - - friend bool operator!=(const COutPoint& a, const COutPoint& b) - { - return !(a == b); - } - - std::string ToString() const; -}; - -/** An inpoint - a combination of a transaction and an index n into its vin */ -class CInPoint -{ -public: - const CTransaction* ptx; - uint32_t n; - - CInPoint() { SetNull(); } - CInPoint(const CTransaction* ptxIn, uint32_t nIn) { ptx = ptxIn; n = nIn; } - void SetNull() { ptx = NULL; n = (uint32_t) -1; } - bool IsNull() const { return (ptx == NULL && n == (uint32_t) -1); } -}; - -/** An input of a transaction. It contains the location of the previous - * transaction's output that it claims and a signature that matches the - * output's public key. - */ -class CTxIn -{ -public: - COutPoint prevout; - CScript scriptSig; - uint32_t nSequence; - - CTxIn() - { - nSequence = std::numeric_limits<unsigned int>::max(); - } - - explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max()); - CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<uint32_t>::max()); - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(prevout); - READWRITE(scriptSig); - READWRITE(nSequence); - } - - bool IsFinal() const - { - return (nSequence == std::numeric_limits<uint32_t>::max()); - } - - friend bool operator==(const CTxIn& a, const CTxIn& b) - { - return (a.prevout == b.prevout && - a.scriptSig == b.scriptSig && - a.nSequence == b.nSequence); - } - - friend bool operator!=(const CTxIn& a, const CTxIn& b) - { - return !(a == b); - } - - std::string ToString() const; -}; - - - -/** Type-safe wrapper class to for fee rates - * (how much to pay based on transaction size) - */ -class CFeeRate -{ -private: - int64_t nSatoshisPerK; // unit is satoshis-per-1,000-bytes -public: - CFeeRate() : nSatoshisPerK(0) { } - explicit CFeeRate(int64_t _nSatoshisPerK): nSatoshisPerK(_nSatoshisPerK) { } - CFeeRate(int64_t nFeePaid, size_t nSize); - CFeeRate(const CFeeRate& other) { nSatoshisPerK = other.nSatoshisPerK; } - - int64_t GetFee(size_t size) const; // unit returned is satoshis - int64_t GetFeePerK() const { return GetFee(1000); } // satoshis-per-1000-bytes - - friend bool operator<(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK < b.nSatoshisPerK; } - friend bool operator>(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK > b.nSatoshisPerK; } - friend bool operator==(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK == b.nSatoshisPerK; } - friend bool operator<=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK <= b.nSatoshisPerK; } - friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; } - std::string ToString() const; - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(nSatoshisPerK); - } -}; - - -/** An output of a transaction. It contains the public key that the next input - * must be able to sign with to claim it. - */ -class CTxOut -{ -public: - int64_t nValue; - CScript scriptPubKey; - - CTxOut() - { - SetNull(); - } - - CTxOut(int64_t nValueIn, CScript scriptPubKeyIn); - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(nValue); - READWRITE(scriptPubKey); - } - - void SetNull() - { - nValue = -1; - scriptPubKey.clear(); - } - - bool IsNull() const - { - return (nValue == -1); - } - - uint256 GetHash() const; - - bool IsDust(CFeeRate minRelayTxFee) const - { - // "Dust" is defined in terms of CTransaction::minRelayTxFee, - // 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 - // need a CTxIn of at least 148 bytes to spend: - // so dust is a txout less than 546 satoshis - // with default minRelayTxFee. - size_t nSize = GetSerializeSize(SER_DISK,0)+148u; - return (nValue < 3*minRelayTxFee.GetFee(nSize)); - } - - friend bool operator==(const CTxOut& a, const CTxOut& b) - { - return (a.nValue == b.nValue && - a.scriptPubKey == b.scriptPubKey); - } - - friend bool operator!=(const CTxOut& a, const CTxOut& b) - { - return !(a == b); - } - - std::string ToString() const; -}; - - -struct CMutableTransaction; - -/** The basic transaction that is broadcasted on the network and contained in - * blocks. A transaction can contain multiple inputs and outputs. - */ -class CTransaction -{ -private: - /** Memory only. */ - const uint256 hash; - void UpdateHash() const; - -public: - static const int32_t CURRENT_VERSION=1; - - // The local variables are made const to prevent unintended modification - // without updating the cached hash value. However, CTransaction is not - // actually immutable; deserialization and assignment are implemented, - // and bypass the constness. This is safe, as they update the entire - // structure, including the hash. - const int32_t nVersion; - const std::vector<CTxIn> vin; - const std::vector<CTxOut> vout; - const uint32_t nLockTime; - - /** Construct a CTransaction that qualifies as IsNull() */ - CTransaction(); - - /** Convert a CMutableTransaction into a CTransaction. */ - CTransaction(const CMutableTransaction &tx); - - CTransaction& operator=(const CTransaction& tx); - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(*const_cast<int32_t*>(&this->nVersion)); - nVersion = this->nVersion; - READWRITE(*const_cast<std::vector<CTxIn>*>(&vin)); - READWRITE(*const_cast<std::vector<CTxOut>*>(&vout)); - READWRITE(*const_cast<uint32_t*>(&nLockTime)); - if (ser_action.ForRead()) - UpdateHash(); - } - - bool IsNull() const { - return vin.empty() && vout.empty(); - } - - const uint256& GetHash() const { - return hash; - } - - // Return sum of txouts. - int64_t GetValueOut() const; - // GetValueIn() is a method on CCoinsViewCache, because - // inputs must be known to compute value in. - - // Compute priority, given priority of inputs and (optionally) tx size - double ComputePriority(double dPriorityInputs, unsigned int nTxSize=0) const; - - // Compute modified tx size for priority calculation (optionally given tx size) - unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const; - - bool IsCoinBase() const - { - return (vin.size() == 1 && vin[0].prevout.IsNull()); - } - - friend bool operator==(const CTransaction& a, const CTransaction& b) - { - return a.hash == b.hash; - } - - friend bool operator!=(const CTransaction& a, const CTransaction& b) - { - return a.hash != b.hash; - } - - std::string ToString() const; -}; - -/** A mutable version of CTransaction. */ -struct CMutableTransaction -{ - int32_t nVersion; - std::vector<CTxIn> vin; - std::vector<CTxOut> vout; - uint32_t nLockTime; - - CMutableTransaction(); - CMutableTransaction(const CTransaction& tx); - - 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(vin); - READWRITE(vout); - READWRITE(nLockTime); - } - - /** Compute the hash of this CMutableTransaction. This is computed on the - * fly, as opposed to GetHash() in CTransaction, which uses a cached result. - */ - uint256 GetHash() const; -}; - -/** wrapper for CTxOut that provides a more compact serialization */ -class CTxOutCompressor -{ -private: - CTxOut &txout; - -public: - static uint64_t CompressAmount(uint64_t nAmount); - static uint64_t DecompressAmount(uint64_t nAmount); - - CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - if (!ser_action.ForRead()) { - uint64_t nVal = CompressAmount(txout.nValue); - READWRITE(VARINT(nVal)); - } else { - uint64_t nVal = 0; - READWRITE(VARINT(nVal)); - txout.nValue = DecompressAmount(nVal); - } - CScriptCompressor cscript(REF(txout.scriptPubKey)); - READWRITE(cscript); - } -}; - -/** Undo information for a CTxIn - * - * Contains the prevout's CTxOut being spent, and if this was the - * last output of the affected transaction, its metadata as well - * (coinbase or not, height, transaction version) - */ -class CTxInUndo -{ -public: - CTxOut txout; // the txout data before being spent - bool fCoinBase; // if the outpoint was the last unspent: whether it belonged to a coinbase - unsigned int nHeight; // if the outpoint was the last unspent: its height - int nVersion; // if the outpoint was the last unspent: its version - - CTxInUndo() : txout(), fCoinBase(false), nHeight(0), nVersion(0) {} - CTxInUndo(const CTxOut &txoutIn, bool fCoinBaseIn = false, unsigned int nHeightIn = 0, int nVersionIn = 0) : txout(txoutIn), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), nVersion(nVersionIn) { } - - unsigned int GetSerializeSize(int nType, int nVersion) const { - return ::GetSerializeSize(VARINT(nHeight*2+(fCoinBase ? 1 : 0)), nType, nVersion) + - (nHeight > 0 ? ::GetSerializeSize(VARINT(this->nVersion), nType, nVersion) : 0) + - ::GetSerializeSize(CTxOutCompressor(REF(txout)), nType, nVersion); - } - - template<typename Stream> - void Serialize(Stream &s, int nType, int nVersion) const { - ::Serialize(s, VARINT(nHeight*2+(fCoinBase ? 1 : 0)), nType, nVersion); - if (nHeight > 0) - ::Serialize(s, VARINT(this->nVersion), nType, nVersion); - ::Serialize(s, CTxOutCompressor(REF(txout)), nType, nVersion); - } - - template<typename Stream> - void Unserialize(Stream &s, int nType, int nVersion) { - unsigned int nCode = 0; - ::Unserialize(s, VARINT(nCode), nType, nVersion); - nHeight = nCode / 2; - fCoinBase = nCode & 1; - if (nHeight > 0) - ::Unserialize(s, VARINT(this->nVersion), nType, nVersion); - ::Unserialize(s, REF(CTxOutCompressor(REF(txout))), nType, nVersion); - } -}; - -/** Undo information for a CTransaction */ -class CTxUndo -{ -public: - // undo information for all txins - std::vector<CTxInUndo> vprevout; - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(vprevout); - } -}; - - -/** Nodes collect new transactions into a block, hash them into a hash tree, - * and scan through nonce values to make the block's hash satisfy proof-of-work - * requirements. When they solve the proof-of-work, they broadcast the block - * to everyone and the block is added to the block chain. The first transaction - * in the block is a special one that creates a new coin owned by the creator - * of the block. - */ -class CBlockHeader -{ -public: - // header - static const int32_t CURRENT_VERSION=2; - int32_t nVersion; - uint256 hashPrevBlock; - uint256 hashMerkleRoot; - uint32_t nTime; - uint32_t nBits; - uint32_t nNonce; - - CBlockHeader() - { - SetNull(); - } - - 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(hashPrevBlock); - READWRITE(hashMerkleRoot); - READWRITE(nTime); - READWRITE(nBits); - READWRITE(nNonce); - } - - void SetNull() - { - nVersion = CBlockHeader::CURRENT_VERSION; - hashPrevBlock = 0; - hashMerkleRoot = 0; - nTime = 0; - nBits = 0; - nNonce = 0; - } - - bool IsNull() const - { - return (nBits == 0); - } - - uint256 GetHash() const; - - int64_t GetBlockTime() const - { - return (int64_t)nTime; - } -}; - - -class CBlock : public CBlockHeader -{ -public: - // network and disk - std::vector<CTransaction> vtx; - - // memory only - mutable std::vector<uint256> vMerkleTree; - - CBlock() - { - SetNull(); - } - - CBlock(const CBlockHeader &header) - { - SetNull(); - *((CBlockHeader*)this) = header; - } - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(*(CBlockHeader*)this); - READWRITE(vtx); - } - - void SetNull() - { - CBlockHeader::SetNull(); - vtx.clear(); - vMerkleTree.clear(); - } - - CBlockHeader GetBlockHeader() const - { - CBlockHeader block; - block.nVersion = nVersion; - block.hashPrevBlock = hashPrevBlock; - block.hashMerkleRoot = hashMerkleRoot; - block.nTime = nTime; - block.nBits = nBits; - block.nNonce = nNonce; - return block; - } - - uint256 BuildMerkleTree() const; - - std::vector<uint256> GetMerkleBranch(int nIndex) const; - static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex); - std::string ToString() const; -}; - - -/** Describes a place in the block chain to another node such that if the - * other node doesn't have the same branch, it can find a recent common trunk. - * The further back it is, the further before the fork it may be. - */ -struct CBlockLocator -{ - std::vector<uint256> vHave; - - CBlockLocator() {} - - CBlockLocator(const std::vector<uint256>& vHaveIn) - { - vHave = vHaveIn; - } - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - if (!(nType & SER_GETHASH)) - READWRITE(nVersion); - READWRITE(vHave); - } - - void SetNull() - { - vHave.clear(); - } - - bool IsNull() - { - return vHave.empty(); - } -}; - -#endif // BITCOIN_CORE_H diff --git a/src/core_io.h b/src/core_io.h index 6268a3bf58..0989cf7437 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -1,13 +1,14 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_CORE_IO_H__ -#define __BITCOIN_CORE_IO_H__ +#ifndef BITCOIN_CORE_IO_H +#define BITCOIN_CORE_IO_H #include <string> #include <vector> +class CBlock; class CScript; class CTransaction; class uint256; @@ -16,13 +17,16 @@ class UniValue; // core_read.cpp extern CScript ParseScript(std::string s); 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); +extern uint256 ParseHashStr(const std::string&, const std::string& strName); extern std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName); // 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 TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry); -#endif // __BITCOIN_CORE_IO_H__ +#endif // BITCOIN_CORE_IO_H diff --git a/src/core_read.cpp b/src/core_read.cpp index 6bd3d9a4fa..7999030662 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -1,14 +1,18 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "core_io.h" -#include "core.h" +#include "primitives/block.h" +#include "primitives/transaction.h" #include "script/script.h" #include "serialize.h" +#include "streams.h" #include "univalue/univalue.h" #include "util.h" +#include "utilstrencodings.h" +#include "version.h" #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/predicate.hpp> @@ -98,7 +102,24 @@ bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx) try { ssData >> tx; } - catch (const std::exception &) { + catch (const std::exception&) { + return false; + } + + return true; +} + +bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk) +{ + if (!IsHex(strHexBlk)) + return false; + + std::vector<unsigned char> blockData(ParseHex(strHexBlk)); + CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION); + try { + ssBlock >> block; + } + catch (const std::exception&) { return false; } @@ -110,6 +131,11 @@ uint256 ParseHashUV(const UniValue& v, const string& strName) string strHex; if (v.isStr()) strHex = v.getValStr(); + return ParseHashStr(strHex, strName); // Note: ParseHashStr("") throws a runtime_error +} + +uint256 ParseHashStr(const std::string& strHex, const std::string& strName) +{ if (!IsHex(strHex)) // Note: IsHex("") is false throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')"); diff --git a/src/core_write.cpp b/src/core_write.cpp index cd64aabf63..b6fd7fe877 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -1,22 +1,59 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "core_io.h" #include "base58.h" -#include "core.h" +#include "primitives/transaction.h" #include "script/script.h" #include "script/standard.h" #include "serialize.h" +#include "streams.h" #include "univalue/univalue.h" #include "util.h" #include "utilmoneystr.h" +#include "utilstrencodings.h" #include <boost/foreach.hpp> using namespace std; +string FormatScript(const CScript& script) +{ + string ret; + CScript::const_iterator it = script.begin(); + opcodetype op; + while (it != script.end()) { + CScript::const_iterator it2 = it; + vector<unsigned char> vch; + if (script.GetOp2(it, op, &vch)) { + if (op == OP_0) { + ret += "0 "; + continue; + } else if ((op >= OP_1 && op <= OP_16) || op == OP_1NEGATE) { + ret += strprintf("%i ", op - OP_1NEGATE - 1); + continue; + } else if (op >= OP_NOP && op <= OP_CHECKMULTISIGVERIFY) { + string str(GetOpName(op)); + if (str.substr(0, 3) == string("OP_")) { + ret += str.substr(3, string::npos) + " "; + continue; + } + } + if (vch.size() > 0) { + ret += strprintf("0x%x 0x%x ", HexStr(it2, it - vch.size()), HexStr(it - vch.size(), it)); + } else { + ret += strprintf("0x%x", HexStr(it2, it)); + } + continue; + } + ret += strprintf("0x%x ", HexStr(it2, script.end())); + break; + } + return ret.substr(0, ret.size() - 1); +} + string EncodeHexTx(const CTransaction& tx) { CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); @@ -92,4 +129,6 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry) if (hashBlock != 0) entry.pushKV("blockhash", hashBlock.GetHex()); + + entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction". } diff --git a/src/crypter.cpp b/src/crypter.cpp index a872df7024..00f7f7f1bd 100644 --- a/src/crypter.cpp +++ b/src/crypter.cpp @@ -1,10 +1,11 @@ -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-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 "crypter.h" #include "script/script.h" +#include "script/standard.h" #include "util.h" #include <string> diff --git a/src/crypter.h b/src/crypter.h index c7424c9b20..7b4c2f2613 100644 --- a/src/crypter.h +++ b/src/crypter.h @@ -1,33 +1,33 @@ -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 __CRYPTER_H__ -#define __CRYPTER_H__ +#ifndef BITCOIN_CRYPTER_H +#define BITCOIN_CRYPTER_H #include "allocators.h" -#include "serialize.h" #include "keystore.h" +#include "serialize.h" class uint256; const unsigned int WALLET_CRYPTO_KEY_SIZE = 32; const unsigned int WALLET_CRYPTO_SALT_SIZE = 8; -/* -Private key encryption is done based on a CMasterKey, -which holds a salt and random encryption key. - -CMasterKeys are encrypted using AES-256-CBC using a key -derived using derivation method nDerivationMethod -(0 == EVP_sha512()) and derivation iterations nDeriveIterations. -vchOtherDerivationParameters is provided for alternative algorithms -which may require more parameters (such as scrypt). - -Wallet Private Keys are then encrypted using AES-256-CBC -with the double-sha256 of the public key as the IV, and the -master key's key as the encryption key (see keystore.[ch]). -*/ +/** + * Private key encryption is done based on a CMasterKey, + * which holds a salt and random encryption key. + * + * CMasterKeys are encrypted using AES-256-CBC using a key + * derived using derivation method nDerivationMethod + * (0 == EVP_sha512()) and derivation iterations nDeriveIterations. + * vchOtherDerivationParameters is provided for alternative algorithms + * which may require more parameters (such as scrypt). + * + * Wallet Private Keys are then encrypted using AES-256-CBC + * with the double-sha256 of the public key as the IV, and the + * master key's key as the encryption key (see keystore.[ch]). + */ /** Master key for wallet encryption */ class CMasterKey @@ -35,12 +35,12 @@ class CMasterKey public: std::vector<unsigned char> vchCryptedKey; std::vector<unsigned char> vchSalt; - // 0 = EVP_sha512() - // 1 = scrypt() + //! 0 = EVP_sha512() + //! 1 = scrypt() unsigned int nDerivationMethod; unsigned int nDeriveIterations; - // Use this for more parameters to key derivation, - // such as the various parameters to scrypt + //! Use this for more parameters to key derivation, + //! such as the various parameters to scrypt std::vector<unsigned char> vchOtherDerivationParameters; ADD_SERIALIZE_METHODS; @@ -120,17 +120,17 @@ private: CKeyingMaterial vMasterKey; - // if fUseCrypto is true, mapKeys must be empty - // if fUseCrypto is false, vMasterKey must be empty + //! if fUseCrypto is true, mapKeys must be empty + //! if fUseCrypto is false, vMasterKey must be empty bool fUseCrypto; - // keeps track of whether Unlock has run a thourough check before + //! keeps track of whether Unlock has run a thorough check before bool fDecryptionThoroughlyChecked; protected: bool SetCrypted(); - // will encrypt previously unencrypted keys + //! will encrypt previously unencrypted keys bool EncryptKeys(CKeyingMaterial& vMasterKeyIn); bool Unlock(const CKeyingMaterial& vMasterKeyIn); @@ -189,10 +189,11 @@ public: } } - /* Wallet status (encrypted, locked) changed. + /** + * Wallet status (encrypted, locked) changed. * Note: Called without locks held. */ boost::signals2::signal<void (CCryptoKeyStore* wallet)> NotifyStatusChanged; }; -#endif // __CRYPTER_H__ +#endif // BITCOIN_CRYPTER_H diff --git a/src/crypto/common.h b/src/crypto/common.h index 8f675a16c5..8b04b1f728 100644 --- a/src/crypto/common.h +++ b/src/crypto/common.h @@ -1,5 +1,5 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_CRYPTO_COMMON_H @@ -8,12 +8,15 @@ #if defined(HAVE_CONFIG_H) #include "bitcoin-config.h" #endif + #include <stdint.h> + #if defined(HAVE_ENDIAN_H) #include <endian.h> #endif -uint32_t static inline ReadLE32(const unsigned char *ptr) { +uint32_t static inline ReadLE32(const unsigned char* ptr) +{ #if HAVE_DECL_LE32TOH == 1 return le32toh(*((uint32_t*)ptr)); #elif !defined(WORDS_BIGENDIAN) @@ -23,8 +26,8 @@ uint32_t static inline ReadLE32(const unsigned char *ptr) { #endif } -uint64_t static inline ReadLE64(const unsigned char *ptr) { - +uint64_t static inline ReadLE64(const unsigned char* ptr) +{ #if HAVE_DECL_LE64TOH == 1 return le64toh(*((uint64_t*)ptr)); #elif !defined(WORDS_BIGENDIAN) @@ -35,28 +38,40 @@ uint64_t static inline ReadLE64(const unsigned char *ptr) { #endif } -void static inline WriteLE32(unsigned char *ptr, uint32_t x) { +void static inline WriteLE32(unsigned char* ptr, uint32_t x) +{ #if HAVE_DECL_HTOLE32 == 1 *((uint32_t*)ptr) = htole32(x); #elif !defined(WORDS_BIGENDIAN) *((uint32_t*)ptr) = x; #else - ptr[3] = x >> 24; ptr[2] = x >> 16; ptr[1] = x >> 8; ptr[0] = x; + ptr[3] = x >> 24; + ptr[2] = x >> 16; + ptr[1] = x >> 8; + ptr[0] = x; #endif } -void static inline WriteLE64(unsigned char *ptr, uint64_t x) { +void static inline WriteLE64(unsigned char* ptr, uint64_t x) +{ #if HAVE_DECL_HTOLE64 == 1 *((uint64_t*)ptr) = htole64(x); #elif !defined(WORDS_BIGENDIAN) *((uint64_t*)ptr) = x; #else - ptr[7] = x >> 56; ptr[6] = x >> 48; ptr[5] = x >> 40; ptr[4] = x >> 32; - ptr[3] = x >> 24; ptr[2] = x >> 16; ptr[1] = x >> 8; ptr[0] = x; + ptr[7] = x >> 56; + ptr[6] = x >> 48; + ptr[5] = x >> 40; + ptr[4] = x >> 32; + ptr[3] = x >> 24; + ptr[2] = x >> 16; + ptr[1] = x >> 8; + ptr[0] = x; #endif } -uint32_t static inline ReadBE32(const unsigned char *ptr) { +uint32_t static inline ReadBE32(const unsigned char* ptr) +{ #if HAVE_DECL_BE32TOH == 1 return be32toh(*((uint32_t*)ptr)); #else @@ -64,7 +79,8 @@ uint32_t static inline ReadBE32(const unsigned char *ptr) { #endif } -uint64_t static inline ReadBE64(const unsigned char *ptr) { +uint64_t static inline ReadBE64(const unsigned char* ptr) +{ #if HAVE_DECL_BE64TOH == 1 return be64toh(*((uint64_t*)ptr)); #else @@ -73,21 +89,32 @@ uint64_t static inline ReadBE64(const unsigned char *ptr) { #endif } -void static inline WriteBE32(unsigned char *ptr, uint32_t x) { +void static inline WriteBE32(unsigned char* ptr, uint32_t x) +{ #if HAVE_DECL_HTOBE32 == 1 *((uint32_t*)ptr) = htobe32(x); #else - ptr[0] = x >> 24; ptr[1] = x >> 16; ptr[2] = x >> 8; ptr[3] = x; + ptr[0] = x >> 24; + ptr[1] = x >> 16; + ptr[2] = x >> 8; + ptr[3] = x; #endif } -void static inline WriteBE64(unsigned char *ptr, uint64_t x) { +void static inline WriteBE64(unsigned char* ptr, uint64_t x) +{ #if HAVE_DECL_HTOBE64 == 1 *((uint64_t*)ptr) = htobe64(x); #else - ptr[0] = x >> 56; ptr[1] = x >> 48; ptr[2] = x >> 40; ptr[3] = x >> 32; - ptr[4] = x >> 24; ptr[5] = x >> 16; ptr[6] = x >> 8; ptr[7] = x; + ptr[0] = x >> 56; + ptr[1] = x >> 48; + ptr[2] = x >> 40; + ptr[3] = x >> 32; + ptr[4] = x >> 24; + ptr[5] = x >> 16; + ptr[6] = x >> 8; + ptr[7] = x; #endif } -#endif +#endif // BITCOIN_CRYPTO_COMMON_H diff --git a/src/crypto/hmac_sha256.cpp b/src/crypto/hmac_sha256.cpp new file mode 100644 index 0000000000..3c791625d0 --- /dev/null +++ b/src/crypto/hmac_sha256.cpp @@ -0,0 +1,34 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "crypto/hmac_sha256.h" + +#include <string.h> + +CHMAC_SHA256::CHMAC_SHA256(const unsigned char* key, size_t keylen) +{ + unsigned char rkey[64]; + if (keylen <= 64) { + memcpy(rkey, key, keylen); + memset(rkey + keylen, 0, 64 - keylen); + } else { + CSHA256().Write(key, keylen).Finalize(rkey); + memset(rkey + 32, 0, 32); + } + + for (int n = 0; n < 64; n++) + rkey[n] ^= 0x5c; + outer.Write(rkey, 64); + + for (int n = 0; n < 64; n++) + rkey[n] ^= 0x5c ^ 0x36; + inner.Write(rkey, 64); +} + +void CHMAC_SHA256::Finalize(unsigned char hash[OUTPUT_SIZE]) +{ + unsigned char temp[32]; + inner.Finalize(temp); + outer.Write(temp, 32).Finalize(hash); +} diff --git a/src/crypto/hmac_sha256.h b/src/crypto/hmac_sha256.h new file mode 100644 index 0000000000..1519c1457e --- /dev/null +++ b/src/crypto/hmac_sha256.h @@ -0,0 +1,32 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CRYPTO_HMAC_SHA256_H +#define BITCOIN_CRYPTO_HMAC_SHA256_H + +#include "crypto/sha256.h" + +#include <stdint.h> +#include <stdlib.h> + +/** A hasher class for HMAC-SHA-512. */ +class CHMAC_SHA256 +{ +private: + CSHA256 outer; + CSHA256 inner; + +public: + static const size_t OUTPUT_SIZE = 32; + + CHMAC_SHA256(const unsigned char* key, size_t keylen); + CHMAC_SHA256& Write(const unsigned char* data, size_t len) + { + inner.Write(data, len); + return *this; + } + void Finalize(unsigned char hash[OUTPUT_SIZE]); +}; + +#endif // BITCOIN_CRYPTO_HMAC_SHA256_H diff --git a/src/crypto/hmac_sha512.cpp b/src/crypto/hmac_sha512.cpp new file mode 100644 index 0000000000..5939c6ec47 --- /dev/null +++ b/src/crypto/hmac_sha512.cpp @@ -0,0 +1,34 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "crypto/hmac_sha512.h" + +#include <string.h> + +CHMAC_SHA512::CHMAC_SHA512(const unsigned char* key, size_t keylen) +{ + unsigned char rkey[128]; + if (keylen <= 128) { + memcpy(rkey, key, keylen); + memset(rkey + keylen, 0, 128 - keylen); + } else { + CSHA512().Write(key, keylen).Finalize(rkey); + memset(rkey + 64, 0, 64); + } + + for (int n = 0; n < 128; n++) + rkey[n] ^= 0x5c; + outer.Write(rkey, 128); + + for (int n = 0; n < 128; n++) + rkey[n] ^= 0x5c ^ 0x36; + inner.Write(rkey, 128); +} + +void CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) +{ + unsigned char temp[64]; + inner.Finalize(temp); + outer.Write(temp, 64).Finalize(hash); +} diff --git a/src/crypto/hmac_sha512.h b/src/crypto/hmac_sha512.h new file mode 100644 index 0000000000..17dee61ea8 --- /dev/null +++ b/src/crypto/hmac_sha512.h @@ -0,0 +1,32 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CRYPTO_HMAC_SHA512_H +#define BITCOIN_CRYPTO_HMAC_SHA512_H + +#include "crypto/sha512.h" + +#include <stdint.h> +#include <stdlib.h> + +/** A hasher class for HMAC-SHA-512. */ +class CHMAC_SHA512 +{ +private: + CSHA512 outer; + CSHA512 inner; + +public: + static const size_t OUTPUT_SIZE = 64; + + CHMAC_SHA512(const unsigned char* key, size_t keylen); + CHMAC_SHA512& Write(const unsigned char* data, size_t len) + { + inner.Write(data, len); + return *this; + } + void Finalize(unsigned char hash[OUTPUT_SIZE]); +}; + +#endif // BITCOIN_CRYPTO_HMAC_SHA512_H diff --git a/src/crypto/rfc6979_hmac_sha256.cpp b/src/crypto/rfc6979_hmac_sha256.cpp new file mode 100644 index 0000000000..a8c971c3ba --- /dev/null +++ b/src/crypto/rfc6979_hmac_sha256.cpp @@ -0,0 +1,47 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "crypto/rfc6979_hmac_sha256.h" + +#include <string.h> + +#include <algorithm> + +static const unsigned char zero[1] = {0x00}; +static const unsigned char one[1] = {0x01}; + +RFC6979_HMAC_SHA256::RFC6979_HMAC_SHA256(const unsigned char* key, size_t keylen, const unsigned char* msg, size_t msglen) : retry(false) +{ + memset(V, 0x01, sizeof(V)); + memset(K, 0x00, sizeof(K)); + + CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(zero, sizeof(zero)).Write(key, keylen).Write(msg, msglen).Finalize(K); + CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V); + CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(one, sizeof(one)).Write(key, keylen).Write(msg, msglen).Finalize(K); + CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V); +} + +RFC6979_HMAC_SHA256::~RFC6979_HMAC_SHA256() +{ + memset(V, 0x01, sizeof(V)); + memset(K, 0x00, sizeof(K)); +} + +void RFC6979_HMAC_SHA256::Generate(unsigned char* output, size_t outputlen) +{ + if (retry) { + CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(zero, sizeof(zero)).Finalize(K); + CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V); + } + + while (outputlen > 0) { + CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V); + size_t len = std::min(outputlen, sizeof(V)); + memcpy(output, V, len); + output += len; + outputlen -= len; + } + + retry = true; +} diff --git a/src/crypto/rfc6979_hmac_sha256.h b/src/crypto/rfc6979_hmac_sha256.h new file mode 100644 index 0000000000..f3a54a5d11 --- /dev/null +++ b/src/crypto/rfc6979_hmac_sha256.h @@ -0,0 +1,36 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_RFC6979_HMAC_SHA256_H +#define BITCOIN_RFC6979_HMAC_SHA256_H + +#include "crypto/hmac_sha256.h" + +#include <stdint.h> +#include <stdlib.h> + +/** The RFC 6979 PRNG using HMAC-SHA256. */ +class RFC6979_HMAC_SHA256 +{ +private: + unsigned char V[CHMAC_SHA256::OUTPUT_SIZE]; + unsigned char K[CHMAC_SHA256::OUTPUT_SIZE]; + bool retry; + +public: + /** + * Construct a new RFC6979 PRNG, using the given key and message. + * The message is assumed to be already hashed. + */ + RFC6979_HMAC_SHA256(const unsigned char* key, size_t keylen, const unsigned char* msg, size_t msglen); + + /** + * Generate a byte array. + */ + void Generate(unsigned char* output, size_t outputlen); + + ~RFC6979_HMAC_SHA256(); +}; + +#endif // BITCOIN_RFC6979_HMAC_SHA256_H diff --git a/src/crypto/ripemd160.cpp b/src/crypto/ripemd160.cpp index b5e9f0df49..77c9acfc26 100644 --- a/src/crypto/ripemd160.cpp +++ b/src/crypto/ripemd160.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "crypto/ripemd160.h" @@ -9,11 +9,11 @@ #include <string.h> // Internal implementation code. -namespace { - +namespace +{ /// Internal RIPEMD-160 implementation. -namespace ripemd160 { - +namespace ripemd160 +{ uint32_t inline f1(uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; } uint32_t inline f2(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (~x & z); } uint32_t inline f3(uint32_t x, uint32_t y, uint32_t z) { return (x | ~y) ^ z; } @@ -21,7 +21,8 @@ uint32_t inline f4(uint32_t x, uint32_t y, uint32_t z) { return (x & z) | (y & ~ uint32_t inline f5(uint32_t x, uint32_t y, uint32_t z) { return x ^ (y | ~z); } /** Initialize RIPEMD-160 state. */ -void inline Initialize(uint32_t *s) { +void inline Initialize(uint32_t* s) +{ s[0] = 0x67452301ul; s[1] = 0xEFCDAB89ul; s[2] = 0x98BADCFEul; @@ -29,139 +30,223 @@ void inline Initialize(uint32_t *s) { s[4] = 0xC3D2E1F0ul; } -uint32_t inline rol(uint32_t x, int i) { return (x << i) | (x >> (32-i)); } +uint32_t inline rol(uint32_t x, int i) { return (x << i) | (x >> (32 - i)); } -void inline Round(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t f, uint32_t x, uint32_t k, int r) { +void inline Round(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t f, uint32_t x, uint32_t k, int r) +{ a = rol(a + f + x + k, r) + e; c = rol(c, 10); } -void inline R11(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); } -void inline R21(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r); } -void inline R31(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r); } -void inline R41(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r); } -void inline R51(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r); } +void inline R11(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); } +void inline R21(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r); } +void inline R31(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r); } +void inline R41(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r); } +void inline R51(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r); } -void inline R12(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r); } -void inline R22(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r); } -void inline R32(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r); } -void inline R42(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r); } -void inline R52(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); } +void inline R12(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r); } +void inline R22(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r); } +void inline R32(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r); } +void inline R42(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r); } +void inline R52(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); } /** Perform a RIPEMD-160 transformation, processing a 64-byte chunk. */ -void Transform(uint32_t *s, const unsigned char *chunk) { +void Transform(uint32_t* s, const unsigned char* chunk) +{ uint32_t a1 = s[0], b1 = s[1], c1 = s[2], d1 = s[3], e1 = s[4]; - uint32_t a2 = a1 , b2 = b1 , c2 = c1 , d2 = d1 , e2 = e1 ; - uint32_t w0 = ReadLE32(chunk + 0), w1 = ReadLE32(chunk + 4), w2 = ReadLE32(chunk + 8), w3 = ReadLE32(chunk + 12); - uint32_t w4 = ReadLE32(chunk + 16), w5 = ReadLE32(chunk + 20), w6 = ReadLE32(chunk + 24), w7 = ReadLE32(chunk + 28); - uint32_t w8 = ReadLE32(chunk + 32), w9 = ReadLE32(chunk + 36), w10 = ReadLE32(chunk + 40), w11 = ReadLE32(chunk + 44); + uint32_t a2 = a1, b2 = b1, c2 = c1, d2 = d1, e2 = e1; + uint32_t w0 = ReadLE32(chunk + 0), w1 = ReadLE32(chunk + 4), w2 = ReadLE32(chunk + 8), w3 = ReadLE32(chunk + 12); + uint32_t w4 = ReadLE32(chunk + 16), w5 = ReadLE32(chunk + 20), w6 = ReadLE32(chunk + 24), w7 = ReadLE32(chunk + 28); + uint32_t w8 = ReadLE32(chunk + 32), w9 = ReadLE32(chunk + 36), w10 = ReadLE32(chunk + 40), w11 = ReadLE32(chunk + 44); uint32_t w12 = ReadLE32(chunk + 48), w13 = ReadLE32(chunk + 52), w14 = ReadLE32(chunk + 56), w15 = ReadLE32(chunk + 60); - R11(a1, b1, c1, d1, e1, w0 , 11); R12(a2, b2, c2, d2, e2, w5 , 8); - R11(e1, a1, b1, c1, d1, w1 , 14); R12(e2, a2, b2, c2, d2, w14, 9); - R11(d1, e1, a1, b1, c1, w2 , 15); R12(d2, e2, a2, b2, c2, w7 , 9); - R11(c1, d1, e1, a1, b1, w3 , 12); R12(c2, d2, e2, a2, b2, w0 , 11); - R11(b1, c1, d1, e1, a1, w4 , 5); R12(b2, c2, d2, e2, a2, w9 , 13); - R11(a1, b1, c1, d1, e1, w5 , 8); R12(a2, b2, c2, d2, e2, w2 , 15); - R11(e1, a1, b1, c1, d1, w6 , 7); R12(e2, a2, b2, c2, d2, w11, 15); - R11(d1, e1, a1, b1, c1, w7 , 9); R12(d2, e2, a2, b2, c2, w4 , 5); - R11(c1, d1, e1, a1, b1, w8 , 11); R12(c2, d2, e2, a2, b2, w13, 7); - R11(b1, c1, d1, e1, a1, w9 , 13); R12(b2, c2, d2, e2, a2, w6 , 7); - R11(a1, b1, c1, d1, e1, w10, 14); R12(a2, b2, c2, d2, e2, w15, 8); - R11(e1, a1, b1, c1, d1, w11, 15); R12(e2, a2, b2, c2, d2, w8 , 11); - R11(d1, e1, a1, b1, c1, w12, 6); R12(d2, e2, a2, b2, c2, w1 , 14); - R11(c1, d1, e1, a1, b1, w13, 7); R12(c2, d2, e2, a2, b2, w10, 14); - R11(b1, c1, d1, e1, a1, w14, 9); R12(b2, c2, d2, e2, a2, w3 , 12); - R11(a1, b1, c1, d1, e1, w15, 8); R12(a2, b2, c2, d2, e2, w12, 6); - - R21(e1, a1, b1, c1, d1, w7 , 7); R22(e2, a2, b2, c2, d2, w6 , 9); - R21(d1, e1, a1, b1, c1, w4 , 6); R22(d2, e2, a2, b2, c2, w11, 13); - R21(c1, d1, e1, a1, b1, w13, 8); R22(c2, d2, e2, a2, b2, w3 , 15); - R21(b1, c1, d1, e1, a1, w1 , 13); R22(b2, c2, d2, e2, a2, w7 , 7); - R21(a1, b1, c1, d1, e1, w10, 11); R22(a2, b2, c2, d2, e2, w0 , 12); - R21(e1, a1, b1, c1, d1, w6 , 9); R22(e2, a2, b2, c2, d2, w13, 8); - R21(d1, e1, a1, b1, c1, w15, 7); R22(d2, e2, a2, b2, c2, w5 , 9); - R21(c1, d1, e1, a1, b1, w3 , 15); R22(c2, d2, e2, a2, b2, w10, 11); - R21(b1, c1, d1, e1, a1, w12, 7); R22(b2, c2, d2, e2, a2, w14, 7); - R21(a1, b1, c1, d1, e1, w0 , 12); R22(a2, b2, c2, d2, e2, w15, 7); - R21(e1, a1, b1, c1, d1, w9 , 15); R22(e2, a2, b2, c2, d2, w8 , 12); - R21(d1, e1, a1, b1, c1, w5 , 9); R22(d2, e2, a2, b2, c2, w12, 7); - R21(c1, d1, e1, a1, b1, w2 , 11); R22(c2, d2, e2, a2, b2, w4 , 6); - R21(b1, c1, d1, e1, a1, w14, 7); R22(b2, c2, d2, e2, a2, w9 , 15); - R21(a1, b1, c1, d1, e1, w11, 13); R22(a2, b2, c2, d2, e2, w1 , 13); - R21(e1, a1, b1, c1, d1, w8 , 12); R22(e2, a2, b2, c2, d2, w2 , 11); - - R31(d1, e1, a1, b1, c1, w3 , 11); R32(d2, e2, a2, b2, c2, w15, 9); - R31(c1, d1, e1, a1, b1, w10, 13); R32(c2, d2, e2, a2, b2, w5 , 7); - R31(b1, c1, d1, e1, a1, w14, 6); R32(b2, c2, d2, e2, a2, w1 , 15); - R31(a1, b1, c1, d1, e1, w4 , 7); R32(a2, b2, c2, d2, e2, w3 , 11); - R31(e1, a1, b1, c1, d1, w9 , 14); R32(e2, a2, b2, c2, d2, w7 , 8); - R31(d1, e1, a1, b1, c1, w15, 9); R32(d2, e2, a2, b2, c2, w14, 6); - R31(c1, d1, e1, a1, b1, w8 , 13); R32(c2, d2, e2, a2, b2, w6 , 6); - R31(b1, c1, d1, e1, a1, w1 , 15); R32(b2, c2, d2, e2, a2, w9 , 14); - R31(a1, b1, c1, d1, e1, w2 , 14); R32(a2, b2, c2, d2, e2, w11, 12); - R31(e1, a1, b1, c1, d1, w7 , 8); R32(e2, a2, b2, c2, d2, w8 , 13); - R31(d1, e1, a1, b1, c1, w0 , 13); R32(d2, e2, a2, b2, c2, w12, 5); - R31(c1, d1, e1, a1, b1, w6 , 6); R32(c2, d2, e2, a2, b2, w2 , 14); - R31(b1, c1, d1, e1, a1, w13, 5); R32(b2, c2, d2, e2, a2, w10, 13); - R31(a1, b1, c1, d1, e1, w11, 12); R32(a2, b2, c2, d2, e2, w0 , 13); - R31(e1, a1, b1, c1, d1, w5 , 7); R32(e2, a2, b2, c2, d2, w4 , 7); - R31(d1, e1, a1, b1, c1, w12, 5); R32(d2, e2, a2, b2, c2, w13, 5); - - R41(c1, d1, e1, a1, b1, w1 , 11); R42(c2, d2, e2, a2, b2, w8 , 15); - R41(b1, c1, d1, e1, a1, w9 , 12); R42(b2, c2, d2, e2, a2, w6 , 5); - R41(a1, b1, c1, d1, e1, w11, 14); R42(a2, b2, c2, d2, e2, w4 , 8); - R41(e1, a1, b1, c1, d1, w10, 15); R42(e2, a2, b2, c2, d2, w1 , 11); - R41(d1, e1, a1, b1, c1, w0 , 14); R42(d2, e2, a2, b2, c2, w3 , 14); - R41(c1, d1, e1, a1, b1, w8 , 15); R42(c2, d2, e2, a2, b2, w11, 14); - R41(b1, c1, d1, e1, a1, w12, 9); R42(b2, c2, d2, e2, a2, w15, 6); - R41(a1, b1, c1, d1, e1, w4 , 8); R42(a2, b2, c2, d2, e2, w0 , 14); - R41(e1, a1, b1, c1, d1, w13, 9); R42(e2, a2, b2, c2, d2, w5 , 6); - R41(d1, e1, a1, b1, c1, w3 , 14); R42(d2, e2, a2, b2, c2, w12, 9); - R41(c1, d1, e1, a1, b1, w7 , 5); R42(c2, d2, e2, a2, b2, w2 , 12); - R41(b1, c1, d1, e1, a1, w15, 6); R42(b2, c2, d2, e2, a2, w13, 9); - R41(a1, b1, c1, d1, e1, w14, 8); R42(a2, b2, c2, d2, e2, w9 , 12); - R41(e1, a1, b1, c1, d1, w5 , 6); R42(e2, a2, b2, c2, d2, w7 , 5); - R41(d1, e1, a1, b1, c1, w6 , 5); R42(d2, e2, a2, b2, c2, w10, 15); - R41(c1, d1, e1, a1, b1, w2 , 12); R42(c2, d2, e2, a2, b2, w14, 8); - - R51(b1, c1, d1, e1, a1, w4 , 9); R52(b2, c2, d2, e2, a2, w12, 8); - R51(a1, b1, c1, d1, e1, w0 , 15); R52(a2, b2, c2, d2, e2, w15, 5); - R51(e1, a1, b1, c1, d1, w5 , 5); R52(e2, a2, b2, c2, d2, w10, 12); - R51(d1, e1, a1, b1, c1, w9 , 11); R52(d2, e2, a2, b2, c2, w4 , 9); - R51(c1, d1, e1, a1, b1, w7 , 6); R52(c2, d2, e2, a2, b2, w1 , 12); - R51(b1, c1, d1, e1, a1, w12, 8); R52(b2, c2, d2, e2, a2, w5 , 5); - R51(a1, b1, c1, d1, e1, w2 , 13); R52(a2, b2, c2, d2, e2, w8 , 14); - R51(e1, a1, b1, c1, d1, w10, 12); R52(e2, a2, b2, c2, d2, w7 , 6); - R51(d1, e1, a1, b1, c1, w14, 5); R52(d2, e2, a2, b2, c2, w6 , 8); - R51(c1, d1, e1, a1, b1, w1 , 12); R52(c2, d2, e2, a2, b2, w2 , 13); - R51(b1, c1, d1, e1, a1, w3 , 13); R52(b2, c2, d2, e2, a2, w13, 6); - R51(a1, b1, c1, d1, e1, w8 , 14); R52(a2, b2, c2, d2, e2, w14, 5); - R51(e1, a1, b1, c1, d1, w11, 11); R52(e2, a2, b2, c2, d2, w0 , 15); - R51(d1, e1, a1, b1, c1, w6 , 8); R52(d2, e2, a2, b2, c2, w3 , 13); - R51(c1, d1, e1, a1, b1, w15, 5); R52(c2, d2, e2, a2, b2, w9 , 11); - R51(b1, c1, d1, e1, a1, w13, 6); R52(b2, c2, d2, e2, a2, w11, 11); + R11(a1, b1, c1, d1, e1, w0, 11); + R12(a2, b2, c2, d2, e2, w5, 8); + R11(e1, a1, b1, c1, d1, w1, 14); + R12(e2, a2, b2, c2, d2, w14, 9); + R11(d1, e1, a1, b1, c1, w2, 15); + R12(d2, e2, a2, b2, c2, w7, 9); + R11(c1, d1, e1, a1, b1, w3, 12); + R12(c2, d2, e2, a2, b2, w0, 11); + R11(b1, c1, d1, e1, a1, w4, 5); + R12(b2, c2, d2, e2, a2, w9, 13); + R11(a1, b1, c1, d1, e1, w5, 8); + R12(a2, b2, c2, d2, e2, w2, 15); + R11(e1, a1, b1, c1, d1, w6, 7); + R12(e2, a2, b2, c2, d2, w11, 15); + R11(d1, e1, a1, b1, c1, w7, 9); + R12(d2, e2, a2, b2, c2, w4, 5); + R11(c1, d1, e1, a1, b1, w8, 11); + R12(c2, d2, e2, a2, b2, w13, 7); + R11(b1, c1, d1, e1, a1, w9, 13); + R12(b2, c2, d2, e2, a2, w6, 7); + R11(a1, b1, c1, d1, e1, w10, 14); + R12(a2, b2, c2, d2, e2, w15, 8); + R11(e1, a1, b1, c1, d1, w11, 15); + R12(e2, a2, b2, c2, d2, w8, 11); + R11(d1, e1, a1, b1, c1, w12, 6); + R12(d2, e2, a2, b2, c2, w1, 14); + R11(c1, d1, e1, a1, b1, w13, 7); + R12(c2, d2, e2, a2, b2, w10, 14); + R11(b1, c1, d1, e1, a1, w14, 9); + R12(b2, c2, d2, e2, a2, w3, 12); + R11(a1, b1, c1, d1, e1, w15, 8); + R12(a2, b2, c2, d2, e2, w12, 6); + + R21(e1, a1, b1, c1, d1, w7, 7); + R22(e2, a2, b2, c2, d2, w6, 9); + R21(d1, e1, a1, b1, c1, w4, 6); + R22(d2, e2, a2, b2, c2, w11, 13); + R21(c1, d1, e1, a1, b1, w13, 8); + R22(c2, d2, e2, a2, b2, w3, 15); + R21(b1, c1, d1, e1, a1, w1, 13); + R22(b2, c2, d2, e2, a2, w7, 7); + R21(a1, b1, c1, d1, e1, w10, 11); + R22(a2, b2, c2, d2, e2, w0, 12); + R21(e1, a1, b1, c1, d1, w6, 9); + R22(e2, a2, b2, c2, d2, w13, 8); + R21(d1, e1, a1, b1, c1, w15, 7); + R22(d2, e2, a2, b2, c2, w5, 9); + R21(c1, d1, e1, a1, b1, w3, 15); + R22(c2, d2, e2, a2, b2, w10, 11); + R21(b1, c1, d1, e1, a1, w12, 7); + R22(b2, c2, d2, e2, a2, w14, 7); + R21(a1, b1, c1, d1, e1, w0, 12); + R22(a2, b2, c2, d2, e2, w15, 7); + R21(e1, a1, b1, c1, d1, w9, 15); + R22(e2, a2, b2, c2, d2, w8, 12); + R21(d1, e1, a1, b1, c1, w5, 9); + R22(d2, e2, a2, b2, c2, w12, 7); + R21(c1, d1, e1, a1, b1, w2, 11); + R22(c2, d2, e2, a2, b2, w4, 6); + R21(b1, c1, d1, e1, a1, w14, 7); + R22(b2, c2, d2, e2, a2, w9, 15); + R21(a1, b1, c1, d1, e1, w11, 13); + R22(a2, b2, c2, d2, e2, w1, 13); + R21(e1, a1, b1, c1, d1, w8, 12); + R22(e2, a2, b2, c2, d2, w2, 11); + + R31(d1, e1, a1, b1, c1, w3, 11); + R32(d2, e2, a2, b2, c2, w15, 9); + R31(c1, d1, e1, a1, b1, w10, 13); + R32(c2, d2, e2, a2, b2, w5, 7); + R31(b1, c1, d1, e1, a1, w14, 6); + R32(b2, c2, d2, e2, a2, w1, 15); + R31(a1, b1, c1, d1, e1, w4, 7); + R32(a2, b2, c2, d2, e2, w3, 11); + R31(e1, a1, b1, c1, d1, w9, 14); + R32(e2, a2, b2, c2, d2, w7, 8); + R31(d1, e1, a1, b1, c1, w15, 9); + R32(d2, e2, a2, b2, c2, w14, 6); + R31(c1, d1, e1, a1, b1, w8, 13); + R32(c2, d2, e2, a2, b2, w6, 6); + R31(b1, c1, d1, e1, a1, w1, 15); + R32(b2, c2, d2, e2, a2, w9, 14); + R31(a1, b1, c1, d1, e1, w2, 14); + R32(a2, b2, c2, d2, e2, w11, 12); + R31(e1, a1, b1, c1, d1, w7, 8); + R32(e2, a2, b2, c2, d2, w8, 13); + R31(d1, e1, a1, b1, c1, w0, 13); + R32(d2, e2, a2, b2, c2, w12, 5); + R31(c1, d1, e1, a1, b1, w6, 6); + R32(c2, d2, e2, a2, b2, w2, 14); + R31(b1, c1, d1, e1, a1, w13, 5); + R32(b2, c2, d2, e2, a2, w10, 13); + R31(a1, b1, c1, d1, e1, w11, 12); + R32(a2, b2, c2, d2, e2, w0, 13); + R31(e1, a1, b1, c1, d1, w5, 7); + R32(e2, a2, b2, c2, d2, w4, 7); + R31(d1, e1, a1, b1, c1, w12, 5); + R32(d2, e2, a2, b2, c2, w13, 5); + + R41(c1, d1, e1, a1, b1, w1, 11); + R42(c2, d2, e2, a2, b2, w8, 15); + R41(b1, c1, d1, e1, a1, w9, 12); + R42(b2, c2, d2, e2, a2, w6, 5); + R41(a1, b1, c1, d1, e1, w11, 14); + R42(a2, b2, c2, d2, e2, w4, 8); + R41(e1, a1, b1, c1, d1, w10, 15); + R42(e2, a2, b2, c2, d2, w1, 11); + R41(d1, e1, a1, b1, c1, w0, 14); + R42(d2, e2, a2, b2, c2, w3, 14); + R41(c1, d1, e1, a1, b1, w8, 15); + R42(c2, d2, e2, a2, b2, w11, 14); + R41(b1, c1, d1, e1, a1, w12, 9); + R42(b2, c2, d2, e2, a2, w15, 6); + R41(a1, b1, c1, d1, e1, w4, 8); + R42(a2, b2, c2, d2, e2, w0, 14); + R41(e1, a1, b1, c1, d1, w13, 9); + R42(e2, a2, b2, c2, d2, w5, 6); + R41(d1, e1, a1, b1, c1, w3, 14); + R42(d2, e2, a2, b2, c2, w12, 9); + R41(c1, d1, e1, a1, b1, w7, 5); + R42(c2, d2, e2, a2, b2, w2, 12); + R41(b1, c1, d1, e1, a1, w15, 6); + R42(b2, c2, d2, e2, a2, w13, 9); + R41(a1, b1, c1, d1, e1, w14, 8); + R42(a2, b2, c2, d2, e2, w9, 12); + R41(e1, a1, b1, c1, d1, w5, 6); + R42(e2, a2, b2, c2, d2, w7, 5); + R41(d1, e1, a1, b1, c1, w6, 5); + R42(d2, e2, a2, b2, c2, w10, 15); + R41(c1, d1, e1, a1, b1, w2, 12); + R42(c2, d2, e2, a2, b2, w14, 8); + + R51(b1, c1, d1, e1, a1, w4, 9); + R52(b2, c2, d2, e2, a2, w12, 8); + R51(a1, b1, c1, d1, e1, w0, 15); + R52(a2, b2, c2, d2, e2, w15, 5); + R51(e1, a1, b1, c1, d1, w5, 5); + R52(e2, a2, b2, c2, d2, w10, 12); + R51(d1, e1, a1, b1, c1, w9, 11); + R52(d2, e2, a2, b2, c2, w4, 9); + R51(c1, d1, e1, a1, b1, w7, 6); + R52(c2, d2, e2, a2, b2, w1, 12); + R51(b1, c1, d1, e1, a1, w12, 8); + R52(b2, c2, d2, e2, a2, w5, 5); + R51(a1, b1, c1, d1, e1, w2, 13); + R52(a2, b2, c2, d2, e2, w8, 14); + R51(e1, a1, b1, c1, d1, w10, 12); + R52(e2, a2, b2, c2, d2, w7, 6); + R51(d1, e1, a1, b1, c1, w14, 5); + R52(d2, e2, a2, b2, c2, w6, 8); + R51(c1, d1, e1, a1, b1, w1, 12); + R52(c2, d2, e2, a2, b2, w2, 13); + R51(b1, c1, d1, e1, a1, w3, 13); + R52(b2, c2, d2, e2, a2, w13, 6); + R51(a1, b1, c1, d1, e1, w8, 14); + R52(a2, b2, c2, d2, e2, w14, 5); + R51(e1, a1, b1, c1, d1, w11, 11); + R52(e2, a2, b2, c2, d2, w0, 15); + R51(d1, e1, a1, b1, c1, w6, 8); + R52(d2, e2, a2, b2, c2, w3, 13); + R51(c1, d1, e1, a1, b1, w15, 5); + R52(c2, d2, e2, a2, b2, w9, 11); + R51(b1, c1, d1, e1, a1, w13, 6); + R52(b2, c2, d2, e2, a2, w11, 11); uint32_t t = s[0]; s[0] = s[1] + c1 + d2; s[1] = s[2] + d1 + e2; s[2] = s[3] + e1 + a2; s[3] = s[4] + a1 + b2; - s[4] = t + b1 + c2; + s[4] = t + b1 + c2; } -} // namespace ripemd160 +} // namespace ripemd160 -} // namespace +} // namespace ////// RIPEMD160 -CRIPEMD160::CRIPEMD160() : bytes(0) { +CRIPEMD160::CRIPEMD160() : bytes(0) +{ ripemd160::Initialize(s); } -CRIPEMD160& CRIPEMD160::Write(const unsigned char *data, size_t len) { - const unsigned char *end = data + len; +CRIPEMD160& CRIPEMD160::Write(const unsigned char* data, size_t len) +{ + const unsigned char* end = data + len; size_t bufsize = bytes % 64; if (bufsize && bufsize + len >= 64) { // Fill the buffer, and process it. @@ -185,20 +270,22 @@ CRIPEMD160& CRIPEMD160::Write(const unsigned char *data, size_t len) { return *this; } -void CRIPEMD160::Finalize(unsigned char hash[OUTPUT_SIZE]) { +void CRIPEMD160::Finalize(unsigned char hash[OUTPUT_SIZE]) +{ static const unsigned char pad[64] = {0x80}; unsigned char sizedesc[8]; WriteLE64(sizedesc, bytes << 3); Write(pad, 1 + ((119 - (bytes % 64)) % 64)); Write(sizedesc, 8); WriteLE32(hash, s[0]); - WriteLE32(hash+4, s[1]); - WriteLE32(hash+8, s[2]); - WriteLE32(hash+12, s[3]); - WriteLE32(hash+16, s[4]); + WriteLE32(hash + 4, s[1]); + WriteLE32(hash + 8, s[2]); + WriteLE32(hash + 12, s[3]); + WriteLE32(hash + 16, s[4]); } -CRIPEMD160& CRIPEMD160::Reset() { +CRIPEMD160& CRIPEMD160::Reset() +{ bytes = 0; ripemd160::Initialize(s); return *this; diff --git a/src/crypto/ripemd160.h b/src/crypto/ripemd160.h index 44bd4879a5..687204fdae 100644 --- a/src/crypto/ripemd160.h +++ b/src/crypto/ripemd160.h @@ -1,15 +1,16 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_RIPEMD160_H -#define BITCOIN_RIPEMD160_H +#ifndef BITCOIN_CRYPTO_RIPEMD160_H +#define BITCOIN_CRYPTO_RIPEMD160_H #include <stdint.h> #include <stdlib.h> /** A hasher class for RIPEMD-160. */ -class CRIPEMD160 { +class CRIPEMD160 +{ private: uint32_t s[5]; unsigned char buf[64]; @@ -19,9 +20,9 @@ public: static const size_t OUTPUT_SIZE = 20; CRIPEMD160(); - CRIPEMD160& Write(const unsigned char *data, size_t len); + CRIPEMD160& Write(const unsigned char* data, size_t len); void Finalize(unsigned char hash[OUTPUT_SIZE]); CRIPEMD160& Reset(); }; -#endif +#endif // BITCOIN_CRYPTO_RIPEMD160_H diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp index 819abab579..0b895b33a2 100644 --- a/src/crypto/sha1.cpp +++ b/src/crypto/sha1.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "crypto/sha1.h" @@ -9,14 +9,14 @@ #include <string.h> // Internal implementation code. -namespace { - +namespace +{ /// Internal SHA-1 implementation. -namespace sha1 { - +namespace sha1 +{ /** One round of SHA-1. */ -void inline Round(uint32_t a, uint32_t &b, uint32_t c, uint32_t d, uint32_t &e, - uint32_t f, uint32_t k, uint32_t w) { +void inline Round(uint32_t a, uint32_t& b, uint32_t c, uint32_t d, uint32_t& e, uint32_t f, uint32_t k, uint32_t w) +{ e += ((a << 5) | (a >> 27)) + f + k + w; b = (b << 30) | (b >> 2); } @@ -28,7 +28,8 @@ uint32_t inline f3(uint32_t b, uint32_t c, uint32_t d) { return (b & c) | (d & ( uint32_t inline left(uint32_t x) { return (x << 1) | (x >> 31); } /** Initialize SHA-1 state. */ -void inline Initialize(uint32_t *s) { +void inline Initialize(uint32_t* s) +{ s[0] = 0x67452301ul; s[1] = 0xEFCDAB89ul; s[2] = 0x98BADCFEul; @@ -42,20 +43,21 @@ const uint32_t k3 = 0x8F1BBCDCul; const uint32_t k4 = 0xCA62C1D6ul; /** Perform a SHA-1 transformation, processing a 64-byte chunk. */ -void Transform(uint32_t *s, const unsigned char *chunk) { +void Transform(uint32_t* s, const unsigned char* chunk) +{ uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4]; uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; - Round(a, b, c, d, e, f1(b, c, d), k1, w0 = ReadBE32(chunk + 0)); - Round(e, a, b, c, d, f1(a, b, c), k1, w1 = ReadBE32(chunk + 4)); - Round(d, e, a, b, c, f1(e, a, b), k1, w2 = ReadBE32(chunk + 8)); - Round(c, d, e, a, b, f1(d, e, a), k1, w3 = ReadBE32(chunk + 12)); - Round(b, c, d, e, a, f1(c, d, e), k1, w4 = ReadBE32(chunk + 16)); - Round(a, b, c, d, e, f1(b, c, d), k1, w5 = ReadBE32(chunk + 20)); - Round(e, a, b, c, d, f1(a, b, c), k1, w6 = ReadBE32(chunk + 24)); - Round(d, e, a, b, c, f1(e, a, b), k1, w7 = ReadBE32(chunk + 28)); - Round(c, d, e, a, b, f1(d, e, a), k1, w8 = ReadBE32(chunk + 32)); - Round(b, c, d, e, a, f1(c, d, e), k1, w9 = ReadBE32(chunk + 36)); + Round(a, b, c, d, e, f1(b, c, d), k1, w0 = ReadBE32(chunk + 0)); + Round(e, a, b, c, d, f1(a, b, c), k1, w1 = ReadBE32(chunk + 4)); + Round(d, e, a, b, c, f1(e, a, b), k1, w2 = ReadBE32(chunk + 8)); + Round(c, d, e, a, b, f1(d, e, a), k1, w3 = ReadBE32(chunk + 12)); + Round(b, c, d, e, a, f1(c, d, e), k1, w4 = ReadBE32(chunk + 16)); + Round(a, b, c, d, e, f1(b, c, d), k1, w5 = ReadBE32(chunk + 20)); + Round(e, a, b, c, d, f1(a, b, c), k1, w6 = ReadBE32(chunk + 24)); + Round(d, e, a, b, c, f1(e, a, b), k1, w7 = ReadBE32(chunk + 28)); + Round(c, d, e, a, b, f1(d, e, a), k1, w8 = ReadBE32(chunk + 32)); + Round(b, c, d, e, a, f1(c, d, e), k1, w9 = ReadBE32(chunk + 36)); Round(a, b, c, d, e, f1(b, c, d), k1, w10 = ReadBE32(chunk + 40)); Round(e, a, b, c, d, f1(a, b, c), k1, w11 = ReadBE32(chunk + 44)); Round(d, e, a, b, c, f1(e, a, b), k1, w12 = ReadBE32(chunk + 48)); @@ -63,73 +65,73 @@ void Transform(uint32_t *s, const unsigned char *chunk) { Round(b, c, d, e, a, f1(c, d, e), k1, w14 = ReadBE32(chunk + 56)); Round(a, b, c, d, e, f1(b, c, d), k1, w15 = ReadBE32(chunk + 60)); - Round(e, a, b, c, d, f1(a, b, c), k1, w0 = left(w0 ^ w13 ^ w8 ^ w2 )); - Round(d, e, a, b, c, f1(e, a, b), k1, w1 = left(w1 ^ w14 ^ w9 ^ w3 )); - Round(c, d, e, a, b, f1(d, e, a), k1, w2 = left(w2 ^ w15 ^ w10 ^ w4 )); - Round(b, c, d, e, a, f1(c, d, e), k1, w3 = left(w3 ^ w0 ^ w11 ^ w5 )); - Round(a, b, c, d, e, f2(b, c, d), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6 )); - Round(e, a, b, c, d, f2(a, b, c), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7 )); - Round(d, e, a, b, c, f2(e, a, b), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8 )); - Round(c, d, e, a, b, f2(d, e, a), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9 )); - Round(b, c, d, e, a, f2(c, d, e), k2, w8 = left(w8 ^ w5 ^ w0 ^ w10)); - Round(a, b, c, d, e, f2(b, c, d), k2, w9 = left(w9 ^ w6 ^ w1 ^ w11)); - Round(e, a, b, c, d, f2(a, b, c), k2, w10 = left(w10 ^ w7 ^ w2 ^ w12)); - Round(d, e, a, b, c, f2(e, a, b), k2, w11 = left(w11 ^ w8 ^ w3 ^ w13)); - Round(c, d, e, a, b, f2(d, e, a), k2, w12 = left(w12 ^ w9 ^ w4 ^ w14)); - Round(b, c, d, e, a, f2(c, d, e), k2, w13 = left(w13 ^ w10 ^ w5 ^ w15)); - Round(a, b, c, d, e, f2(b, c, d), k2, w14 = left(w14 ^ w11 ^ w6 ^ w0 )); - Round(e, a, b, c, d, f2(a, b, c), k2, w15 = left(w15 ^ w12 ^ w7 ^ w1 )); - - Round(d, e, a, b, c, f2(e, a, b), k2, w0 = left(w0 ^ w13 ^ w8 ^ w2 )); - Round(c, d, e, a, b, f2(d, e, a), k2, w1 = left(w1 ^ w14 ^ w9 ^ w3 )); - Round(b, c, d, e, a, f2(c, d, e), k2, w2 = left(w2 ^ w15 ^ w10 ^ w4 )); - Round(a, b, c, d, e, f2(b, c, d), k2, w3 = left(w3 ^ w0 ^ w11 ^ w5 )); - Round(e, a, b, c, d, f2(a, b, c), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6 )); - Round(d, e, a, b, c, f2(e, a, b), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7 )); - Round(c, d, e, a, b, f2(d, e, a), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8 )); - Round(b, c, d, e, a, f2(c, d, e), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9 )); - Round(a, b, c, d, e, f3(b, c, d), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10)); - Round(e, a, b, c, d, f3(a, b, c), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11)); - Round(d, e, a, b, c, f3(e, a, b), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12)); - Round(c, d, e, a, b, f3(d, e, a), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13)); - Round(b, c, d, e, a, f3(c, d, e), k3, w12 = left(w12 ^ w9 ^ w4 ^ w14)); - Round(a, b, c, d, e, f3(b, c, d), k3, w13 = left(w13 ^ w10 ^ w5 ^ w15)); - Round(e, a, b, c, d, f3(a, b, c), k3, w14 = left(w14 ^ w11 ^ w6 ^ w0 )); - Round(d, e, a, b, c, f3(e, a, b), k3, w15 = left(w15 ^ w12 ^ w7 ^ w1 )); - - Round(c, d, e, a, b, f3(d, e, a), k3, w0 = left(w0 ^ w13 ^ w8 ^ w2 )); - Round(b, c, d, e, a, f3(c, d, e), k3, w1 = left(w1 ^ w14 ^ w9 ^ w3 )); - Round(a, b, c, d, e, f3(b, c, d), k3, w2 = left(w2 ^ w15 ^ w10 ^ w4 )); - Round(e, a, b, c, d, f3(a, b, c), k3, w3 = left(w3 ^ w0 ^ w11 ^ w5 )); - Round(d, e, a, b, c, f3(e, a, b), k3, w4 = left(w4 ^ w1 ^ w12 ^ w6 )); - Round(c, d, e, a, b, f3(d, e, a), k3, w5 = left(w5 ^ w2 ^ w13 ^ w7 )); - Round(b, c, d, e, a, f3(c, d, e), k3, w6 = left(w6 ^ w3 ^ w14 ^ w8 )); - Round(a, b, c, d, e, f3(b, c, d), k3, w7 = left(w7 ^ w4 ^ w15 ^ w9 )); - Round(e, a, b, c, d, f3(a, b, c), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10)); - Round(d, e, a, b, c, f3(e, a, b), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11)); - Round(c, d, e, a, b, f3(d, e, a), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12)); - Round(b, c, d, e, a, f3(c, d, e), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13)); - Round(a, b, c, d, e, f2(b, c, d), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14)); - Round(e, a, b, c, d, f2(a, b, c), k4, w13 = left(w13 ^ w10 ^ w5 ^ w15)); - Round(d, e, a, b, c, f2(e, a, b), k4, w14 = left(w14 ^ w11 ^ w6 ^ w0 )); - Round(c, d, e, a, b, f2(d, e, a), k4, w15 = left(w15 ^ w12 ^ w7 ^ w1 )); - - Round(b, c, d, e, a, f2(c, d, e), k4, w0 = left(w0 ^ w13 ^ w8 ^ w2 )); - Round(a, b, c, d, e, f2(b, c, d), k4, w1 = left(w1 ^ w14 ^ w9 ^ w3 )); - Round(e, a, b, c, d, f2(a, b, c), k4, w2 = left(w2 ^ w15 ^ w10 ^ w4 )); - Round(d, e, a, b, c, f2(e, a, b), k4, w3 = left(w3 ^ w0 ^ w11 ^ w5 )); - Round(c, d, e, a, b, f2(d, e, a), k4, w4 = left(w4 ^ w1 ^ w12 ^ w6 )); - Round(b, c, d, e, a, f2(c, d, e), k4, w5 = left(w5 ^ w2 ^ w13 ^ w7 )); - Round(a, b, c, d, e, f2(b, c, d), k4, w6 = left(w6 ^ w3 ^ w14 ^ w8 )); - Round(e, a, b, c, d, f2(a, b, c), k4, w7 = left(w7 ^ w4 ^ w15 ^ w9 )); - Round(d, e, a, b, c, f2(e, a, b), k4, w8 = left(w8 ^ w5 ^ w0 ^ w10)); - Round(c, d, e, a, b, f2(d, e, a), k4, w9 = left(w9 ^ w6 ^ w1 ^ w11)); - Round(b, c, d, e, a, f2(c, d, e), k4, w10 = left(w10 ^ w7 ^ w2 ^ w12)); - Round(a, b, c, d, e, f2(b, c, d), k4, w11 = left(w11 ^ w8 ^ w3 ^ w13)); - Round(e, a, b, c, d, f2(a, b, c), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14)); - Round(d, e, a, b, c, f2(e, a, b), k4, left(w13 ^ w10 ^ w5 ^ w15)); - Round(c, d, e, a, b, f2(d, e, a), k4, left(w14 ^ w11 ^ w6 ^ w0 )); - Round(b, c, d, e, a, f2(c, d, e), k4, left(w15 ^ w12 ^ w7 ^ w1 )); + Round(e, a, b, c, d, f1(a, b, c), k1, w0 = left(w0 ^ w13 ^ w8 ^ w2)); + Round(d, e, a, b, c, f1(e, a, b), k1, w1 = left(w1 ^ w14 ^ w9 ^ w3)); + Round(c, d, e, a, b, f1(d, e, a), k1, w2 = left(w2 ^ w15 ^ w10 ^ w4)); + Round(b, c, d, e, a, f1(c, d, e), k1, w3 = left(w3 ^ w0 ^ w11 ^ w5)); + Round(a, b, c, d, e, f2(b, c, d), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6)); + Round(e, a, b, c, d, f2(a, b, c), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7)); + Round(d, e, a, b, c, f2(e, a, b), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8)); + Round(c, d, e, a, b, f2(d, e, a), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9)); + Round(b, c, d, e, a, f2(c, d, e), k2, w8 = left(w8 ^ w5 ^ w0 ^ w10)); + Round(a, b, c, d, e, f2(b, c, d), k2, w9 = left(w9 ^ w6 ^ w1 ^ w11)); + Round(e, a, b, c, d, f2(a, b, c), k2, w10 = left(w10 ^ w7 ^ w2 ^ w12)); + Round(d, e, a, b, c, f2(e, a, b), k2, w11 = left(w11 ^ w8 ^ w3 ^ w13)); + Round(c, d, e, a, b, f2(d, e, a), k2, w12 = left(w12 ^ w9 ^ w4 ^ w14)); + Round(b, c, d, e, a, f2(c, d, e), k2, w13 = left(w13 ^ w10 ^ w5 ^ w15)); + Round(a, b, c, d, e, f2(b, c, d), k2, w14 = left(w14 ^ w11 ^ w6 ^ w0)); + Round(e, a, b, c, d, f2(a, b, c), k2, w15 = left(w15 ^ w12 ^ w7 ^ w1)); + + Round(d, e, a, b, c, f2(e, a, b), k2, w0 = left(w0 ^ w13 ^ w8 ^ w2)); + Round(c, d, e, a, b, f2(d, e, a), k2, w1 = left(w1 ^ w14 ^ w9 ^ w3)); + Round(b, c, d, e, a, f2(c, d, e), k2, w2 = left(w2 ^ w15 ^ w10 ^ w4)); + Round(a, b, c, d, e, f2(b, c, d), k2, w3 = left(w3 ^ w0 ^ w11 ^ w5)); + Round(e, a, b, c, d, f2(a, b, c), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6)); + Round(d, e, a, b, c, f2(e, a, b), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7)); + Round(c, d, e, a, b, f2(d, e, a), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8)); + Round(b, c, d, e, a, f2(c, d, e), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9)); + Round(a, b, c, d, e, f3(b, c, d), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10)); + Round(e, a, b, c, d, f3(a, b, c), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11)); + Round(d, e, a, b, c, f3(e, a, b), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12)); + Round(c, d, e, a, b, f3(d, e, a), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13)); + Round(b, c, d, e, a, f3(c, d, e), k3, w12 = left(w12 ^ w9 ^ w4 ^ w14)); + Round(a, b, c, d, e, f3(b, c, d), k3, w13 = left(w13 ^ w10 ^ w5 ^ w15)); + Round(e, a, b, c, d, f3(a, b, c), k3, w14 = left(w14 ^ w11 ^ w6 ^ w0)); + Round(d, e, a, b, c, f3(e, a, b), k3, w15 = left(w15 ^ w12 ^ w7 ^ w1)); + + Round(c, d, e, a, b, f3(d, e, a), k3, w0 = left(w0 ^ w13 ^ w8 ^ w2)); + Round(b, c, d, e, a, f3(c, d, e), k3, w1 = left(w1 ^ w14 ^ w9 ^ w3)); + Round(a, b, c, d, e, f3(b, c, d), k3, w2 = left(w2 ^ w15 ^ w10 ^ w4)); + Round(e, a, b, c, d, f3(a, b, c), k3, w3 = left(w3 ^ w0 ^ w11 ^ w5)); + Round(d, e, a, b, c, f3(e, a, b), k3, w4 = left(w4 ^ w1 ^ w12 ^ w6)); + Round(c, d, e, a, b, f3(d, e, a), k3, w5 = left(w5 ^ w2 ^ w13 ^ w7)); + Round(b, c, d, e, a, f3(c, d, e), k3, w6 = left(w6 ^ w3 ^ w14 ^ w8)); + Round(a, b, c, d, e, f3(b, c, d), k3, w7 = left(w7 ^ w4 ^ w15 ^ w9)); + Round(e, a, b, c, d, f3(a, b, c), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10)); + Round(d, e, a, b, c, f3(e, a, b), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11)); + Round(c, d, e, a, b, f3(d, e, a), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12)); + Round(b, c, d, e, a, f3(c, d, e), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13)); + Round(a, b, c, d, e, f2(b, c, d), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14)); + Round(e, a, b, c, d, f2(a, b, c), k4, w13 = left(w13 ^ w10 ^ w5 ^ w15)); + Round(d, e, a, b, c, f2(e, a, b), k4, w14 = left(w14 ^ w11 ^ w6 ^ w0)); + Round(c, d, e, a, b, f2(d, e, a), k4, w15 = left(w15 ^ w12 ^ w7 ^ w1)); + + Round(b, c, d, e, a, f2(c, d, e), k4, w0 = left(w0 ^ w13 ^ w8 ^ w2)); + Round(a, b, c, d, e, f2(b, c, d), k4, w1 = left(w1 ^ w14 ^ w9 ^ w3)); + Round(e, a, b, c, d, f2(a, b, c), k4, w2 = left(w2 ^ w15 ^ w10 ^ w4)); + Round(d, e, a, b, c, f2(e, a, b), k4, w3 = left(w3 ^ w0 ^ w11 ^ w5)); + Round(c, d, e, a, b, f2(d, e, a), k4, w4 = left(w4 ^ w1 ^ w12 ^ w6)); + Round(b, c, d, e, a, f2(c, d, e), k4, w5 = left(w5 ^ w2 ^ w13 ^ w7)); + Round(a, b, c, d, e, f2(b, c, d), k4, w6 = left(w6 ^ w3 ^ w14 ^ w8)); + Round(e, a, b, c, d, f2(a, b, c), k4, w7 = left(w7 ^ w4 ^ w15 ^ w9)); + Round(d, e, a, b, c, f2(e, a, b), k4, w8 = left(w8 ^ w5 ^ w0 ^ w10)); + Round(c, d, e, a, b, f2(d, e, a), k4, w9 = left(w9 ^ w6 ^ w1 ^ w11)); + Round(b, c, d, e, a, f2(c, d, e), k4, w10 = left(w10 ^ w7 ^ w2 ^ w12)); + Round(a, b, c, d, e, f2(b, c, d), k4, w11 = left(w11 ^ w8 ^ w3 ^ w13)); + Round(e, a, b, c, d, f2(a, b, c), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14)); + Round(d, e, a, b, c, f2(e, a, b), k4, left(w13 ^ w10 ^ w5 ^ w15)); + Round(c, d, e, a, b, f2(d, e, a), k4, left(w14 ^ w11 ^ w6 ^ w0)); + Round(b, c, d, e, a, f2(c, d, e), k4, left(w15 ^ w12 ^ w7 ^ w1)); s[0] += a; s[1] += b; @@ -138,18 +140,20 @@ void Transform(uint32_t *s, const unsigned char *chunk) { s[4] += e; } -} // namespace sha1 +} // namespace sha1 -} // namespace +} // namespace ////// SHA1 -CSHA1::CSHA1() : bytes(0) { +CSHA1::CSHA1() : bytes(0) +{ sha1::Initialize(s); } -CSHA1& CSHA1::Write(const unsigned char *data, size_t len) { - const unsigned char *end = data + len; +CSHA1& CSHA1::Write(const unsigned char* data, size_t len) +{ + const unsigned char* end = data + len; size_t bufsize = bytes % 64; if (bufsize && bufsize + len >= 64) { // Fill the buffer, and process it. @@ -173,20 +177,22 @@ CSHA1& CSHA1::Write(const unsigned char *data, size_t len) { return *this; } -void CSHA1::Finalize(unsigned char hash[OUTPUT_SIZE]) { +void CSHA1::Finalize(unsigned char hash[OUTPUT_SIZE]) +{ static const unsigned char pad[64] = {0x80}; unsigned char sizedesc[8]; WriteBE64(sizedesc, bytes << 3); Write(pad, 1 + ((119 - (bytes % 64)) % 64)); Write(sizedesc, 8); WriteBE32(hash, s[0]); - WriteBE32(hash+4, s[1]); - WriteBE32(hash+8, s[2]); - WriteBE32(hash+12, s[3]); - WriteBE32(hash+16, s[4]); + WriteBE32(hash + 4, s[1]); + WriteBE32(hash + 8, s[2]); + WriteBE32(hash + 12, s[3]); + WriteBE32(hash + 16, s[4]); } -CSHA1& CSHA1::Reset() { +CSHA1& CSHA1::Reset() +{ bytes = 0; sha1::Initialize(s); return *this; diff --git a/src/crypto/sha1.h b/src/crypto/sha1.h index b16f2c88ce..7b2a21bc6c 100644 --- a/src/crypto/sha1.h +++ b/src/crypto/sha1.h @@ -1,15 +1,16 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_SHA1_H -#define BITCOIN_SHA1_H +#ifndef BITCOIN_CRYPTO_SHA1_H +#define BITCOIN_CRYPTO_SHA1_H #include <stdint.h> #include <stdlib.h> /** A hasher class for SHA1. */ -class CSHA1 { +class CSHA1 +{ private: uint32_t s[5]; unsigned char buf[64]; @@ -19,9 +20,9 @@ public: static const size_t OUTPUT_SIZE = 20; CSHA1(); - CSHA1& Write(const unsigned char *data, size_t len); + CSHA1& Write(const unsigned char* data, size_t len); void Finalize(unsigned char hash[OUTPUT_SIZE]); CSHA1& Reset(); }; -#endif +#endif // BITCOIN_CRYPTO_SHA1_H diff --git a/src/crypto/sha2.cpp b/src/crypto/sha2.cpp deleted file mode 100644 index 72f191afcd..0000000000 --- a/src/crypto/sha2.cpp +++ /dev/null @@ -1,399 +0,0 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "crypto/sha2.h" - -#include "crypto/common.h" - -#include <string.h> - -// Internal implementation code. -namespace { - -/// Internal SHA-256 implementation. -namespace sha256 { - -uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); } -uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); } -uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); } -uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); } -uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); } -uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); } - -/** One round of SHA-256. */ -void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t &d, - uint32_t e, uint32_t f, uint32_t g, uint32_t &h, - uint32_t k, uint32_t w) { - uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w; - uint32_t t2 = Sigma0(a) + Maj(a, b, c); - d += t1; - h = t1 + t2; -} - -/** Initialize SHA-256 state. */ -void inline Initialize(uint32_t *s) { - s[0] = 0x6a09e667ul; - s[1] = 0xbb67ae85ul; - s[2] = 0x3c6ef372ul; - s[3] = 0xa54ff53aul; - s[4] = 0x510e527ful; - s[5] = 0x9b05688cul; - s[6] = 0x1f83d9abul; - s[7] = 0x5be0cd19ul; -} - -/** Perform one SHA-256 transformation, processing a 64-byte chunk. */ -void Transform(uint32_t *s, const unsigned char *chunk) { - uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; - uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; - - Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0)); - Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4)); - Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8)); - Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12)); - Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16)); - Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20)); - Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24)); - Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28)); - Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32)); - Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36)); - Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40)); - Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44)); - Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48)); - Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52)); - Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56)); - Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60)); - - Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0( w0)); - - Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0( w0)); - - Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0( w0)); - - s[0] += a; - s[1] += b; - s[2] += c; - s[3] += d; - s[4] += e; - s[5] += f; - s[6] += g; - s[7] += h; -} - -} // namespace sha256 - -/// Internal SHA-512 implementation. -namespace sha512 { - -uint64_t inline Ch(uint64_t x, uint64_t y, uint64_t z) { return z ^ (x & (y ^ z)); } -uint64_t inline Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) | (z & (x | y)); } -uint64_t inline Sigma0(uint64_t x) { return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25); } -uint64_t inline Sigma1(uint64_t x) { return (x >> 14 | x << 50) ^ (x >> 18 | x << 46) ^ (x >> 41 | x << 23); } -uint64_t inline sigma0(uint64_t x) { return (x >> 1 | x << 63) ^ (x >> 8 | x << 56) ^ (x >> 7); } -uint64_t inline sigma1(uint64_t x) { return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6); } - -/** One round of SHA-512. */ -void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t &d, - uint64_t e, uint64_t f, uint64_t g, uint64_t &h, - uint64_t k, uint64_t w) { - uint64_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w; - uint64_t t2 = Sigma0(a) + Maj(a, b, c); - d += t1; - h = t1 + t2; -} - -/** Initialize SHA-256 state. */ -void inline Initialize(uint64_t *s) { - s[0] = 0x6a09e667f3bcc908ull; - s[1] = 0xbb67ae8584caa73bull; - s[2] = 0x3c6ef372fe94f82bull; - s[3] = 0xa54ff53a5f1d36f1ull; - s[4] = 0x510e527fade682d1ull; - s[5] = 0x9b05688c2b3e6c1full; - s[6] = 0x1f83d9abfb41bd6bull; - s[7] = 0x5be0cd19137e2179ull; -} - -/** Perform one SHA-512 transformation, processing a 128-byte chunk. */ -void Transform(uint64_t *s, const unsigned char *chunk) { - uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; - uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; - - Round(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22ull, w0 = ReadBE64(chunk + 0)); - Round(h, a, b, c, d, e, f, g, 0x7137449123ef65cdull, w1 = ReadBE64(chunk + 8)); - Round(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2full, w2 = ReadBE64(chunk + 16)); - Round(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbcull, w3 = ReadBE64(chunk + 24)); - Round(e, f, g, h, a, b, c, d, 0x3956c25bf348b538ull, w4 = ReadBE64(chunk + 32)); - Round(d, e, f, g, h, a, b, c, 0x59f111f1b605d019ull, w5 = ReadBE64(chunk + 40)); - Round(c, d, e, f, g, h, a, b, 0x923f82a4af194f9bull, w6 = ReadBE64(chunk + 48)); - Round(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118ull, w7 = ReadBE64(chunk + 56)); - Round(a, b, c, d, e, f, g, h, 0xd807aa98a3030242ull, w8 = ReadBE64(chunk + 64)); - Round(h, a, b, c, d, e, f, g, 0x12835b0145706fbeull, w9 = ReadBE64(chunk + 72)); - Round(g, h, a, b, c, d, e, f, 0x243185be4ee4b28cull, w10 = ReadBE64(chunk + 80)); - Round(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2ull, w11 = ReadBE64(chunk + 88)); - Round(e, f, g, h, a, b, c, d, 0x72be5d74f27b896full, w12 = ReadBE64(chunk + 96)); - Round(d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1ull, w13 = ReadBE64(chunk + 104)); - Round(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235ull, w14 = ReadBE64(chunk + 112)); - Round(b, c, d, e, f, g, h, a, 0xc19bf174cf692694ull, w15 = ReadBE64(chunk + 120)); - - Round(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65ull, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275ull, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483ull, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x76f988da831153b5ull, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0x983e5152ee66dfabull, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0xa831c66d2db43210ull, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0xb00327c898fb213full, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4ull, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0( w0)); - - Round(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aedull, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0x53380d139d95b3dfull, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x650a73548baf63deull, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8ull, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6ull, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x92722c851482353bull, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364ull, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0xa81a664bbc423001ull, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791ull, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0xc76c51a30654be30ull, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0( w0)); - - Round(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99ull, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8ull, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63ull, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acbull, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373ull, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fcull, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0x78a5636f43172f60ull, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72ull, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0x8cc702081a6439ecull, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0( w0)); - - Round(a, b, c, d, e, f, g, h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1eull, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178ull, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x06f067aa72176fbaull, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6ull, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x113f9804bef90daeull, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x1b710b35131c471bull, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0x28db77f523047d84ull, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0x32caab7b40c72493ull, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebcull, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0x431d67c49c100d4cull, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faecull, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x6c44198c4a475817ull, w15 += sigma1(w13) + w8 + sigma0( w0)); - - s[0] += a; - s[1] += b; - s[2] += c; - s[3] += d; - s[4] += e; - s[5] += f; - s[6] += g; - s[7] += h; -} - -} // namespace sha512 - -} // namespace - - -////// SHA-256 - -CSHA256::CSHA256() : bytes(0) { - sha256::Initialize(s); -} - -CSHA256& CSHA256::Write(const unsigned char *data, size_t len) { - const unsigned char *end = data + len; - size_t bufsize = bytes % 64; - if (bufsize && bufsize + len >= 64) { - // Fill the buffer, and process it. - memcpy(buf + bufsize, data, 64 - bufsize); - bytes += 64 - bufsize; - data += 64 - bufsize; - sha256::Transform(s, buf); - bufsize = 0; - } - while (end >= data + 64) { - // Process full chunks directly from the source. - sha256::Transform(s, data); - bytes += 64; - data += 64; - } - if (end > data) { - // Fill the buffer with what remains. - memcpy(buf + bufsize, data, end - data); - bytes += end - data; - } - return *this; -} - -void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE]) { - static const unsigned char pad[64] = {0x80}; - unsigned char sizedesc[8]; - WriteBE64(sizedesc, bytes << 3); - Write(pad, 1 + ((119 - (bytes % 64)) % 64)); - Write(sizedesc, 8); - WriteBE32(hash, s[0]); - WriteBE32(hash+4, s[1]); - WriteBE32(hash+8, s[2]); - WriteBE32(hash+12, s[3]); - WriteBE32(hash+16, s[4]); - WriteBE32(hash+20, s[5]); - WriteBE32(hash+24, s[6]); - WriteBE32(hash+28, s[7]); -} - -CSHA256& CSHA256::Reset() { - bytes = 0; - sha256::Initialize(s); - return *this; -} - -////// SHA-512 - -CSHA512::CSHA512() : bytes(0) { - sha512::Initialize(s); -} - -CSHA512& CSHA512::Write(const unsigned char *data, size_t len) { - const unsigned char *end = data + len; - size_t bufsize = bytes % 128; - if (bufsize && bufsize + len >= 128) { - // Fill the buffer, and process it. - memcpy(buf + bufsize, data, 128 - bufsize); - bytes += 128 - bufsize; - data += 128 - bufsize; - sha512::Transform(s, buf); - bufsize = 0; - } - while (end >= data + 128) { - // Process full chunks directly from the source. - sha512::Transform(s, data); - data += 128; - bytes += 128; - } - if (end > data) { - // Fill the buffer with what remains. - memcpy(buf + bufsize, data, end - data); - bytes += end - data; - } - return *this; -} - -void CSHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) { - static const unsigned char pad[128] = {0x80}; - unsigned char sizedesc[16] = {0x00}; - WriteBE64(sizedesc+8, bytes << 3); - Write(pad, 1 + ((239 - (bytes % 128)) % 128)); - Write(sizedesc, 16); - WriteBE64(hash, s[0]); - WriteBE64(hash+8, s[1]); - WriteBE64(hash+16, s[2]); - WriteBE64(hash+24, s[3]); - WriteBE64(hash+32, s[4]); - WriteBE64(hash+40, s[5]); - WriteBE64(hash+48, s[6]); - WriteBE64(hash+56, s[7]); -} - -CSHA512& CSHA512::Reset() { - bytes = 0; - sha512::Initialize(s); - return *this; -} - -////// HMAC-SHA-512 - -CHMAC_SHA512::CHMAC_SHA512(const unsigned char *key, size_t keylen) { - unsigned char rkey[128]; - if (keylen <= 128) { - memcpy(rkey, key, keylen); - memset(rkey + keylen, 0, 128 - keylen); - } else { - CSHA512().Write(key, keylen).Finalize(rkey); - memset(rkey + 64, 0, 64); - } - - for (int n=0; n<128; n++) - rkey[n] ^= 0x5c; - outer.Write(rkey, 128); - - for (int n=0; n<128; n++) - rkey[n] ^= 0x5c ^ 0x36; - inner.Write(rkey, 128); -} - -void CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) { - unsigned char temp[64]; - inner.Finalize(temp); - outer.Write(temp, 64).Finalize(hash); -} diff --git a/src/crypto/sha2.h b/src/crypto/sha2.h deleted file mode 100644 index 088d5e194c..0000000000 --- a/src/crypto/sha2.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_SHA2_H -#define BITCOIN_SHA2_H - -#include <stdint.h> -#include <stdlib.h> - -/** A hasher class for SHA-256. */ -class CSHA256 { -private: - uint32_t s[8]; - unsigned char buf[64]; - size_t bytes; - -public: - static const size_t OUTPUT_SIZE = 32; - - CSHA256(); - CSHA256& Write(const unsigned char *data, size_t len); - void Finalize(unsigned char hash[OUTPUT_SIZE]); - CSHA256& Reset(); -}; - -/** A hasher class for SHA-512. */ -class CSHA512 { -private: - uint64_t s[8]; - unsigned char buf[128]; - size_t bytes; - -public: - static const size_t OUTPUT_SIZE = 64; - - CSHA512(); - CSHA512& Write(const unsigned char *data, size_t len); - void Finalize(unsigned char hash[OUTPUT_SIZE]); - CSHA512& Reset(); -}; - -/** A hasher class for HMAC-SHA-512. */ -class CHMAC_SHA512 { -private: - CSHA512 outer; - CSHA512 inner; - -public: - static const size_t OUTPUT_SIZE = 64; - - CHMAC_SHA512(const unsigned char *key, size_t keylen); - CHMAC_SHA512& Write(const unsigned char *data, size_t len) { - inner.Write(data, len); - return *this; - } - void Finalize(unsigned char hash[OUTPUT_SIZE]); -}; - -#endif diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp new file mode 100644 index 0000000000..5b9f00a0a2 --- /dev/null +++ b/src/crypto/sha256.cpp @@ -0,0 +1,189 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "crypto/sha256.h" + +#include "crypto/common.h" + +#include <string.h> + +// Internal implementation code. +namespace +{ +/// Internal SHA-256 implementation. +namespace sha256 +{ +uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); } +uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); } +uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); } +uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); } +uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); } +uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); } + +/** One round of SHA-256. */ +void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, uint32_t f, uint32_t g, uint32_t& h, uint32_t k, uint32_t w) +{ + uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w; + uint32_t t2 = Sigma0(a) + Maj(a, b, c); + d += t1; + h = t1 + t2; +} + +/** Initialize SHA-256 state. */ +void inline Initialize(uint32_t* s) +{ + s[0] = 0x6a09e667ul; + s[1] = 0xbb67ae85ul; + s[2] = 0x3c6ef372ul; + s[3] = 0xa54ff53aul; + s[4] = 0x510e527ful; + s[5] = 0x9b05688cul; + s[6] = 0x1f83d9abul; + s[7] = 0x5be0cd19ul; +} + +/** Perform one SHA-256 transformation, processing a 64-byte chunk. */ +void Transform(uint32_t* s, const unsigned char* chunk) +{ + uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; + uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; + + Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0)); + Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4)); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8)); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12)); + Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16)); + Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20)); + Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24)); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28)); + Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32)); + Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36)); + Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40)); + Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44)); + Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48)); + Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52)); + Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56)); + Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60)); + + Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0)); + + s[0] += a; + s[1] += b; + s[2] += c; + s[3] += d; + s[4] += e; + s[5] += f; + s[6] += g; + s[7] += h; +} + +} // namespace sha256 +} // namespace + + +////// SHA-256 + +CSHA256::CSHA256() : bytes(0) +{ + sha256::Initialize(s); +} + +CSHA256& CSHA256::Write(const unsigned char* data, size_t len) +{ + const unsigned char* end = data + len; + size_t bufsize = bytes % 64; + if (bufsize && bufsize + len >= 64) { + // Fill the buffer, and process it. + memcpy(buf + bufsize, data, 64 - bufsize); + bytes += 64 - bufsize; + data += 64 - bufsize; + sha256::Transform(s, buf); + bufsize = 0; + } + while (end >= data + 64) { + // Process full chunks directly from the source. + sha256::Transform(s, data); + bytes += 64; + data += 64; + } + if (end > data) { + // Fill the buffer with what remains. + memcpy(buf + bufsize, data, end - data); + bytes += end - data; + } + return *this; +} + +void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE]) +{ + static const unsigned char pad[64] = {0x80}; + unsigned char sizedesc[8]; + WriteBE64(sizedesc, bytes << 3); + Write(pad, 1 + ((119 - (bytes % 64)) % 64)); + Write(sizedesc, 8); + WriteBE32(hash, s[0]); + WriteBE32(hash + 4, s[1]); + WriteBE32(hash + 8, s[2]); + WriteBE32(hash + 12, s[3]); + WriteBE32(hash + 16, s[4]); + WriteBE32(hash + 20, s[5]); + WriteBE32(hash + 24, s[6]); + WriteBE32(hash + 28, s[7]); +} + +CSHA256& CSHA256::Reset() +{ + bytes = 0; + sha256::Initialize(s); + return *this; +} diff --git a/src/crypto/sha256.h b/src/crypto/sha256.h new file mode 100644 index 0000000000..85cf33739a --- /dev/null +++ b/src/crypto/sha256.h @@ -0,0 +1,28 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CRYPTO_SHA256_H +#define BITCOIN_CRYPTO_SHA256_H + +#include <stdint.h> +#include <stdlib.h> + +/** A hasher class for SHA-256. */ +class CSHA256 +{ +private: + uint32_t s[8]; + unsigned char buf[64]; + size_t bytes; + +public: + static const size_t OUTPUT_SIZE = 32; + + CSHA256(); + CSHA256& Write(const unsigned char* data, size_t len); + void Finalize(unsigned char hash[OUTPUT_SIZE]); + CSHA256& Reset(); +}; + +#endif // BITCOIN_CRYPTO_SHA256_H diff --git a/src/crypto/sha512.cpp b/src/crypto/sha512.cpp new file mode 100644 index 0000000000..564127cc31 --- /dev/null +++ b/src/crypto/sha512.cpp @@ -0,0 +1,207 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "crypto/sha512.h" + +#include "crypto/common.h" + +#include <string.h> + +// Internal implementation code. +namespace +{ +/// Internal SHA-512 implementation. +namespace sha512 +{ +uint64_t inline Ch(uint64_t x, uint64_t y, uint64_t z) { return z ^ (x & (y ^ z)); } +uint64_t inline Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) | (z & (x | y)); } +uint64_t inline Sigma0(uint64_t x) { return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25); } +uint64_t inline Sigma1(uint64_t x) { return (x >> 14 | x << 50) ^ (x >> 18 | x << 46) ^ (x >> 41 | x << 23); } +uint64_t inline sigma0(uint64_t x) { return (x >> 1 | x << 63) ^ (x >> 8 | x << 56) ^ (x >> 7); } +uint64_t inline sigma1(uint64_t x) { return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6); } + +/** One round of SHA-512. */ +void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t& d, uint64_t e, uint64_t f, uint64_t g, uint64_t& h, uint64_t k, uint64_t w) +{ + uint64_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w; + uint64_t t2 = Sigma0(a) + Maj(a, b, c); + d += t1; + h = t1 + t2; +} + +/** Initialize SHA-256 state. */ +void inline Initialize(uint64_t* s) +{ + s[0] = 0x6a09e667f3bcc908ull; + s[1] = 0xbb67ae8584caa73bull; + s[2] = 0x3c6ef372fe94f82bull; + s[3] = 0xa54ff53a5f1d36f1ull; + s[4] = 0x510e527fade682d1ull; + s[5] = 0x9b05688c2b3e6c1full; + s[6] = 0x1f83d9abfb41bd6bull; + s[7] = 0x5be0cd19137e2179ull; +} + +/** Perform one SHA-512 transformation, processing a 128-byte chunk. */ +void Transform(uint64_t* s, const unsigned char* chunk) +{ + uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; + uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; + + Round(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22ull, w0 = ReadBE64(chunk + 0)); + Round(h, a, b, c, d, e, f, g, 0x7137449123ef65cdull, w1 = ReadBE64(chunk + 8)); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2full, w2 = ReadBE64(chunk + 16)); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbcull, w3 = ReadBE64(chunk + 24)); + Round(e, f, g, h, a, b, c, d, 0x3956c25bf348b538ull, w4 = ReadBE64(chunk + 32)); + Round(d, e, f, g, h, a, b, c, 0x59f111f1b605d019ull, w5 = ReadBE64(chunk + 40)); + Round(c, d, e, f, g, h, a, b, 0x923f82a4af194f9bull, w6 = ReadBE64(chunk + 48)); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118ull, w7 = ReadBE64(chunk + 56)); + Round(a, b, c, d, e, f, g, h, 0xd807aa98a3030242ull, w8 = ReadBE64(chunk + 64)); + Round(h, a, b, c, d, e, f, g, 0x12835b0145706fbeull, w9 = ReadBE64(chunk + 72)); + Round(g, h, a, b, c, d, e, f, 0x243185be4ee4b28cull, w10 = ReadBE64(chunk + 80)); + Round(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2ull, w11 = ReadBE64(chunk + 88)); + Round(e, f, g, h, a, b, c, d, 0x72be5d74f27b896full, w12 = ReadBE64(chunk + 96)); + Round(d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1ull, w13 = ReadBE64(chunk + 104)); + Round(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235ull, w14 = ReadBE64(chunk + 112)); + Round(b, c, d, e, f, g, h, a, 0xc19bf174cf692694ull, w15 = ReadBE64(chunk + 120)); + + Round(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65ull, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275ull, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483ull, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x76f988da831153b5ull, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x983e5152ee66dfabull, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa831c66d2db43210ull, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0xb00327c898fb213full, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4ull, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aedull, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x53380d139d95b3dfull, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x650a73548baf63deull, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8ull, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6ull, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x92722c851482353bull, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364ull, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa81a664bbc423001ull, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791ull, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0xc76c51a30654be30ull, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99ull, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8ull, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63ull, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acbull, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373ull, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fcull, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0x78a5636f43172f60ull, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72ull, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0x8cc702081a6439ecull, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1eull, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178ull, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x06f067aa72176fbaull, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6ull, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x113f9804bef90daeull, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x1b710b35131c471bull, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x28db77f523047d84ull, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0x32caab7b40c72493ull, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebcull, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0x431d67c49c100d4cull, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faecull, w14 + sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x6c44198c4a475817ull, w15 + sigma1(w13) + w8 + sigma0(w0)); + + s[0] += a; + s[1] += b; + s[2] += c; + s[3] += d; + s[4] += e; + s[5] += f; + s[6] += g; + s[7] += h; +} + +} // namespace sha512 + +} // namespace + + +////// SHA-512 + +CSHA512::CSHA512() : bytes(0) +{ + sha512::Initialize(s); +} + +CSHA512& CSHA512::Write(const unsigned char* data, size_t len) +{ + const unsigned char* end = data + len; + size_t bufsize = bytes % 128; + if (bufsize && bufsize + len >= 128) { + // Fill the buffer, and process it. + memcpy(buf + bufsize, data, 128 - bufsize); + bytes += 128 - bufsize; + data += 128 - bufsize; + sha512::Transform(s, buf); + bufsize = 0; + } + while (end >= data + 128) { + // Process full chunks directly from the source. + sha512::Transform(s, data); + data += 128; + bytes += 128; + } + if (end > data) { + // Fill the buffer with what remains. + memcpy(buf + bufsize, data, end - data); + bytes += end - data; + } + return *this; +} + +void CSHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) +{ + static const unsigned char pad[128] = {0x80}; + unsigned char sizedesc[16] = {0x00}; + WriteBE64(sizedesc + 8, bytes << 3); + Write(pad, 1 + ((239 - (bytes % 128)) % 128)); + Write(sizedesc, 16); + WriteBE64(hash, s[0]); + WriteBE64(hash + 8, s[1]); + WriteBE64(hash + 16, s[2]); + WriteBE64(hash + 24, s[3]); + WriteBE64(hash + 32, s[4]); + WriteBE64(hash + 40, s[5]); + WriteBE64(hash + 48, s[6]); + WriteBE64(hash + 56, s[7]); +} + +CSHA512& CSHA512::Reset() +{ + bytes = 0; + sha512::Initialize(s); + return *this; +} diff --git a/src/crypto/sha512.h b/src/crypto/sha512.h new file mode 100644 index 0000000000..f1f17caf90 --- /dev/null +++ b/src/crypto/sha512.h @@ -0,0 +1,28 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CRYPTO_SHA512_H +#define BITCOIN_CRYPTO_SHA512_H + +#include <stdint.h> +#include <stdlib.h> + +/** A hasher class for SHA-512. */ +class CSHA512 +{ +private: + uint64_t s[8]; + unsigned char buf[128]; + size_t bytes; + +public: + static const size_t OUTPUT_SIZE = 64; + + CSHA512(); + CSHA512& Write(const unsigned char* data, size_t len); + void Finalize(unsigned char hash[OUTPUT_SIZE]); + CSHA512& Reset(); +}; + +#endif // BITCOIN_CRYPTO_SHA512_H diff --git a/src/db.cpp b/src/db.cpp index 12650e459f..94629968d5 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "db.h" @@ -1,12 +1,14 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_DB_H #define BITCOIN_DB_H +#include "clientversion.h" #include "serialize.h" +#include "streams.h" #include "sync.h" #include "version.h" @@ -48,7 +50,7 @@ public: void MakeMock(); bool IsMock() { return fMockDb; } - /* + /** * Verify that database file strFile is OK. If it is not, * call the callback to try to recover. * This must be called BEFORE strFile is opened. @@ -58,7 +60,7 @@ public: RECOVER_OK, RECOVER_FAIL }; VerifyResult Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile)); - /* + /** * Salvage data from a file that Verify says is bad. * fAggressive sets the DB_AGGRESSIVE flag (see berkeley DB->verify() method documentation). * Appends binary key/value pairs to vResult, returns true if successful. diff --git a/src/eccryptoverify.cpp b/src/eccryptoverify.cpp new file mode 100644 index 0000000000..e894e1122c --- /dev/null +++ b/src/eccryptoverify.cpp @@ -0,0 +1,68 @@ +// 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. + +#include "eccryptoverify.h" + +namespace { + +int CompareBigEndian(const unsigned char *c1, size_t c1len, const unsigned char *c2, size_t c2len) { + while (c1len > c2len) { + if (*c1) + return 1; + c1++; + c1len--; + } + while (c2len > c1len) { + if (*c2) + return -1; + c2++; + c2len--; + } + while (c1len > 0) { + if (*c1 > *c2) + return 1; + if (*c2 > *c1) + return -1; + c1++; + c2++; + c1len--; + } + return 0; +} + +/** Order of secp256k1's generator minus 1. */ +const unsigned char vchMaxModOrder[32] = { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, + 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, + 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40 +}; + +/** Half of the order of secp256k1's generator minus 1. */ +const unsigned char vchMaxModHalfOrder[32] = { + 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x5D,0x57,0x6E,0x73,0x57,0xA4,0x50,0x1D, + 0xDF,0xE9,0x2F,0x46,0x68,0x1B,0x20,0xA0 +}; + +const unsigned char vchZero[1] = {0}; +} // anon namespace + +namespace eccrypto { + +bool Check(const unsigned char *vch) { + return vch && + CompareBigEndian(vch, 32, vchZero, 0) > 0 && + CompareBigEndian(vch, 32, vchMaxModOrder, 32) <= 0; +} + +bool CheckSignatureElement(const unsigned char *vch, int len, bool half) { + return vch && + CompareBigEndian(vch, len, vchZero, 0) > 0 && + CompareBigEndian(vch, len, half ? vchMaxModHalfOrder : vchMaxModOrder, 32) <= 0; +} + +} // namespace eccrypto diff --git a/src/eccryptoverify.h b/src/eccryptoverify.h new file mode 100644 index 0000000000..c67c1e44fc --- /dev/null +++ b/src/eccryptoverify.h @@ -0,0 +1,21 @@ +// 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_ECCRYPTOVERIFY_H +#define BITCOIN_ECCRYPTOVERIFY_H + +#include <vector> +#include <cstdlib> + +class uint256; + +namespace eccrypto { + +bool Check(const unsigned char *vch); +bool CheckSignatureElement(const unsigned char *vch, int len, bool half); + +} // eccrypto namespace + +#endif // BITCOIN_ECCRYPTOVERIFY_H diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp new file mode 100644 index 0000000000..c29390eb98 --- /dev/null +++ b/src/ecwrapper.cpp @@ -0,0 +1,171 @@ +// 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. + +#include "ecwrapper.h" + +#include "serialize.h" +#include "uint256.h" + +#include <openssl/bn.h> +#include <openssl/ecdsa.h> +#include <openssl/obj_mac.h> + +namespace { + +/** + * Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields + * recid selects which key is recovered + * if check is non-zero, additional checks are performed + */ +int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check) +{ + if (!eckey) return 0; + + int ret = 0; + BN_CTX *ctx = NULL; + + BIGNUM *x = NULL; + BIGNUM *e = NULL; + BIGNUM *order = NULL; + BIGNUM *sor = NULL; + BIGNUM *eor = NULL; + BIGNUM *field = NULL; + EC_POINT *R = NULL; + EC_POINT *O = NULL; + EC_POINT *Q = NULL; + BIGNUM *rr = NULL; + BIGNUM *zero = NULL; + int n = 0; + int i = recid / 2; + + const EC_GROUP *group = EC_KEY_get0_group(eckey); + if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; } + BN_CTX_start(ctx); + order = BN_CTX_get(ctx); + if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; } + x = BN_CTX_get(ctx); + if (!BN_copy(x, order)) { ret=-1; goto err; } + if (!BN_mul_word(x, i)) { ret=-1; goto err; } + if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; } + field = BN_CTX_get(ctx); + if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; } + if (BN_cmp(x, field) >= 0) { ret=0; goto err; } + if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } + if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; } + if (check) + { + if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } + if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; } + if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; } + } + if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } + n = EC_GROUP_get_degree(group); + e = BN_CTX_get(ctx); + if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; } + if (8*msglen > n) BN_rshift(e, e, 8-(n & 7)); + zero = BN_CTX_get(ctx); + if (!BN_zero(zero)) { ret=-1; goto err; } + if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; } + rr = BN_CTX_get(ctx); + if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; } + sor = BN_CTX_get(ctx); + if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; } + eor = BN_CTX_get(ctx); + if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; } + if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; } + if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; } + + ret = 1; + +err: + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (R != NULL) EC_POINT_free(R); + if (O != NULL) EC_POINT_free(O); + if (Q != NULL) EC_POINT_free(Q); + return ret; +} + +} // anon namespace + +CECKey::CECKey() { + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + assert(pkey != NULL); +} + +CECKey::~CECKey() { + EC_KEY_free(pkey); +} + +void CECKey::GetPubKey(std::vector<unsigned char> &pubkey, bool fCompressed) { + EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED); + int nSize = i2o_ECPublicKey(pkey, NULL); + assert(nSize); + assert(nSize <= 65); + pubkey.clear(); + pubkey.resize(nSize); + unsigned char *pbegin(begin_ptr(pubkey)); + int nSize2 = i2o_ECPublicKey(pkey, &pbegin); + assert(nSize == nSize2); +} + +bool CECKey::SetPubKey(const unsigned char* pubkey, size_t size) { + return o2i_ECPublicKey(&pkey, &pubkey, size) != NULL; +} + +bool CECKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) { + // -1 = error, 0 = bad sig, 1 = good + if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) + return false; + return true; +} + +bool CECKey::Recover(const uint256 &hash, const unsigned char *p64, int rec) +{ + if (rec<0 || rec>=3) + return false; + ECDSA_SIG *sig = ECDSA_SIG_new(); + BN_bin2bn(&p64[0], 32, sig->r); + BN_bin2bn(&p64[32], 32, sig->s); + bool ret = ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), rec, 0) == 1; + ECDSA_SIG_free(sig); + return ret; +} + +bool CECKey::TweakPublic(const unsigned char vchTweak[32]) { + bool ret = true; + BN_CTX *ctx = BN_CTX_new(); + BN_CTX_start(ctx); + BIGNUM *bnTweak = BN_CTX_get(ctx); + BIGNUM *bnOrder = BN_CTX_get(ctx); + BIGNUM *bnOne = BN_CTX_get(ctx); + const EC_GROUP *group = EC_KEY_get0_group(pkey); + EC_GROUP_get_order(group, bnOrder, ctx); // what a grossly inefficient way to get the (constant) group order... + BN_bin2bn(vchTweak, 32, bnTweak); + if (BN_cmp(bnTweak, bnOrder) >= 0) + ret = false; // extremely unlikely + EC_POINT *point = EC_POINT_dup(EC_KEY_get0_public_key(pkey), group); + BN_one(bnOne); + EC_POINT_mul(group, point, bnTweak, point, bnOne, ctx); + if (EC_POINT_is_at_infinity(group, point)) + ret = false; // ridiculously unlikely + EC_KEY_set_public_key(pkey, point); + EC_POINT_free(point); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ret; +} + +bool CECKey::SanityCheck() +{ + EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if(pkey == NULL) + return false; + EC_KEY_free(pkey); + + // TODO Is there more EC functionality that could be missing? + return true; +} diff --git a/src/ecwrapper.h b/src/ecwrapper.h new file mode 100644 index 0000000000..efb6cd18a7 --- /dev/null +++ b/src/ecwrapper.h @@ -0,0 +1,40 @@ +// 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_ECWRAPPER_H +#define BITCOIN_ECWRAPPER_H + +#include <cstddef> +#include <vector> + +#include <openssl/ec.h> + +class uint256; + +/** RAII Wrapper around OpenSSL's EC_KEY */ +class CECKey { +private: + EC_KEY *pkey; + +public: + CECKey(); + ~CECKey(); + + void GetPubKey(std::vector<unsigned char>& pubkey, bool fCompressed); + bool SetPubKey(const unsigned char* pubkey, size_t size); + bool Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig); + + /** + * reconstruct public key from a compact signature + * This is only slightly more CPU intensive than just verifying it. + * If this function succeeds, the recovered public key is guaranteed to be valid + * (the signature is a valid signature of the given data for that key) + */ + bool Recover(const uint256 &hash, const unsigned char *p64, int rec); + + bool TweakPublic(const unsigned char vchTweak[32]); + static bool SanityCheck(); +}; + +#endif // BITCOIN_ECWRAPPER_H diff --git a/src/hash.cpp b/src/hash.cpp index 4ce4da4c30..a7eb5a2a0b 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -1,4 +1,9 @@ +// Copyright (c) 2013-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "hash.h" +#include "crypto/hmac_sha512.h" inline uint32_t ROTL32(uint32_t x, int8_t r) { @@ -9,45 +14,48 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char { // The following is MurmurHash3 (x86_32), see http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp uint32_t h1 = nHashSeed; - const uint32_t c1 = 0xcc9e2d51; - const uint32_t c2 = 0x1b873593; + if (vDataToHash.size() > 0) + { + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; - const int nblocks = vDataToHash.size() / 4; + const int nblocks = vDataToHash.size() / 4; - //---------- - // body - const uint32_t* blocks = (const uint32_t*)(&vDataToHash[0] + nblocks * 4); + //---------- + // body + const uint32_t* blocks = (const uint32_t*)(&vDataToHash[0] + nblocks * 4); - for (int i = -nblocks; i; i++) { - uint32_t k1 = blocks[i]; + for (int i = -nblocks; i; i++) { + uint32_t k1 = blocks[i]; - k1 *= c1; - k1 = ROTL32(k1, 15); - k1 *= c2; + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; - h1 ^= k1; - h1 = ROTL32(h1, 13); - h1 = h1 * 5 + 0xe6546b64; - } + h1 ^= k1; + h1 = ROTL32(h1, 13); + h1 = h1 * 5 + 0xe6546b64; + } - //---------- - // tail - const uint8_t* tail = (const uint8_t*)(&vDataToHash[0] + nblocks * 4); - - uint32_t k1 = 0; - - switch (vDataToHash.size() & 3) { - case 3: - k1 ^= tail[2] << 16; - case 2: - k1 ^= tail[1] << 8; - case 1: - k1 ^= tail[0]; - k1 *= c1; - k1 = ROTL32(k1, 15); - k1 *= c2; - h1 ^= k1; - }; + //---------- + // tail + const uint8_t* tail = (const uint8_t*)(&vDataToHash[0] + nblocks * 4); + + uint32_t k1 = 0; + + switch (vDataToHash.size() & 3) { + case 3: + k1 ^= tail[2] << 16; + case 2: + k1 ^= tail[1] << 8; + case 1: + k1 ^= tail[0]; + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + h1 ^= k1; + }; + } //---------- // finalization @@ -60,3 +68,16 @@ 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]) +{ + 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); +} diff --git a/src/hash.h b/src/hash.h index bdcd4afb47..e56b784a61 100644 --- a/src/hash.h +++ b/src/hash.h @@ -1,13 +1,13 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-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_HASH_H #define BITCOIN_HASH_H #include "crypto/ripemd160.h" -#include "crypto/sha2.h" +#include "crypto/sha256.h" #include "serialize.h" #include "uint256.h" #include "version.h" @@ -159,4 +159,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]); + #endif // BITCOIN_HASH_H diff --git a/src/init.cpp b/src/init.cpp index 7299bd0f4a..a09caeea40 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #if defined(HAVE_CONFIG_H) @@ -10,6 +10,7 @@ #include "init.h" #include "addrman.h" +#include "amount.h" #include "checkpoints.h" #include "compat/sanity.h" #include "key.h" @@ -17,6 +18,7 @@ #include "miner.h" #include "net.h" #include "rpcserver.h" +#include "script/standard.h" #include "txdb.h" #include "ui_interface.h" #include "util.h" @@ -45,8 +47,9 @@ using namespace boost; using namespace std; #ifdef ENABLE_WALLET -CWallet* pwalletMain; +CWallet* pwalletMain = NULL; #endif +bool fFeeEstimatesInitialized = false; #ifdef WIN32 // Win32 LevelDB doesn't use filedescriptors, and the ones used for @@ -57,7 +60,7 @@ CWallet* pwalletMain; #define MIN_CORE_FILEDESCRIPTORS 150 #endif -// Used to pass flags to the Bind() function +/** Used to pass flags to the Bind() function */ enum BindFlags { BF_NONE = 0, BF_EXPLICIT = (1U << 0), @@ -109,7 +112,7 @@ bool ShutdownRequested() return fRequestShutdown; } -static CCoinsViewDB *pcoinsdbview; +static CCoinsViewDB *pcoinsdbview = NULL; void Shutdown() { @@ -119,6 +122,10 @@ void Shutdown() if (!lockShutdown) return; + /// Note: Shutdown() must be able to handle cases in which AppInit2() failed part of the way, + /// for example if the data directory was found to be locked. + /// Be sure that anything that writes files or flushes caches only does this if the respective + /// module was initialized. RenameThread("bitcoin-shutoff"); mempool.AddTransactionsUpdated(1); StopRPCThreads(); @@ -130,25 +137,22 @@ void Shutdown() StopNode(); UnregisterNodeSignals(GetNodeSignals()); + if (fFeeEstimatesInitialized) { boost::filesystem::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME; CAutoFile est_fileout(fopen(est_path.string().c_str(), "wb"), SER_DISK, CLIENT_VERSION); - if (est_fileout) + if (!est_fileout.IsNull()) mempool.WriteFeeEstimates(est_fileout); else LogPrintf("%s: Failed to write fee estimates to %s\n", __func__, est_path.string()); + fFeeEstimatesInitialized = false; } { LOCK(cs_main); -#ifdef ENABLE_WALLET - if (pwalletMain) - pwalletMain->SetBestChain(chainActive.GetLocator()); -#endif - if (pblocktree) - pblocktree->Flush(); - if (pcoinsTip) - pcoinsTip->Flush(); + if (pcoinsTip != NULL) { + FlushStateToDisk(); + } delete pcoinsTip; pcoinsTip = NULL; delete pcoinsdbview; @@ -163,17 +167,17 @@ void Shutdown() #ifndef WIN32 boost::filesystem::remove(GetPidFile()); #endif - UnregisterAllWallets(); + UnregisterAllValidationInterfaces(); #ifdef ENABLE_WALLET - if (pwalletMain) - delete pwalletMain; + delete pwalletMain; + pwalletMain = NULL; #endif LogPrintf("%s: done\n", __func__); } -// -// Signal handlers are very limited in what they are allowed to do, so: -// +/** + * Signal handlers are very limited in what they are allowed to do, so: + */ void HandleSIGTERM(int) { fRequestShutdown = true; @@ -215,9 +219,9 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -? " + _("This help message") + "\n"; strUsage += " -alertnotify=<cmd> " + _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)") + "\n"; strUsage += " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n"; - strUsage += " -checkblocks=<n> " + _("How many blocks to check at startup (default: 288, 0 = all)") + "\n"; - strUsage += " -checklevel=<n> " + _("How thorough the block verification of -checkblocks is (0-4, default: 3)") + "\n"; - strUsage += " -conf=<file> " + _("Specify configuration file (default: bitcoin.conf)") + "\n"; + strUsage += " -checkblocks=<n> " + strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288) + "\n"; + strUsage += " -checklevel=<n> " + strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3) + "\n"; + strUsage += " -conf=<file> " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n"; if (mode == HMM_BITCOIND) { #if !defined(WIN32) @@ -227,83 +231,83 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n"; strUsage += " -dbcache=<n> " + strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache) + "\n"; strUsage += " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + " " + _("on startup") + "\n"; - strUsage += " -maxorphanblocks=<n> " + strprintf(_("Keep at most <n> unconnectable blocks in memory (default: %u)"), DEFAULT_MAX_ORPHAN_BLOCKS) + "\n"; strUsage += " -maxorphantx=<n> " + strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "\n"; strUsage += " -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) + "\n"; #ifndef WIN32 - strUsage += " -pid=<file> " + _("Specify pid file (default: bitcoind.pid)") + "\n"; + strUsage += " -pid=<file> " + strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid") + "\n"; #endif strUsage += " -reindex " + _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup") + "\n"; #if !defined(WIN32) strUsage += " -sysperms " + _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)") + "\n"; #endif - strUsage += " -txindex " + _("Maintain a full transaction index (default: 0)") + "\n"; + strUsage += " -txindex " + strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0) + "\n"; strUsage += "\n" + _("Connection options:") + "\n"; strUsage += " -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n"; - strUsage += " -banscore=<n> " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n"; - strUsage += " -bantime=<n> " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n"; + strUsage += " -banscore=<n> " + strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100) + "\n"; + strUsage += " -bantime=<n> " + strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400) + "\n"; strUsage += " -bind=<addr> " + _("Bind to given address and always listen on it. Use [host]:port notation for IPv6") + "\n"; strUsage += " -connect=<ip> " + _("Connect only to the specified node(s)") + "\n"; - strUsage += " -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n"; + strUsage += " -discover " + _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)") + "\n"; strUsage += " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)") + "\n"; strUsage += " -dnsseed " + _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)") + "\n"; strUsage += " -externalip=<ip> " + _("Specify your own public address") + "\n"; - strUsage += " -forcednsseed " + _("Always query for peer addresses via DNS lookup (default: 0)") + "\n"; + strUsage += " -forcednsseed " + strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0) + "\n"; strUsage += " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n"; - strUsage += " -maxconnections=<n> " + _("Maintain at most <n> connections to peers (default: 125)") + "\n"; - strUsage += " -maxreceivebuffer=<n> " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)") + "\n"; - strUsage += " -maxsendbuffer=<n> " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)") + "\n"; - strUsage += " -onion=<ip:port> " + _("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)") + "\n"; + strUsage += " -maxconnections=<n> " + strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125) + "\n"; + strUsage += " -maxreceivebuffer=<n> " + strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000) + "\n"; + strUsage += " -maxsendbuffer=<n> " + strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000) + "\n"; + strUsage += " -onion=<ip:port> " + strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy") + "\n"; strUsage += " -onlynet=<net> " + _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)") + "\n"; - strUsage += " -permitbaremultisig " + _("Relay non-P2SH multisig (default: 1)") + "\n"; - strUsage += " -port=<port> " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n"; + strUsage += " -permitbaremultisig " + strprintf(_("Relay non-P2SH multisig (default: %u)"), 1) + "\n"; + strUsage += " -port=<port> " + strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 8333, 18333) + "\n"; strUsage += " -proxy=<ip:port> " + _("Connect through SOCKS5 proxy") + "\n"; strUsage += " -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n"; - strUsage += " -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000)") + "\n"; + strUsage += " -timeout=<n> " + strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT) + "\n"; #ifdef USE_UPNP #if USE_UPNP strUsage += " -upnp " + _("Use UPnP to map the listening port (default: 1 when listening)") + "\n"; #else - strUsage += " -upnp " + _("Use UPnP to map the listening port (default: 0)") + "\n"; + strUsage += " -upnp " + strprintf(_("Use UPnP to map the listening port (default: %u)"), 0) + "\n"; #endif #endif strUsage += " -whitebind=<addr> " + _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6") + "\n"; - strUsage += " -whitelist=<netmask> " + _("Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.") + "\n"; + strUsage += " -whitelist=<netmask> " + _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + "\n"; strUsage += " " + _("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") + "\n"; #ifdef ENABLE_WALLET strUsage += "\n" + _("Wallet options:") + "\n"; strUsage += " -disablewallet " + _("Do not load the wallet and disable wallet RPC calls") + "\n"; - strUsage += " -keypool=<n> " + _("Set key pool size to <n> (default: 100)") + "\n"; + strUsage += " -keypool=<n> " + strprintf(_("Set key pool size to <n> (default: %u)"), 100) + "\n"; if (GetBoolArg("-help-debug", false)) strUsage += " -mintxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"), FormatMoney(CWallet::minTxFee.GetFeePerK())) + "\n"; strUsage += " -paytxfee=<amt> " + strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())) + "\n"; strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + " " + _("on startup") + "\n"; - strUsage += " -respendnotify=<cmd> " + _("Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)") + "\n"; strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n"; - strUsage += " -spendzeroconfchange " + _("Spend unconfirmed change when sending transactions (default: 1)") + "\n"; - strUsage += " -txconfirmtarget=<n> " + _("If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: 1)") + "\n"; + strUsage += " -sendfreetransactions " + strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0) + "\n"; + strUsage += " -spendzeroconfchange " + strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1) + "\n"; + strUsage += " -txconfirmtarget=<n> " + strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1) + "\n"; + strUsage += " -maxtxfee=<amt> " + strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), FormatMoney(maxTxFee)) + "\n"; strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n"; - strUsage += " -wallet=<file> " + _("Specify wallet file (within data directory)") + " " + _("(default: wallet.dat)") + "\n"; + strUsage += " -wallet=<file> " + _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat") + "\n"; strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n"; strUsage += " -zapwallettxes=<mode> " + _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + "\n"; - strUsage += " " + _("(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)") + "\n"; + strUsage += " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)") + "\n"; #endif strUsage += "\n" + _("Debugging/Testing options:") + "\n"; if (GetBoolArg("-help-debug", false)) { - strUsage += " -checkpoints " + _("Only accept block chain matching built-in checkpoints (default: 1)") + "\n"; - strUsage += " -dblogsize=<n> " + _("Flush database activity from memory pool to disk log every <n> megabytes (default: 100)") + "\n"; - strUsage += " -disablesafemode " + _("Disable safemode, override a real safe mode event (default: 0)") + "\n"; - strUsage += " -testsafemode " + _("Force safe mode (default: 0)") + "\n"; + strUsage += " -checkpoints " + strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1) + "\n"; + strUsage += " -dblogsize=<n> " + strprintf(_("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)"), 100) + "\n"; + strUsage += " -disablesafemode " + strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0) + "\n"; + strUsage += " -testsafemode " + strprintf(_("Force safe mode (default: %u)"), 0) + "\n"; strUsage += " -dropmessagestest=<n> " + _("Randomly drop 1 of every <n> network messages") + "\n"; strUsage += " -fuzzmessagestest=<n> " + _("Randomly fuzz 1 of every <n> network messages") + "\n"; - strUsage += " -flushwallet " + _("Run a thread to flush wallet periodically (default: 1)") + "\n"; - strUsage += " -stopafterblockimport " + _("Stop running after importing blocks from disk (default: 0)") + "\n"; + strUsage += " -flushwallet " + strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1) + "\n"; + strUsage += " -stopafterblockimport " + strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0) + "\n"; } - strUsage += " -debug=<category> " + _("Output debugging information (default: 0, supplying <category> is optional)") + "\n"; + strUsage += " -debug=<category> " + strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + "\n"; strUsage += " " + _("If <category> is not supplied, output all debugging information.") + "\n"; strUsage += " " + _("<category> can be:"); strUsage += " addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below @@ -311,25 +315,23 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += ", qt"; strUsage += ".\n"; #ifdef ENABLE_WALLET - strUsage += " -gen " + _("Generate coins (default: 0)") + "\n"; - strUsage += " -genproclimit=<n> " + _("Set the processor limit for when generation is on (-1 = unlimited, default: -1)") + "\n"; + strUsage += " -gen " + strprintf(_("Generate coins (default: %u)"), 0) + "\n"; + strUsage += " -genproclimit=<n> " + strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1) + "\n"; #endif strUsage += " -help-debug " + _("Show all debugging options (usage: --help -help-debug)") + "\n"; - strUsage += " -logips " + _("Include IP addresses in debug output (default: 0)") + "\n"; - strUsage += " -logtimestamps " + _("Prepend debug output with timestamp (default: 1)") + "\n"; + strUsage += " -logips " + strprintf(_("Include IP addresses in debug output (default: %u)"), 0) + "\n"; + strUsage += " -logtimestamps " + strprintf(_("Prepend debug output with timestamp (default: %u)"), 1) + "\n"; if (GetBoolArg("-help-debug", false)) { - strUsage += " -limitfreerelay=<n> " + _("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)") + "\n"; - strUsage += " -maxsigcachesize=<n> " + _("Limit size of signature cache to <n> entries (default: 50000)") + "\n"; + strUsage += " -limitfreerelay=<n> " + strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15) + "\n"; + strUsage += " -maxsigcachesize=<n> " + strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000) + "\n"; } strUsage += " -minrelaytxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())) + "\n"; strUsage += " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n"; if (GetBoolArg("-help-debug", false)) { - strUsage += " -printblock=<hash> " + _("Print block on startup, if found in block index") + "\n"; - strUsage += " -printblocktree " + _("Print block tree on startup (default: 0)") + "\n"; - strUsage += " -printpriority " + _("Log transaction priority and fee per kB when mining blocks (default: 0)") + "\n"; - strUsage += " -privdb " + _("Sets the DB_PRIVATE flag in the wallet db environment (default: 1)") + "\n"; + strUsage += " -printpriority " + strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0) + "\n"; + strUsage += " -privdb " + strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1) + "\n"; strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n"; strUsage += " " + _("This is intended for regression testing tools and app development.") + "\n"; strUsage += " " + _("In this mode -genproclimit controls how many blocks are generated immediately.") + "\n"; @@ -338,27 +340,29 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += " -testnet " + _("Use the test network") + "\n"; strUsage += "\n" + _("Node relay options:") + "\n"; - strUsage += " -datacarrier " + _("Relay and mine data carrier transactions (default: 1)") + "\n"; + strUsage += " -datacarrier " + strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1) + "\n"; + strUsage += " -datacarriersize " + strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY) + "\n"; strUsage += "\n" + _("Block creation options:") + "\n"; - strUsage += " -blockminsize=<n> " + _("Set minimum block size in bytes (default: 0)") + "\n"; + strUsage += " -blockminsize=<n> " + strprintf(_("Set minimum block size in bytes (default: %u)"), 0) + "\n"; strUsage += " -blockmaxsize=<n> " + strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE) + "\n"; strUsage += " -blockprioritysize=<n> " + strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE) + "\n"; strUsage += "\n" + _("RPC server options:") + "\n"; strUsage += " -server " + _("Accept command line and JSON-RPC commands") + "\n"; + strUsage += " -rest " + strprintf(_("Accept public REST requests (default: %u)"), 0) + "\n"; strUsage += " -rpcbind=<addr> " + _("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)") + "\n"; strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n"; strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n"; - strUsage += " -rpcport=<port> " + _("Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)") + "\n"; + strUsage += " -rpcport=<port> " + strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n"; strUsage += " -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") + "\n"; - strUsage += " -rpcthreads=<n> " + _("Set the number of threads to service RPC calls (default: 4)") + "\n"; + strUsage += " -rpcthreads=<n> " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n"; strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n"; strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n"; - strUsage += " -rpcsslcertificatechainfile=<file.cert> " + _("Server certificate file (default: server.cert)") + "\n"; - strUsage += " -rpcsslprivatekeyfile=<file.pem> " + _("Server private key (default: server.pem)") + "\n"; - strUsage += " -rpcsslciphers=<ciphers> " + _("Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)") + "\n"; + strUsage += " -rpcsslcertificatechainfile=<file.cert> " + strprintf(_("Server certificate file (default: %s)"), "server.cert") + "\n"; + strUsage += " -rpcsslprivatekeyfile=<file.pem> " + strprintf(_("Server private key (default: %s)"), "server.pem") + "\n"; + strUsage += " -rpcsslciphers=<ciphers> " + strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH") + "\n"; return strUsage; } @@ -369,7 +373,7 @@ std::string LicenseInfo() "\n" + FormatParagraph(_("This is experimental software.")) + "\n" + "\n" + - FormatParagraph(_("Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.")) + "\n" + + FormatParagraph(_("Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.")) + "\n" + "\n" + FormatParagraph(_("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.")) + "\n"; @@ -542,51 +546,63 @@ bool AppInit2(boost::thread_group& threadGroup) // ********************************************************* Step 2: parameter interactions - if (mapArgs.count("-bind") || mapArgs.count("-whitebind")) { - // when specifying an explicit binding address, you want to listen on it - // even when -connect or -proxy is specified + // Set this early so that parameter interactions go to console + fPrintToConsole = GetBoolArg("-printtoconsole", false); + fLogTimestamps = GetBoolArg("-logtimestamps", true); + fLogIPs = GetBoolArg("-logips", false); + + // when specifying an explicit binding address, you want to listen on it + // even when -connect or -proxy is specified + if (mapArgs.count("-bind")) { + if (SoftSetBoolArg("-listen", true)) + LogPrintf("%s: parameter interaction: -bind set -> setting -listen=1\n", __func__); + } + if (mapArgs.count("-whitebind")) { if (SoftSetBoolArg("-listen", true)) - LogPrintf("AppInit2 : parameter interaction: -bind or -whitebind set -> setting -listen=1\n"); + LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__); } if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) { // when only connecting to trusted nodes, do not seed via DNS, or listen by default if (SoftSetBoolArg("-dnsseed", false)) - LogPrintf("AppInit2 : parameter interaction: -connect set -> setting -dnsseed=0\n"); + LogPrintf("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__); if (SoftSetBoolArg("-listen", false)) - LogPrintf("AppInit2 : parameter interaction: -connect set -> setting -listen=0\n"); + LogPrintf("%s: parameter interaction: -connect set -> setting -listen=0\n", __func__); } if (mapArgs.count("-proxy")) { // to protect privacy, do not listen by default if a default proxy server is specified if (SoftSetBoolArg("-listen", false)) - LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -listen=0\n"); + LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=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__); } - if (!GetBoolArg("-listen", true)) { + if (!GetBoolArg("-listen", DEFAULT_LISTEN)) { // do not map ports or try to retrieve public IP when not listening (pointless) if (SoftSetBoolArg("-upnp", false)) - LogPrintf("AppInit2 : parameter interaction: -listen=0 -> setting -upnp=0\n"); + LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__); if (SoftSetBoolArg("-discover", false)) - LogPrintf("AppInit2 : parameter interaction: -listen=0 -> setting -discover=0\n"); + LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__); } if (mapArgs.count("-externalip")) { // if an explicit public IP is specified, do not try to find others if (SoftSetBoolArg("-discover", false)) - LogPrintf("AppInit2 : parameter interaction: -externalip set -> setting -discover=0\n"); + LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__); } if (GetBoolArg("-salvagewallet", false)) { // Rewrite just private keys: rescan to find transactions if (SoftSetBoolArg("-rescan", true)) - LogPrintf("AppInit2 : parameter interaction: -salvagewallet=1 -> setting -rescan=1\n"); + LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); } // -zapwallettx implies a rescan if (GetBoolArg("-zapwallettxes", false)) { if (SoftSetBoolArg("-rescan", true)) - LogPrintf("AppInit2 : parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n"); + LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__); } // Make sure enough file descriptors are available @@ -634,19 +650,13 @@ bool AppInit2(boost::thread_group& threadGroup) nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS; fServer = GetBoolArg("-server", false); - fPrintToConsole = GetBoolArg("-printtoconsole", false); - fLogTimestamps = GetBoolArg("-logtimestamps", true); - fLogIPs = GetBoolArg("-logips", false); #ifdef ENABLE_WALLET bool fDisableWallet = GetBoolArg("-disablewallet", false); #endif - if (mapArgs.count("-timeout")) - { - int nNewTimeout = GetArg("-timeout", 5000); - if (nNewTimeout > 0 && nNewTimeout < 600000) - nConnectTimeout = nNewTimeout; - } + nConnectTimeout = GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT); + if (nConnectTimeout <= 0) + nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; // Continue to put "/P2SH/" in the coinbase to monitor // BIP16 support. @@ -662,7 +672,7 @@ bool AppInit2(boost::thread_group& threadGroup) // cost to you of processing a transaction. if (mapArgs.count("-minrelaytxfee")) { - int64_t n = 0; + CAmount n = 0; if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0) ::minRelayTxFee = CFeeRate(n); else @@ -672,7 +682,7 @@ bool AppInit2(boost::thread_group& threadGroup) #ifdef ENABLE_WALLET if (mapArgs.count("-mintxfee")) { - int64_t n = 0; + CAmount n = 0; if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0) CWallet::minTxFee = CFeeRate(n); else @@ -680,7 +690,7 @@ bool AppInit2(boost::thread_group& threadGroup) } if (mapArgs.count("-paytxfee")) { - int64_t nFeePerK = 0; + CAmount nFeePerK = 0; if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK)) return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"])); if (nFeePerK > nHighTransactionFeeWarning) @@ -692,15 +702,32 @@ bool AppInit2(boost::thread_group& threadGroup) mapArgs["-paytxfee"], ::minRelayTxFee.ToString())); } } + if (mapArgs.count("-maxtxfee")) + { + CAmount nMaxFee = 0; + if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee)) + return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s'"), mapArgs["-maptxfee"])); + if (nMaxFee > nHighTransactionMaxFeeWarning) + InitWarning(_("Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.")); + maxTxFee = nMaxFee; + if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) + { + return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), + mapArgs["-maxtxfee"], ::minRelayTxFee.ToString())); + } + } nTxConfirmTarget = GetArg("-txconfirmtarget", 1); bSpendZeroConfChange = GetArg("-spendzeroconfchange", true); + fSendFreeTransactions = GetArg("-sendfreetransactions", false); std::string strWalletFile = GetArg("-wallet", "wallet.dat"); #endif // ENABLE_WALLET fIsBareMultisigStd = GetArg("-permitbaremultisig", true) != 0; + nMaxDatacarrierBytes = GetArg("-datacarriersize", nMaxDatacarrierBytes); // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log + // Sanity check if (!InitSanityCheck()) return InitError(_("Initialization sanity check failed. Bitcoin Core is shutting down.")); @@ -737,12 +764,23 @@ bool AppInit2(boost::thread_group& threadGroup) LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD); std::ostringstream strErrors; + LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads); if (nScriptCheckThreads) { - LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads); for (int i=0; i<nScriptCheckThreads-1; i++) threadGroup.create_thread(&ThreadScriptCheck); } + /* 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 + * be disabled when initialisation is finished. + */ + if (fServer) + { + uiInterface.InitMessage.connect(SetRPCWarmupStatus); + StartRPCThreads(); + } + int64_t nStart; // ********************************************************* Step 5: verify wallet database integrity @@ -759,7 +797,7 @@ bool AppInit2(boost::thread_group& threadGroup) try { boost::filesystem::rename(pathDatabase, pathDatabaseBak); LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string()); - } catch(boost::filesystem::filesystem_error &error) { + } catch (const boost::filesystem::filesystem_error&) { // failure is ok (well, not really, but it's not worse than what we started with) } @@ -829,10 +867,8 @@ bool AppInit2(boost::thread_group& threadGroup) if (!addrProxy.IsValid()) return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"])); - if (!IsLimited(NET_IPV4)) - SetProxy(NET_IPV4, addrProxy); - if (!IsLimited(NET_IPV6)) - SetProxy(NET_IPV6, addrProxy); + SetProxy(NET_IPV4, addrProxy); + SetProxy(NET_IPV6, addrProxy); SetNameProxy(addrProxy); fProxy = true; } @@ -914,7 +950,7 @@ bool AppInit2(boost::thread_group& threadGroup) filesystem::create_hard_link(source, dest); LogPrintf("Hardlinked %s -> %s\n", source.string(), dest.string()); linked = true; - } catch (filesystem::filesystem_error & e) { + } catch (const filesystem::filesystem_error& e) { // Note: hardlink creation failing is not a disaster, it just means // blocks will get re-downloaded from peers. LogPrintf("Error hardlinking blk%04u.dat : %s\n", i, e.what()); @@ -958,7 +994,7 @@ bool AppInit2(boost::thread_group& threadGroup) pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex); pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex); - pcoinsTip = new CCoinsViewCache(*pcoinsdbview); + pcoinsTip = new CCoinsViewCache(pcoinsdbview); if (fReindex) pblocktree->WriteReindexing(true); @@ -970,7 +1006,7 @@ bool AppInit2(boost::thread_group& threadGroup) // If the loaded chain has a wrong genesis, bail out immediately // (we're likely using a testnet datadir, or the other way around). - if (!mapBlockIndex.empty() && chainActive.Genesis() == NULL) + if (!mapBlockIndex.empty() && mapBlockIndex.count(Params().HashGenesisBlock()) == 0) return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?")); // Initialize the block index (no-op if non-empty database was already loaded) @@ -991,7 +1027,7 @@ bool AppInit2(boost::thread_group& threadGroup) strLoadError = _("Corrupted block database detected"); break; } - } catch(std::exception &e) { + } catch (const std::exception& e) { if (fDebug) LogPrintf("%s\n", e.what()); strLoadError = _("Error opening block database"); break; @@ -1029,39 +1065,12 @@ bool AppInit2(boost::thread_group& threadGroup) } LogPrintf(" block index %15dms\n", GetTimeMillis() - nStart); - if (GetBoolArg("-printblockindex", false) || GetBoolArg("-printblocktree", false)) - { - PrintBlockTree(); - return false; - } - - if (mapArgs.count("-printblock")) - { - string strMatch = mapArgs["-printblock"]; - int nFound = 0; - for (BlockMap::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) - { - uint256 hash = (*mi).first; - if (boost::algorithm::starts_with(hash.ToString(), strMatch)) - { - CBlockIndex* pindex = (*mi).second; - CBlock block; - ReadBlockFromDisk(block, pindex); - block.BuildMerkleTree(); - LogPrintf("%s\n", block.ToString()); - nFound++; - } - } - if (nFound == 0) - LogPrintf("No blocks matching %s were found\n", strMatch); - return false; - } - boost::filesystem::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME; - CAutoFile est_filein = CAutoFile(fopen(est_path.string().c_str(), "rb"), SER_DISK, CLIENT_VERSION); + CAutoFile est_filein(fopen(est_path.string().c_str(), "rb"), SER_DISK, CLIENT_VERSION); // Allowed to fail as this file IS missing on first startup. - if (est_filein) + if (!est_filein.IsNull()) mempool.ReadFeeEstimates(est_filein); + fFeeEstimatesInitialized = true; // ********************************************************* Step 8: load wallet #ifdef ENABLE_WALLET @@ -1149,7 +1158,7 @@ bool AppInit2(boost::thread_group& threadGroup) LogPrintf("%s", strErrors.str()); LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart); - RegisterWallet(pwalletMain); + RegisterValidationInterface(pwalletMain); CBlockIndex *pindexRescan = chainActive.Tip(); if (GetBoolArg("-rescan", false)) @@ -1159,7 +1168,7 @@ bool AppInit2(boost::thread_group& threadGroup) CWalletDB walletdb(strWalletFile); CBlockLocator locator; if (walletdb.ReadBestBlock(locator)) - pindexRescan = chainActive.FindFork(locator); + pindexRescan = FindForkInGlobalIndex(chainActive, locator); else pindexRescan = chainActive.Genesis(); } @@ -1218,22 +1227,7 @@ bool AppInit2(boost::thread_group& threadGroup) } threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles)); - // ********************************************************* Step 10: load peers - - uiInterface.InitMessage(_("Loading addresses...")); - - nStart = GetTimeMillis(); - - { - CAddrDB adb; - if (!adb.Read(addrman)) - LogPrintf("Invalid or missing peers.dat; recreating\n"); - } - - LogPrintf("Loaded %i addresses from peers.dat %dms\n", - addrman.size(), GetTimeMillis() - nStart); - - // ********************************************************* Step 11: start node + // ********************************************************* Step 10: start node if (!CheckDiskSpace()) return false; @@ -1253,17 +1247,16 @@ bool AppInit2(boost::thread_group& threadGroup) #endif StartNode(threadGroup); - if (fServer) - StartRPCThreads(); #ifdef ENABLE_WALLET // Generate coins in the background if (pwalletMain) - GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", -1)); + GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1)); #endif - // ********************************************************* Step 12: finished + // ********************************************************* Step 11: finished + SetRPCWarmupFinished(); uiInterface.InitMessage(_("Done loading")); #ifdef ENABLE_WALLET diff --git a/src/init.h b/src/init.h index aaf8c07e6e..d451f65be9 100644 --- a/src/init.h +++ b/src/init.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_INIT_H @@ -22,7 +22,7 @@ bool ShutdownRequested(); void Shutdown(); bool AppInit2(boost::thread_group& threadGroup); -/* The help message mode determines what help message to show */ +/** The help message mode determines what help message to show */ enum HelpMessageMode { HMM_BITCOIND, HMM_BITCOIN_QT diff --git a/src/key.cpp b/src/key.cpp index 8ed787654a..7f1cef1708 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -1,29 +1,25 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "key.h" -#include "crypto/sha2.h" +#include "crypto/hmac_sha512.h" +#include "crypto/rfc6979_hmac_sha256.h" +#include "eccryptoverify.h" +#include "pubkey.h" #include "random.h" -#ifdef USE_SECP256K1 #include <secp256k1.h> -#else -#include <openssl/bn.h> -#include <openssl/ecdsa.h> -#include <openssl/obj_mac.h> -#endif +#include "ecwrapper.h" -// anonymous namespace with local implementation code (OpenSSL interaction) +//! anonymous namespace namespace { -#ifdef USE_SECP256K1 -#include <secp256k1.h> class CSecp256k1Init { public: CSecp256k1Init() { - secp256k1_start(); + secp256k1_start(SECP256K1_START_SIGN); } ~CSecp256k1Init() { secp256k1_stop(); @@ -31,383 +27,10 @@ public: }; static CSecp256k1Init instance_of_csecp256k1; -#else - -// Generate a private key from just the secret parameter -int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key) -{ - int ok = 0; - BN_CTX *ctx = NULL; - EC_POINT *pub_key = NULL; - - if (!eckey) return 0; - - const EC_GROUP *group = EC_KEY_get0_group(eckey); - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - - pub_key = EC_POINT_new(group); - - if (pub_key == NULL) - goto err; - - if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) - goto err; - - EC_KEY_set_private_key(eckey,priv_key); - EC_KEY_set_public_key(eckey,pub_key); - - ok = 1; - -err: - - if (pub_key) - EC_POINT_free(pub_key); - if (ctx != NULL) - BN_CTX_free(ctx); - - return(ok); -} - -// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields -// recid selects which key is recovered -// if check is non-zero, additional checks are performed -int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check) -{ - if (!eckey) return 0; - - int ret = 0; - BN_CTX *ctx = NULL; - - BIGNUM *x = NULL; - BIGNUM *e = NULL; - BIGNUM *order = NULL; - BIGNUM *sor = NULL; - BIGNUM *eor = NULL; - BIGNUM *field = NULL; - EC_POINT *R = NULL; - EC_POINT *O = NULL; - EC_POINT *Q = NULL; - BIGNUM *rr = NULL; - BIGNUM *zero = NULL; - int n = 0; - int i = recid / 2; - - const EC_GROUP *group = EC_KEY_get0_group(eckey); - if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; } - BN_CTX_start(ctx); - order = BN_CTX_get(ctx); - if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; } - x = BN_CTX_get(ctx); - if (!BN_copy(x, order)) { ret=-1; goto err; } - if (!BN_mul_word(x, i)) { ret=-1; goto err; } - if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; } - field = BN_CTX_get(ctx); - if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; } - if (BN_cmp(x, field) >= 0) { ret=0; goto err; } - if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } - if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; } - if (check) - { - if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } - if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; } - if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; } - } - if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } - n = EC_GROUP_get_degree(group); - e = BN_CTX_get(ctx); - if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; } - if (8*msglen > n) BN_rshift(e, e, 8-(n & 7)); - zero = BN_CTX_get(ctx); - if (!BN_zero(zero)) { ret=-1; goto err; } - if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; } - rr = BN_CTX_get(ctx); - if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; } - sor = BN_CTX_get(ctx); - if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; } - eor = BN_CTX_get(ctx); - if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; } - if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; } - if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; } - - ret = 1; - -err: - if (ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - if (R != NULL) EC_POINT_free(R); - if (O != NULL) EC_POINT_free(O); - if (Q != NULL) EC_POINT_free(Q); - return ret; -} - -// RAII Wrapper around OpenSSL's EC_KEY -class CECKey { -private: - EC_KEY *pkey; - -public: - CECKey() { - pkey = EC_KEY_new_by_curve_name(NID_secp256k1); - assert(pkey != NULL); - } - - ~CECKey() { - EC_KEY_free(pkey); - } - - void GetSecretBytes(unsigned char vch[32]) const { - const BIGNUM *bn = EC_KEY_get0_private_key(pkey); - assert(bn); - int nBytes = BN_num_bytes(bn); - int n=BN_bn2bin(bn,&vch[32 - nBytes]); - assert(n == nBytes); - memset(vch, 0, 32 - nBytes); - } - - void SetSecretBytes(const unsigned char vch[32]) { - bool ret; - BIGNUM bn; - BN_init(&bn); - ret = BN_bin2bn(vch, 32, &bn) != NULL; - assert(ret); - ret = EC_KEY_regenerate_key(pkey, &bn) != 0; - assert(ret); - BN_clear_free(&bn); - } - - void GetPrivKey(CPrivKey &privkey, bool fCompressed) { - EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED); - int nSize = i2d_ECPrivateKey(pkey, NULL); - assert(nSize); - privkey.resize(nSize); - unsigned char* pbegin = &privkey[0]; - int nSize2 = i2d_ECPrivateKey(pkey, &pbegin); - assert(nSize == nSize2); - } - - bool SetPrivKey(const CPrivKey &privkey, bool fSkipCheck=false) { - const unsigned char* pbegin = &privkey[0]; - if (d2i_ECPrivateKey(&pkey, &pbegin, privkey.size())) { - if(fSkipCheck) - return true; - - // d2i_ECPrivateKey returns true if parsing succeeds. - // This doesn't necessarily mean the key is valid. - if (EC_KEY_check_key(pkey)) - return true; - } - return false; - } - - void GetPubKey(CPubKey &pubkey, bool fCompressed) { - EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED); - int nSize = i2o_ECPublicKey(pkey, NULL); - assert(nSize); - assert(nSize <= 65); - unsigned char c[65]; - unsigned char *pbegin = c; - int nSize2 = i2o_ECPublicKey(pkey, &pbegin); - assert(nSize == nSize2); - pubkey.Set(&c[0], &c[nSize]); - } - - bool SetPubKey(const CPubKey &pubkey) { - const unsigned char* pbegin = pubkey.begin(); - return o2i_ECPublicKey(&pkey, &pbegin, pubkey.size()) != NULL; - } - - bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) { - vchSig.clear(); - ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey); - if (sig == NULL) - return false; - BN_CTX *ctx = BN_CTX_new(); - BN_CTX_start(ctx); - const EC_GROUP *group = EC_KEY_get0_group(pkey); - BIGNUM *order = BN_CTX_get(ctx); - BIGNUM *halforder = BN_CTX_get(ctx); - EC_GROUP_get_order(group, order, ctx); - BN_rshift1(halforder, order); - if (BN_cmp(sig->s, halforder) > 0) { - // enforce low S values, by negating the value (modulo the order) if above order/2. - BN_sub(sig->s, order, sig->s); - } - BN_CTX_end(ctx); - BN_CTX_free(ctx); - unsigned int nSize = ECDSA_size(pkey); - vchSig.resize(nSize); // Make sure it is big enough - unsigned char *pos = &vchSig[0]; - nSize = i2d_ECDSA_SIG(sig, &pos); - ECDSA_SIG_free(sig); - vchSig.resize(nSize); // Shrink to fit actual size - return true; - } - - bool Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) { - // -1 = error, 0 = bad sig, 1 = good - if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) - return false; - return true; - } - - bool SignCompact(const uint256 &hash, unsigned char *p64, int &rec) { - bool fOk = false; - ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey); - if (sig==NULL) - return false; - memset(p64, 0, 64); - int nBitsR = BN_num_bits(sig->r); - int nBitsS = BN_num_bits(sig->s); - if (nBitsR <= 256 && nBitsS <= 256) { - CPubKey pubkey; - GetPubKey(pubkey, true); - for (int i=0; i<4; i++) { - CECKey keyRec; - if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1) { - CPubKey pubkeyRec; - keyRec.GetPubKey(pubkeyRec, true); - if (pubkeyRec == pubkey) { - rec = i; - fOk = true; - break; - } - } - } - assert(fOk); - BN_bn2bin(sig->r,&p64[32-(nBitsR+7)/8]); - BN_bn2bin(sig->s,&p64[64-(nBitsS+7)/8]); - } - ECDSA_SIG_free(sig); - return fOk; - } - - // reconstruct public key from a compact signature - // This is only slightly more CPU intensive than just verifying it. - // If this function succeeds, the recovered public key is guaranteed to be valid - // (the signature is a valid signature of the given data for that key) - bool Recover(const uint256 &hash, const unsigned char *p64, int rec) - { - if (rec<0 || rec>=3) - return false; - ECDSA_SIG *sig = ECDSA_SIG_new(); - BN_bin2bn(&p64[0], 32, sig->r); - BN_bin2bn(&p64[32], 32, sig->s); - bool ret = ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), rec, 0) == 1; - ECDSA_SIG_free(sig); - return ret; - } - - static bool TweakSecret(unsigned char vchSecretOut[32], const unsigned char vchSecretIn[32], const unsigned char vchTweak[32]) - { - bool ret = true; - BN_CTX *ctx = BN_CTX_new(); - BN_CTX_start(ctx); - BIGNUM *bnSecret = BN_CTX_get(ctx); - BIGNUM *bnTweak = BN_CTX_get(ctx); - BIGNUM *bnOrder = BN_CTX_get(ctx); - EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp256k1); - EC_GROUP_get_order(group, bnOrder, ctx); // what a grossly inefficient way to get the (constant) group order... - BN_bin2bn(vchTweak, 32, bnTweak); - if (BN_cmp(bnTweak, bnOrder) >= 0) - ret = false; // extremely unlikely - BN_bin2bn(vchSecretIn, 32, bnSecret); - BN_add(bnSecret, bnSecret, bnTweak); - BN_nnmod(bnSecret, bnSecret, bnOrder, ctx); - if (BN_is_zero(bnSecret)) - ret = false; // ridiculously unlikely - int nBits = BN_num_bits(bnSecret); - memset(vchSecretOut, 0, 32); - BN_bn2bin(bnSecret, &vchSecretOut[32-(nBits+7)/8]); - EC_GROUP_free(group); - BN_CTX_end(ctx); - BN_CTX_free(ctx); - return ret; - } - - bool TweakPublic(const unsigned char vchTweak[32]) { - bool ret = true; - BN_CTX *ctx = BN_CTX_new(); - BN_CTX_start(ctx); - BIGNUM *bnTweak = BN_CTX_get(ctx); - BIGNUM *bnOrder = BN_CTX_get(ctx); - BIGNUM *bnOne = BN_CTX_get(ctx); - const EC_GROUP *group = EC_KEY_get0_group(pkey); - EC_GROUP_get_order(group, bnOrder, ctx); // what a grossly inefficient way to get the (constant) group order... - BN_bin2bn(vchTweak, 32, bnTweak); - if (BN_cmp(bnTweak, bnOrder) >= 0) - ret = false; // extremely unlikely - EC_POINT *point = EC_POINT_dup(EC_KEY_get0_public_key(pkey), group); - BN_one(bnOne); - EC_POINT_mul(group, point, bnTweak, point, bnOne, ctx); - if (EC_POINT_is_at_infinity(group, point)) - ret = false; // ridiculously unlikely - EC_KEY_set_public_key(pkey, point); - EC_POINT_free(point); - BN_CTX_end(ctx); - BN_CTX_free(ctx); - return ret; - } -}; - -#endif - -int CompareBigEndian(const unsigned char *c1, size_t c1len, const unsigned char *c2, size_t c2len) { - while (c1len > c2len) { - if (*c1) - return 1; - c1++; - c1len--; - } - while (c2len > c1len) { - if (*c2) - return -1; - c2++; - c2len--; - } - while (c1len > 0) { - if (*c1 > *c2) - return 1; - if (*c2 > *c1) - return -1; - c1++; - c2++; - c1len--; - } - return 0; -} - -// Order of secp256k1's generator minus 1. -const unsigned char vchMaxModOrder[32] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, - 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, - 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40 -}; - -// Half of the order of secp256k1's generator minus 1. -const unsigned char vchMaxModHalfOrder[32] = { - 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0x5D,0x57,0x6E,0x73,0x57,0xA4,0x50,0x1D, - 0xDF,0xE9,0x2F,0x46,0x68,0x1B,0x20,0xA0 -}; - -const unsigned char vchZero[1] = {0}; - } // anon namespace bool CKey::Check(const unsigned char *vch) { - return CompareBigEndian(vch, 32, vchZero, 0) > 0 && - CompareBigEndian(vch, 32, vchMaxModOrder, 32) <= 0; -} - -bool CKey::CheckSignatureElement(const unsigned char *vch, int len, bool half) { - return CompareBigEndian(vch, len, vchZero, 0) > 0 && - CompareBigEndian(vch, len, half ? vchMaxModHalfOrder : vchMaxModOrder, 32) <= 0; + return eccrypto::Check(vch); } void CKey::MakeNewKey(bool fCompressedIn) { @@ -419,15 +42,8 @@ void CKey::MakeNewKey(bool fCompressedIn) { } bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) { -#ifdef USE_SECP256K1 - if (!secp256k1_ecdsa_privkey_import((unsigned char*)begin(), &privkey[0], privkey.size())) - return false; -#else - CECKey key; - if (!key.SetPrivKey(privkey)) + if (!secp256k1_ec_privkey_import((unsigned char*)begin(), &privkey[0], privkey.size())) return false; - key.GetSecretBytes(vch); -#endif fCompressed = fCompressedIn; fValid = true; return true; @@ -436,56 +52,57 @@ bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) { CPrivKey CKey::GetPrivKey() const { assert(fValid); CPrivKey privkey; -#ifdef USE_SECP256K1 + int privkeylen, ret; privkey.resize(279); - int privkeylen = 279; - int ret = secp256k1_ecdsa_privkey_export(begin(), (unsigned char*)&privkey[0], &privkeylen, fCompressed); + privkeylen = 279; + ret = secp256k1_ec_privkey_export(begin(), (unsigned char*)&privkey[0], &privkeylen, fCompressed); assert(ret); privkey.resize(privkeylen); -#else - CECKey key; - key.SetSecretBytes(vch); - key.GetPrivKey(privkey, fCompressed); -#endif return privkey; } CPubKey CKey::GetPubKey() const { assert(fValid); - CPubKey pubkey; -#ifdef USE_SECP256K1 + CPubKey result; int clen = 65; - int ret = secp256k1_ecdsa_pubkey_create((unsigned char*)pubkey.begin(), &clen, begin(), fCompressed); + int ret = secp256k1_ec_pubkey_create((unsigned char*)result.begin(), &clen, begin(), fCompressed); + assert((int)result.size() == clen); assert(ret); - assert(pubkey.IsValid()); - assert((int)pubkey.size() == clen); -#else - CECKey key; - key.SetSecretBytes(vch); - key.GetPubKey(pubkey, fCompressed); -#endif - return pubkey; + assert(result.IsValid()); + return result; } -bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const { +bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_t test_case) const { if (!fValid) return false; -#ifdef USE_SECP256K1 vchSig.resize(72); - int nSigLen = 72; - CKey nonce; + RFC6979_HMAC_SHA256 prng(begin(), 32, (unsigned char*)&hash, 32); do { - nonce.MakeNewKey(true); - if (secp256k1_ecdsa_sign((const unsigned char*)&hash, 32, (unsigned char*)&vchSig[0], &nSigLen, begin(), nonce.begin())) - break; + uint256 nonce; + prng.Generate((unsigned char*)&nonce, 32); + nonce += test_case; + int nSigLen = 72; + int ret = secp256k1_ecdsa_sign((const unsigned char*)&hash, (unsigned char*)&vchSig[0], &nSigLen, begin(), (unsigned char*)&nonce); + nonce = 0; + if (ret) { + vchSig.resize(nSigLen); + return true; + } } while(true); - vchSig.resize(nSigLen); - return true; -#else - CECKey key; - key.SetSecretBytes(vch); - return key.Sign(hash, vchSig); -#endif +} + +bool CKey::VerifyPubKey(const CPubKey& pubkey) const { + if (pubkey.IsCompressed() != fCompressed) { + return false; + } + unsigned char rnd[8]; + std::string str = "Bitcoin key verification\n"; + GetRandBytes(rnd, sizeof(rnd)); + uint256 hash; + CHash256().Write((unsigned char*)str.data(), str.size()).Write(rnd, sizeof(rnd)).Finalize((unsigned char*)&hash); + std::vector<unsigned char> vchSig; + Sign(hash, vchSig); + return pubkey.Verify(hash, vchSig); } bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const { @@ -493,122 +110,30 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) return false; vchSig.resize(65); int rec = -1; -#ifdef USE_SECP256K1 - CKey nonce; + RFC6979_HMAC_SHA256 prng(begin(), 32, (unsigned char*)&hash, 32); do { - nonce.MakeNewKey(true); - if (secp256k1_ecdsa_sign_compact((const unsigned char*)&hash, 32, &vchSig[1], begin(), nonce.begin(), &rec)) + uint256 nonce; + prng.Generate((unsigned char*)&nonce, 32); + int ret = secp256k1_ecdsa_sign_compact((const unsigned char*)&hash, &vchSig[1], begin(), (unsigned char*)&nonce, &rec); + nonce = 0; + if (ret) break; } while(true); -#else - CECKey key; - key.SetSecretBytes(vch); - if (!key.SignCompact(hash, &vchSig[1], rec)) - return false; -#endif assert(rec != -1); vchSig[0] = 27 + rec + (fCompressed ? 4 : 0); return true; } bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) { -#ifdef USE_SECP256K1 - if (!secp256k1_ecdsa_privkey_import((unsigned char*)begin(), &privkey[0], privkey.size())) + if (!secp256k1_ec_privkey_import((unsigned char*)begin(), &privkey[0], privkey.size())) return false; -#else - CECKey key; - if (!key.SetPrivKey(privkey, fSkipCheck)) - return false; - key.GetSecretBytes(vch); -#endif fCompressed = vchPubKey.IsCompressed(); fValid = true; if (fSkipCheck) return true; - if (GetPubKey() != vchPubKey) - return false; - - return true; -} - -bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const { - if (!IsValid()) - return false; -#ifdef USE_SECP256K1 - if (secp256k1_ecdsa_verify((const unsigned char*)&hash, 32, &vchSig[0], vchSig.size(), begin(), size()) != 1) - return false; -#else - CECKey key; - if (!key.SetPubKey(*this)) - return false; - if (!key.Verify(hash, vchSig)) - return false; -#endif - return true; -} - -bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) { - if (vchSig.size() != 65) - return false; - int recid = (vchSig[0] - 27) & 3; - bool fComp = ((vchSig[0] - 27) & 4) != 0; -#ifdef USE_SECP256K1 - int pubkeylen = 65; - if (!secp256k1_ecdsa_recover_compact((const unsigned char*)&hash, 32, &vchSig[1], (unsigned char*)begin(), &pubkeylen, fComp, recid)) - return false; - assert((int)size() == pubkeylen); -#else - CECKey key; - if (!key.Recover(hash, &vchSig[1], recid)) - return false; - key.GetPubKey(*this, fComp); -#endif - return true; -} - -bool CPubKey::IsFullyValid() const { - if (!IsValid()) - return false; -#ifdef USE_SECP256K1 - if (!secp256k1_ecdsa_pubkey_verify(begin(), size())) - return false; -#else - CECKey key; - if (!key.SetPubKey(*this)) - return false; -#endif - return true; -} - -bool CPubKey::Decompress() { - if (!IsValid()) - return false; -#ifdef USE_SECP256K1 - int clen = size(); - int ret = secp256k1_ecdsa_pubkey_decompress((unsigned char*)begin(), &clen); - assert(ret); - assert(clen == (int)size()); -#else - CECKey key; - if (!key.SetPubKey(*this)) - return false; - key.GetPubKey(*this, false); -#endif - return true; -} - -void static BIP32Hash(const unsigned char chainCode[32], 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); + return VerifyPubKey(vchPubKey); } bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const { @@ -625,37 +150,14 @@ bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild BIP32Hash(cc, nChild, 0, begin(), out); } memcpy(ccChild, out+32, 32); -#ifdef USE_SECP256K1 memcpy((unsigned char*)keyChild.begin(), begin(), 32); - bool ret = secp256k1_ecdsa_privkey_tweak_add((unsigned char*)keyChild.begin(), out); -#else - bool ret = CECKey::TweakSecret((unsigned char*)keyChild.begin(), begin(), out); -#endif + bool ret = secp256k1_ec_privkey_tweak_add((unsigned char*)keyChild.begin(), out); UnlockObject(out); keyChild.fCompressed = true; keyChild.fValid = ret; return ret; } -bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) 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); -#ifdef USE_SECP256K1 - pubkeyChild = *this; - bool ret = secp256k1_ecdsa_pubkey_tweak_add((unsigned char*)pubkeyChild.begin(), pubkeyChild.size(), out); -#else - CECKey key; - bool ret = key.SetPubKey(*this); - ret &= key.TweakPublic(out); - key.GetPubKey(pubkeyChild, true); -#endif - return ret; -} - bool CExtKey::Derive(CExtKey &out, unsigned int nChild) const { out.nDepth = nDepth + 1; CKeyID id = key.GetPubKey().GetID(); @@ -706,42 +208,14 @@ void CExtKey::Decode(const unsigned char code[74]) { key.Set(code+42, code+74, true); } -void CExtPubKey::Encode(unsigned char code[74]) const { - code[0] = nDepth; - 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); - assert(pubkey.size() == 33); - memcpy(code+41, pubkey.begin(), 33); -} - -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); - pubkey.Set(code+41, code+74); -} - -bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const { - out.nDepth = nDepth + 1; - CKeyID id = pubkey.GetID(); - memcpy(&out.vchFingerprint[0], &id, 4); - out.nChild = nChild; - return pubkey.Derive(out.pubkey, out.vchChainCode, nChild, vchChainCode); -} - bool ECC_InitSanityCheck() { -#ifdef USE_SECP256K1 - return true; -#else - EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1); - if(pkey == NULL) +#if !defined(USE_SECP256K1) + if (!CECKey::SanityCheck()) { return false; - EC_KEY_free(pkey); - - // TODO Is there more EC functionality that could be missing? - return true; + } #endif + CKey key; + key.MakeNewKey(true); + CPubKey pubkey = key.GetPubKey(); + return key.VerifyPubKey(pubkey); } @@ -1,227 +1,70 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_KEY_H #define BITCOIN_KEY_H #include "allocators.h" -#include "hash.h" #include "serialize.h" #include "uint256.h" #include <stdexcept> #include <vector> -// secp256k1: -// const unsigned int PRIVATE_KEY_SIZE = 279; -// const unsigned int PUBLIC_KEY_SIZE = 65; -// const unsigned int SIGNATURE_SIZE = 72; -// -// see www.keylength.com -// script supports up to 75 for single byte push +class CPubKey; -/** A reference to a CKey: the Hash160 of its serialized public key */ -class CKeyID : public uint160 -{ -public: - CKeyID() : uint160(0) {} - CKeyID(const uint160& in) : uint160(in) {} -}; - -/** A reference to a CScript: the Hash160 of its serialization (see script.h) */ -class CScriptID : public uint160 -{ -public: - CScriptID() : uint160(0) {} - CScriptID(const uint160& in) : uint160(in) {} -}; - -/** An encapsulated public key. */ -class CPubKey -{ -private: - // Just store the serialized data. - // Its length can very cheaply be computed from the first byte. - unsigned char vch[65]; - - // Compute the length of a pubkey with a given first byte. - unsigned int static GetLen(unsigned char chHeader) - { - if (chHeader == 2 || chHeader == 3) - return 33; - if (chHeader == 4 || chHeader == 6 || chHeader == 7) - return 65; - return 0; - } - - // Set this key data to be invalid - void Invalidate() - { - vch[0] = 0xFF; - } - -public: - // Construct an invalid public key. - CPubKey() - { - Invalidate(); - } - - // Initialize a public key using begin/end iterators to byte data. - template <typename T> - void Set(const T pbegin, const T pend) - { - int len = pend == pbegin ? 0 : GetLen(pbegin[0]); - if (len && len == (pend - pbegin)) - memcpy(vch, (unsigned char*)&pbegin[0], len); - else - Invalidate(); - } +struct CExtPubKey; - // Construct a public key using begin/end iterators to byte data. - template <typename T> - CPubKey(const T pbegin, const T pend) - { - Set(pbegin, pend); - } +/** + * secp256k1: + * const unsigned int PRIVATE_KEY_SIZE = 279; + * const unsigned int PUBLIC_KEY_SIZE = 65; + * const unsigned int SIGNATURE_SIZE = 72; + * + * see www.keylength.com + * script supports up to 75 for single byte push + */ - // Construct a public key from a byte vector. - CPubKey(const std::vector<unsigned char>& vch) - { - Set(vch.begin(), vch.end()); - } - - // Simple read-only vector-like interface to the pubkey data. - unsigned int size() const { return GetLen(vch[0]); } - const unsigned char* begin() const { return vch; } - const unsigned char* end() const { return vch + size(); } - const unsigned char& operator[](unsigned int pos) const { return vch[pos]; } - - // Comparator implementation. - friend bool operator==(const CPubKey& a, const CPubKey& b) - { - return a.vch[0] == b.vch[0] && - memcmp(a.vch, b.vch, a.size()) == 0; - } - friend bool operator!=(const CPubKey& a, const CPubKey& b) - { - return !(a == b); - } - friend bool operator<(const CPubKey& a, const CPubKey& b) - { - return a.vch[0] < b.vch[0] || - (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0); - } - - // Implement serialization, as if this was a byte vector. - unsigned int GetSerializeSize(int nType, int nVersion) const - { - return size() + 1; - } - template <typename Stream> - void Serialize(Stream& s, int nType, int nVersion) const - { - unsigned int len = size(); - ::WriteCompactSize(s, len); - s.write((char*)vch, len); - } - template <typename Stream> - void Unserialize(Stream& s, int nType, int nVersion) - { - unsigned int len = ::ReadCompactSize(s); - if (len <= 65) { - s.read((char*)vch, len); - } else { - // invalid pubkey, skip available data - char dummy; - while (len--) - s.read(&dummy, 1); - Invalidate(); - } - } - - // Get the KeyID of this public key (hash of its serialization) - CKeyID GetID() const - { - return CKeyID(Hash160(vch, vch + size())); - } - - // Get the 256-bit hash of this public key. - uint256 GetHash() const - { - return Hash(vch, vch + size()); - } - - // Check syntactic correctness. - // - // Note that this is consensus critical as CheckSig() calls it! - bool IsValid() const - { - return size() > 0; - } - - // fully validate whether this is a valid public key (more expensive than IsValid()) - bool IsFullyValid() const; - - // Check whether this is a compressed public key. - bool IsCompressed() const - { - return size() == 33; - } - - // Verify a DER signature (~72 bytes). - // If this public key is not fully valid, the return value will be false. - bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const; - - // Recover a public key from a compact signature. - bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig); - - // Turn this public key into an uncompressed public key. - bool Decompress(); - - // Derive BIP32 child pubkey. - bool Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const; -}; - - -// secure_allocator is defined in allocators.h -// CPrivKey is a serialized private key, with all parameters included (279 bytes) +/** + * secure_allocator is defined in allocators.h + * CPrivKey is a serialized private key, with all parameters included (279 bytes) + */ typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey; /** An encapsulated private key. */ class CKey { private: - // Whether this private key is valid. We check for correctness when modifying the key - // data, so fValid should always correspond to the actual state. + //! Whether this private key is valid. We check for correctness when modifying the key + //! data, so fValid should always correspond to the actual state. bool fValid; - // Whether the public key corresponding to this private key is (to be) compressed. + //! Whether the public key corresponding to this private key is (to be) compressed. bool fCompressed; - // The actual byte data + //! The actual byte data unsigned char vch[32]; - // Check whether the 32-byte array pointed to be vch is valid keydata. + //! Check whether the 32-byte array pointed to be vch is valid keydata. bool static Check(const unsigned char* vch); public: - // Construct an invalid private key. + //! Construct an invalid private key. CKey() : fValid(false), fCompressed(false) { LockObject(vch); } - // Copy constructor. This is necessary because of memlocking. + //! Copy constructor. This is necessary because of memlocking. CKey(const CKey& secret) : fValid(secret.fValid), fCompressed(secret.fCompressed) { LockObject(vch); memcpy(vch, secret.vch, sizeof(vch)); } - // Destructor (again necessary because of memlocking). + //! Destructor (again necessary because of memlocking). ~CKey() { UnlockObject(vch); @@ -233,7 +76,7 @@ public: memcmp(&a.vch[0], &b.vch[0], a.size()) == 0; } - // Initialize using begin and end iterators to byte data. + //! Initialize using begin and end iterators to byte data. template <typename T> void Set(const T pbegin, const T pend, bool fCompressedIn) { @@ -250,69 +93,67 @@ public: } } - // Simple read-only vector-like interface. + //! Simple read-only vector-like interface. unsigned int size() const { return (fValid ? 32 : 0); } const unsigned char* begin() const { return vch; } const unsigned char* end() const { return vch + size(); } - // Check whether this private key is valid. + //! Check whether this private key is valid. bool IsValid() const { return fValid; } - // Check whether the public key corresponding to this private key is (to be) compressed. + //! Check whether the public key corresponding to this private key is (to be) compressed. bool IsCompressed() const { return fCompressed; } - // Initialize from a CPrivKey (serialized OpenSSL private key data). + //! Initialize from a CPrivKey (serialized OpenSSL private key data). bool SetPrivKey(const CPrivKey& vchPrivKey, bool fCompressed); - // Generate a new private key using a cryptographic PRNG. + //! Generate a new private key using a cryptographic PRNG. void MakeNewKey(bool fCompressed); - // Convert the private key to a CPrivKey (serialized OpenSSL private key data). - // This is expensive. + /** + * Convert the private key to a CPrivKey (serialized OpenSSL private key data). + * This is expensive. + */ CPrivKey GetPrivKey() const; - // Compute the public key from a private key. - // This is expensive. + /** + * Compute the public key from a private key. + * This is expensive. + */ CPubKey GetPubKey() const; - // Create a DER-serialized signature. - bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig) const; - - // Create a compact signature (65 bytes), which allows reconstructing the used public key. - // The format is one header byte, followed by two times 32 bytes for the serialized r and s values. - // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, - // 0x1D = second key with even y, 0x1E = second key with odd y, - // add 0x04 for compressed keys. + /** + * Create a DER-serialized signature. + * The test_case parameter tweaks the deterministic nonce, and is only for + * testing. It should be zero for normal use. + */ + bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, uint32_t test_case = 0) const; + + /** + * Create a compact signature (65 bytes), which allows reconstructing the used public key. + * The format is one header byte, followed by two times 32 bytes for the serialized r and s values. + * The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, + * 0x1D = second key with even y, 0x1E = second key with odd y, + * add 0x04 for compressed keys. + */ bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const; - // Derive BIP32 child key. + //! Derive BIP32 child key. bool Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const; - // Load private key and check that public key matches. + /** + * Verify thoroughly whether a private key and a public key match. + * This is done using a different mechanism than just regenerating it. + */ + bool VerifyPubKey(const CPubKey& vchPubKey) const; + + //! Load private key and check that public key matches. bool Load(CPrivKey& privkey, CPubKey& vchPubKey, bool fSkipCheck); - // Check whether an element of a signature (r or s) is valid. + //! Check whether an element of a signature (r or s) is valid. static bool CheckSignatureElement(const unsigned char* vch, int len, bool half); }; -struct CExtPubKey { - unsigned char nDepth; - unsigned char vchFingerprint[4]; - unsigned int nChild; - unsigned char vchChainCode[32]; - CPubKey pubkey; - - 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; - } - - void Encode(unsigned char code[74]) const; - void Decode(const unsigned char code[74]); - bool Derive(CExtPubKey& out, unsigned int nChild) const; -}; - struct CExtKey { unsigned char nDepth; unsigned char vchFingerprint[4]; diff --git a/src/keystore.cpp b/src/keystore.cpp index 98bc0e9e28..482125a39a 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "keystore.h" @@ -8,6 +8,7 @@ #include "crypter.h" #include "key.h" #include "script/script.h" +#include "script/standard.h" #include "util.h" #include <boost/foreach.hpp> @@ -38,7 +39,7 @@ bool CBasicKeyStore::AddCScript(const CScript& redeemScript) return error("CBasicKeyStore::AddCScript() : redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE); LOCK(cs_KeyStore); - mapScripts[redeemScript.GetID()] = redeemScript; + mapScripts[CScriptID(redeemScript)] = redeemScript; return true; } @@ -67,6 +68,13 @@ bool CBasicKeyStore::AddWatchOnly(const CScript &dest) return true; } +bool CBasicKeyStore::RemoveWatchOnly(const CScript &dest) +{ + LOCK(cs_KeyStore); + setWatchOnly.erase(dest); + return true; +} + bool CBasicKeyStore::HaveWatchOnly(const CScript &dest) const { LOCK(cs_KeyStore); diff --git a/src/keystore.h b/src/keystore.h index 3b49e282d9..6655264d72 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -1,18 +1,20 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_KEYSTORE_H #define BITCOIN_KEYSTORE_H #include "key.h" +#include "pubkey.h" #include "sync.h" #include <boost/signals2/signal.hpp> #include <boost/variant.hpp> class CScript; +class CScriptID; /** A virtual base class for key stores */ class CKeyStore @@ -23,23 +25,24 @@ protected: public: virtual ~CKeyStore() {} - // Add a key to the store. + //! Add a key to the store. virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) =0; virtual bool AddKey(const CKey &key); - // Check whether a key corresponding to a given address is present in the store. + //! Check whether a key corresponding to a given address is present in the store. 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; - // Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki + //! Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki virtual bool AddCScript(const CScript& redeemScript) =0; virtual bool HaveCScript(const CScriptID &hash) const =0; virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0; - // Support for Watch-only addresses + //! Support for Watch-only addresses virtual bool AddWatchOnly(const CScript &dest) =0; + virtual bool RemoveWatchOnly(const CScript &dest) =0; virtual bool HaveWatchOnly(const CScript &dest) const =0; virtual bool HaveWatchOnly() const =0; }; @@ -98,6 +101,7 @@ public: virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const; virtual bool AddWatchOnly(const CScript &dest); + virtual bool RemoveWatchOnly(const CScript &dest); virtual bool HaveWatchOnly(const CScript &dest) const; virtual bool HaveWatchOnly() const; }; diff --git a/src/leveldb/CONTRIBUTING.md b/src/leveldb/CONTRIBUTING.md new file mode 100644 index 0000000000..cd600ff46b --- /dev/null +++ b/src/leveldb/CONTRIBUTING.md @@ -0,0 +1,36 @@ +# Contributing + +We'd love to accept your code patches! However, before we can take them, we +have to jump a couple of legal hurdles. + +## Contributor License Agreements + +Please fill out either the individual or corporate Contributor License +Agreement as appropriate. + +* If you are an individual writing original source code and you're sure you +own the intellectual property, then sign an [individual CLA](https://developers.google.com/open-source/cla/individual). +* If you work for a company that wants to allow you to contribute your work, +then sign a [corporate CLA](https://developers.google.com/open-source/cla/corporate). + +Follow either of the two links above to access the appropriate CLA and +instructions for how to sign and return it. + +## Submitting a Patch + +1. Sign the contributors license agreement above. +2. Decide which code you want to submit. A submission should be a set of changes +that addresses one issue in the [issue tracker](https://github.com/google/leveldb/issues). +Please don't mix more than one logical change per submission, because it makes +the history hard to follow. If you want to make a change +(e.g. add a sample or feature) that doesn't have a corresponding issue in the +issue tracker, please create one. +3. **Submitting**: When you are ready to submit, send us a Pull Request. Be +sure to include the issue number you fixed and the name you used to sign +the CLA. + +## Writing Code ## + +If your contribution contains code, please make sure that it follows +[the style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml). +Otherwise we will have to ask you to make changes, and that's no fun for anyone. diff --git a/src/leveldb/Makefile b/src/leveldb/Makefile index f8903b69e4..2bd2cadcdd 100644 --- a/src/leveldb/Makefile +++ b/src/leveldb/Makefile @@ -6,9 +6,12 @@ # Uncomment exactly one of the lines labelled (A), (B), and (C) below # to switch between compilation modes. -OPT ?= -O2 -DNDEBUG # (A) Production use (optimized mode) -# OPT ?= -g2 # (B) Debug mode, w/ full line-level debugging symbols -# OPT ?= -O2 -g2 -DNDEBUG # (C) Profiling mode: opt, but w/debugging symbols +# (A) Production use (optimized mode) +OPT ?= -O2 -DNDEBUG +# (B) Debug mode, w/ full line-level debugging symbols +# OPT ?= -g2 +# (C) Profiling mode: opt, but w/debugging symbols +# OPT ?= -O2 -g2 -DNDEBUG #----------------------------------------------- # detect what platform we're building on @@ -29,6 +32,11 @@ MEMENVOBJECTS = $(MEMENV_SOURCES:.cc=.o) TESTUTIL = ./util/testutil.o TESTHARNESS = ./util/testharness.o $(TESTUTIL) +# Note: iOS should probably be using libtool, not ar. +ifeq ($(PLATFORM), IOS) +AR=xcrun ar +endif + TESTS = \ arena_test \ autocompact_test \ @@ -43,6 +51,7 @@ TESTS = \ env_test \ filename_test \ filter_block_test \ + hash_test \ issue178_test \ issue200_test \ log_test \ @@ -72,7 +81,7 @@ SHARED = $(SHARED1) else # Update db.h if you change these. SHARED_MAJOR = 1 -SHARED_MINOR = 17 +SHARED_MINOR = 18 SHARED1 = libleveldb.$(PLATFORM_SHARED_EXT) SHARED2 = $(SHARED1).$(SHARED_MAJOR) SHARED3 = $(SHARED1).$(SHARED_MAJOR).$(SHARED_MINOR) @@ -152,6 +161,9 @@ filename_test: db/filename_test.o $(LIBOBJECTS) $(TESTHARNESS) filter_block_test: table/filter_block_test.o $(LIBOBJECTS) $(TESTHARNESS) $(CXX) $(LDFLAGS) table/filter_block_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) +hash_test: util/hash_test.o $(LIBOBJECTS) $(TESTHARNESS) + $(CXX) $(LDFLAGS) util/hash_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) + issue178_test: issues/issue178_test.o $(LIBOBJECTS) $(TESTHARNESS) $(CXX) $(LDFLAGS) issues/issue178_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) @@ -194,17 +206,17 @@ IOSARCH=-arch armv6 -arch armv7 -arch armv7s -arch arm64 .cc.o: mkdir -p ios-x86/$(dir $@) - $(CXX) $(CXXFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -arch x86_64 -c $< -o ios-x86/$@ + xcrun -sdk iphonesimulator $(CXX) $(CXXFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -arch x86_64 -c $< -o ios-x86/$@ mkdir -p ios-arm/$(dir $@) xcrun -sdk iphoneos $(CXX) $(CXXFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk $(IOSARCH) -c $< -o ios-arm/$@ - lipo ios-x86/$@ ios-arm/$@ -create -output $@ + xcrun lipo ios-x86/$@ ios-arm/$@ -create -output $@ .c.o: mkdir -p ios-x86/$(dir $@) - $(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -arch x86_64 -c $< -o ios-x86/$@ + xcrun -sdk iphonesimulator $(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -arch x86_64 -c $< -o ios-x86/$@ mkdir -p ios-arm/$(dir $@) xcrun -sdk iphoneos $(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk $(IOSARCH) -c $< -o ios-arm/$@ - lipo ios-x86/$@ ios-arm/$@ -create -output $@ + xcrun lipo ios-x86/$@ ios-arm/$@ -create -output $@ else .cc.o: diff --git a/src/leveldb/README.md b/src/leveldb/README.md new file mode 100644 index 0000000000..480affb5ca --- /dev/null +++ b/src/leveldb/README.md @@ -0,0 +1,138 @@ +**LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.** + +Authors: Sanjay Ghemawat (sanjay@google.com) and Jeff Dean (jeff@google.com) + +# Features + * Keys and values are arbitrary byte arrays. + * Data is stored sorted by key. + * Callers can provide a custom comparison function to override the sort order. + * The basic operations are `Put(key,value)`, `Get(key)`, `Delete(key)`. + * Multiple changes can be made in one atomic batch. + * Users can create a transient snapshot to get a consistent view of data. + * Forward and backward iteration is supported over the data. + * Data is automatically compressed using the [Snappy compression library](http://code.google.com/p/snappy). + * External activity (file system operations etc.) is relayed through a virtual interface so users can customize the operating system interactions. + * [Detailed documentation](http://htmlpreview.github.io/?https://github.com/google/leveldb/blob/master/doc/index.html) about how to use the library is included with the source code. + + +# Limitations + * This is not a SQL database. It does not have a relational data model, it does not support SQL queries, and it has no support for indexes. + * Only a single process (possibly multi-threaded) can access a particular database at a time. + * There is no client-server support builtin to the library. An application that needs such support will have to wrap their own server around the library. + +# Performance + +Here is a performance report (with explanations) from the run of the +included db_bench program. The results are somewhat noisy, but should +be enough to get a ballpark performance estimate. + +## Setup + +We use a database with a million entries. Each entry has a 16 byte +key, and a 100 byte value. Values used by the benchmark compress to +about half their original size. + + LevelDB: version 1.1 + Date: Sun May 1 12:11:26 2011 + CPU: 4 x Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz + CPUCache: 4096 KB + Keys: 16 bytes each + Values: 100 bytes each (50 bytes after compression) + Entries: 1000000 + Raw Size: 110.6 MB (estimated) + File Size: 62.9 MB (estimated) + +## Write performance + +The "fill" benchmarks create a brand new database, in either +sequential, or random order. The "fillsync" benchmark flushes data +from the operating system to the disk after every operation; the other +write operations leave the data sitting in the operating system buffer +cache for a while. The "overwrite" benchmark does random writes that +update existing keys in the database. + + fillseq : 1.765 micros/op; 62.7 MB/s + fillsync : 268.409 micros/op; 0.4 MB/s (10000 ops) + fillrandom : 2.460 micros/op; 45.0 MB/s + overwrite : 2.380 micros/op; 46.5 MB/s + +Each "op" above corresponds to a write of a single key/value pair. +I.e., a random write benchmark goes at approximately 400,000 writes per second. + +Each "fillsync" operation costs much less (0.3 millisecond) +than a disk seek (typically 10 milliseconds). We suspect that this is +because the hard disk itself is buffering the update in its memory and +responding before the data has been written to the platter. This may +or may not be safe based on whether or not the hard disk has enough +power to save its memory in the event of a power failure. + +## Read performance + +We list the performance of reading sequentially in both the forward +and reverse direction, and also the performance of a random lookup. +Note that the database created by the benchmark is quite small. +Therefore the report characterizes the performance of leveldb when the +working set fits in memory. The cost of reading a piece of data that +is not present in the operating system buffer cache will be dominated +by the one or two disk seeks needed to fetch the data from disk. +Write performance will be mostly unaffected by whether or not the +working set fits in memory. + + readrandom : 16.677 micros/op; (approximately 60,000 reads per second) + readseq : 0.476 micros/op; 232.3 MB/s + readreverse : 0.724 micros/op; 152.9 MB/s + +LevelDB compacts its underlying storage data in the background to +improve read performance. The results listed above were done +immediately after a lot of random writes. The results after +compactions (which are usually triggered automatically) are better. + + readrandom : 11.602 micros/op; (approximately 85,000 reads per second) + readseq : 0.423 micros/op; 261.8 MB/s + readreverse : 0.663 micros/op; 166.9 MB/s + +Some of the high cost of reads comes from repeated decompression of blocks +read from disk. If we supply enough cache to the leveldb so it can hold the +uncompressed blocks in memory, the read performance improves again: + + readrandom : 9.775 micros/op; (approximately 100,000 reads per second before compaction) + readrandom : 5.215 micros/op; (approximately 190,000 reads per second after compaction) + +## Repository contents + +See doc/index.html for more explanation. See doc/impl.html for a brief overview of the implementation. + +The public interface is in include/*.h. Callers should not include or +rely on the details of any other header files in this package. Those +internal APIs may be changed without warning. + +Guide to header files: + +* **include/db.h**: Main interface to the DB: Start here + +* **include/options.h**: Control over the behavior of an entire database, +and also control over the behavior of individual reads and writes. + +* **include/comparator.h**: Abstraction for user-specified comparison function. +If you want just bytewise comparison of keys, you can use the default +comparator, but clients can write their own comparator implementations if they +want custom ordering (e.g. to handle different character encodings, etc.) + +* **include/iterator.h**: Interface for iterating over data. You can get +an iterator from a DB object. + +* **include/write_batch.h**: Interface for atomically applying multiple +updates to a database. + +* **include/slice.h**: A simple module for maintaining a pointer and a +length into some other byte array. + +* **include/status.h**: Status is returned from many of the public interfaces +and is used to report success and various kinds of errors. + +* **include/env.h**: +Abstraction of the OS environment. A posix implementation of this interface is +in util/env_posix.cc + +* **include/table.h, include/table_builder.h**: Lower-level modules that most +clients probably won't use directly diff --git a/src/leveldb/build_detect_platform b/src/leveldb/build_detect_platform index 85b1ce0224..a1101c1bda 100755 --- a/src/leveldb/build_detect_platform +++ b/src/leveldb/build_detect_platform @@ -20,7 +20,7 @@ # # The PLATFORM_CCFLAGS and PLATFORM_CXXFLAGS might include the following: # -# -DLEVELDB_CSTDATOMIC_PRESENT if <cstdatomic> is present +# -DLEVELDB_ATOMIC_PRESENT if <atomic> is present # -DLEVELDB_PLATFORM_POSIX for Posix-based platforms # -DSNAPPY if the Snappy library is present # @@ -72,6 +72,12 @@ if [ "$CXX" = "g++" ]; then fi case "$TARGET_OS" in + CYGWIN_*) + PLATFORM=OS_LINUX + COMMON_FLAGS="$MEMCMP_FLAG -lpthread -DOS_LINUX -DCYGWIN" + PLATFORM_LDFLAGS="-lpthread" + PORT_FILE=port/port_posix.cc + ;; Darwin) PLATFORM=OS_MACOSX COMMON_FLAGS="$MEMCMP_FLAG -DOS_MACOSX" @@ -185,13 +191,14 @@ if [ "$CROSS_COMPILE" = "true" ]; then else CXXOUTPUT="${TMPDIR}/leveldb_build_detect_platform-cxx.$$" - # If -std=c++0x works, use <cstdatomic>. Otherwise use port_posix.h. + # If -std=c++0x works, use <atomic> as fallback for when memory barriers + # are not available. $CXX $CXXFLAGS -std=c++0x -x c++ - -o $CXXOUTPUT 2>/dev/null <<EOF - #include <cstdatomic> + #include <atomic> int main() {} EOF if [ "$?" = 0 ]; then - COMMON_FLAGS="$COMMON_FLAGS -DLEVELDB_PLATFORM_POSIX -DLEVELDB_CSTDATOMIC_PRESENT" + COMMON_FLAGS="$COMMON_FLAGS -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT" PLATFORM_CXXFLAGS="-std=c++0x" else COMMON_FLAGS="$COMMON_FLAGS -DLEVELDB_PLATFORM_POSIX" diff --git a/src/leveldb/db/db_bench.cc b/src/leveldb/db/db_bench.cc index fc46d89693..705a170aae 100644 --- a/src/leveldb/db/db_bench.cc +++ b/src/leveldb/db/db_bench.cc @@ -431,7 +431,7 @@ class Benchmark { benchmarks = sep + 1; } - // Reset parameters that may be overriddden bwlow + // Reset parameters that may be overridden below num_ = FLAGS_num; reads_ = (FLAGS_reads < 0 ? FLAGS_num : FLAGS_reads); value_size_ = FLAGS_value_size; @@ -811,7 +811,6 @@ class Benchmark { void SeekRandom(ThreadState* thread) { ReadOptions options; - std::string value; int found = 0; for (int i = 0; i < reads_; i++) { Iterator* iter = db_->NewIterator(options); diff --git a/src/leveldb/db/db_impl.cc b/src/leveldb/db/db_impl.cc index faf5e7d7ba..49b95953b4 100644 --- a/src/leveldb/db/db_impl.cc +++ b/src/leveldb/db/db_impl.cc @@ -392,7 +392,7 @@ Status DBImpl::RecoverLogFile(uint64_t log_number, reporter.info_log = options_.info_log; reporter.fname = fname.c_str(); reporter.status = (options_.paranoid_checks ? &status : NULL); - // We intentially make log::Reader do checksumming even if + // We intentionally make log::Reader do checksumming even if // paranoid_checks==false so that corruptions cause entire commits // to be skipped instead of propagating bad information (like overly // large sequence numbers). @@ -1267,7 +1267,7 @@ WriteBatch* DBImpl::BuildBatchGroup(Writer** last_writer) { break; } - // Append to *reuslt + // Append to *result if (result == first->batch) { // Switch to temporary batch instead of disturbing caller's batch result = tmp_batch_; diff --git a/src/leveldb/db/db_test.cc b/src/leveldb/db/db_test.cc index 280b01c14b..0fed9137d5 100644 --- a/src/leveldb/db/db_test.cc +++ b/src/leveldb/db/db_test.cc @@ -626,7 +626,7 @@ TEST(DBTest, GetEncountersEmptyLevel) { // * sstable B in level 2 // Then do enough Get() calls to arrange for an automatic compaction // of sstable A. A bug would cause the compaction to be marked as - // occuring at level 1 (instead of the correct level 0). + // occurring at level 1 (instead of the correct level 0). // Step 1: First place sstables in levels 0 and 2 int compaction_count = 0; diff --git a/src/leveldb/db/dbformat.h b/src/leveldb/db/dbformat.h index 5d8a032bd3..ea897b13c0 100644 --- a/src/leveldb/db/dbformat.h +++ b/src/leveldb/db/dbformat.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors. -#ifndef STORAGE_LEVELDB_DB_FORMAT_H_ -#define STORAGE_LEVELDB_DB_FORMAT_H_ +#ifndef STORAGE_LEVELDB_DB_DBFORMAT_H_ +#define STORAGE_LEVELDB_DB_DBFORMAT_H_ #include <stdio.h> #include "leveldb/comparator.h" @@ -227,4 +227,4 @@ inline LookupKey::~LookupKey() { } // namespace leveldb -#endif // STORAGE_LEVELDB_DB_FORMAT_H_ +#endif // STORAGE_LEVELDB_DB_DBFORMAT_H_ diff --git a/src/leveldb/db/dumpfile.cc b/src/leveldb/db/dumpfile.cc new file mode 100644 index 0000000000..61c47c2ff9 --- /dev/null +++ b/src/leveldb/db/dumpfile.cc @@ -0,0 +1,225 @@ +// Copyright (c) 2012 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include <stdio.h> +#include "db/dbformat.h" +#include "db/filename.h" +#include "db/log_reader.h" +#include "db/version_edit.h" +#include "db/write_batch_internal.h" +#include "leveldb/env.h" +#include "leveldb/iterator.h" +#include "leveldb/options.h" +#include "leveldb/status.h" +#include "leveldb/table.h" +#include "leveldb/write_batch.h" +#include "util/logging.h" + +namespace leveldb { + +namespace { + +bool GuessType(const std::string& fname, FileType* type) { + size_t pos = fname.rfind('/'); + std::string basename; + if (pos == std::string::npos) { + basename = fname; + } else { + basename = std::string(fname.data() + pos + 1, fname.size() - pos - 1); + } + uint64_t ignored; + return ParseFileName(basename, &ignored, type); +} + +// Notified when log reader encounters corruption. +class CorruptionReporter : public log::Reader::Reporter { + public: + WritableFile* dst_; + virtual void Corruption(size_t bytes, const Status& status) { + std::string r = "corruption: "; + AppendNumberTo(&r, bytes); + r += " bytes; "; + r += status.ToString(); + r.push_back('\n'); + dst_->Append(r); + } +}; + +// Print contents of a log file. (*func)() is called on every record. +Status PrintLogContents(Env* env, const std::string& fname, + void (*func)(uint64_t, Slice, WritableFile*), + WritableFile* dst) { + SequentialFile* file; + Status s = env->NewSequentialFile(fname, &file); + if (!s.ok()) { + return s; + } + CorruptionReporter reporter; + reporter.dst_ = dst; + log::Reader reader(file, &reporter, true, 0); + Slice record; + std::string scratch; + while (reader.ReadRecord(&record, &scratch)) { + (*func)(reader.LastRecordOffset(), record, dst); + } + delete file; + return Status::OK(); +} + +// Called on every item found in a WriteBatch. +class WriteBatchItemPrinter : public WriteBatch::Handler { + public: + WritableFile* dst_; + virtual void Put(const Slice& key, const Slice& value) { + std::string r = " put '"; + AppendEscapedStringTo(&r, key); + r += "' '"; + AppendEscapedStringTo(&r, value); + r += "'\n"; + dst_->Append(r); + } + virtual void Delete(const Slice& key) { + std::string r = " del '"; + AppendEscapedStringTo(&r, key); + r += "'\n"; + dst_->Append(r); + } +}; + + +// Called on every log record (each one of which is a WriteBatch) +// found in a kLogFile. +static void WriteBatchPrinter(uint64_t pos, Slice record, WritableFile* dst) { + std::string r = "--- offset "; + AppendNumberTo(&r, pos); + r += "; "; + if (record.size() < 12) { + r += "log record length "; + AppendNumberTo(&r, record.size()); + r += " is too small\n"; + dst->Append(r); + return; + } + WriteBatch batch; + WriteBatchInternal::SetContents(&batch, record); + r += "sequence "; + AppendNumberTo(&r, WriteBatchInternal::Sequence(&batch)); + r.push_back('\n'); + dst->Append(r); + WriteBatchItemPrinter batch_item_printer; + batch_item_printer.dst_ = dst; + Status s = batch.Iterate(&batch_item_printer); + if (!s.ok()) { + dst->Append(" error: " + s.ToString() + "\n"); + } +} + +Status DumpLog(Env* env, const std::string& fname, WritableFile* dst) { + return PrintLogContents(env, fname, WriteBatchPrinter, dst); +} + +// Called on every log record (each one of which is a WriteBatch) +// found in a kDescriptorFile. +static void VersionEditPrinter(uint64_t pos, Slice record, WritableFile* dst) { + std::string r = "--- offset "; + AppendNumberTo(&r, pos); + r += "; "; + VersionEdit edit; + Status s = edit.DecodeFrom(record); + if (!s.ok()) { + r += s.ToString(); + r.push_back('\n'); + } else { + r += edit.DebugString(); + } + dst->Append(r); +} + +Status DumpDescriptor(Env* env, const std::string& fname, WritableFile* dst) { + return PrintLogContents(env, fname, VersionEditPrinter, dst); +} + +Status DumpTable(Env* env, const std::string& fname, WritableFile* dst) { + uint64_t file_size; + RandomAccessFile* file = NULL; + Table* table = NULL; + Status s = env->GetFileSize(fname, &file_size); + if (s.ok()) { + s = env->NewRandomAccessFile(fname, &file); + } + if (s.ok()) { + // We use the default comparator, which may or may not match the + // comparator used in this database. However this should not cause + // problems since we only use Table operations that do not require + // any comparisons. In particular, we do not call Seek or Prev. + s = Table::Open(Options(), file, file_size, &table); + } + if (!s.ok()) { + delete table; + delete file; + return s; + } + + ReadOptions ro; + ro.fill_cache = false; + Iterator* iter = table->NewIterator(ro); + std::string r; + for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { + r.clear(); + ParsedInternalKey key; + if (!ParseInternalKey(iter->key(), &key)) { + r = "badkey '"; + AppendEscapedStringTo(&r, iter->key()); + r += "' => '"; + AppendEscapedStringTo(&r, iter->value()); + r += "'\n"; + dst->Append(r); + } else { + r = "'"; + AppendEscapedStringTo(&r, key.user_key); + r += "' @ "; + AppendNumberTo(&r, key.sequence); + r += " : "; + if (key.type == kTypeDeletion) { + r += "del"; + } else if (key.type == kTypeValue) { + r += "val"; + } else { + AppendNumberTo(&r, key.type); + } + r += " => '"; + AppendEscapedStringTo(&r, iter->value()); + r += "'\n"; + dst->Append(r); + } + } + s = iter->status(); + if (!s.ok()) { + dst->Append("iterator error: " + s.ToString() + "\n"); + } + + delete iter; + delete table; + delete file; + return Status::OK(); +} + +} // namespace + +Status DumpFile(Env* env, const std::string& fname, WritableFile* dst) { + FileType ftype; + if (!GuessType(fname, &ftype)) { + return Status::InvalidArgument(fname + ": unknown file type"); + } + switch (ftype) { + case kLogFile: return DumpLog(env, fname, dst); + case kDescriptorFile: return DumpDescriptor(env, fname, dst); + case kTableFile: return DumpTable(env, fname, dst); + default: + break; + } + return Status::InvalidArgument(fname + ": not a dump-able file type"); +} + +} // namespace leveldb diff --git a/src/leveldb/db/leveldb_main.cc b/src/leveldb/db/leveldb_main.cc index 995d76107a..9f4b7dd70c 100644 --- a/src/leveldb/db/leveldb_main.cc +++ b/src/leveldb/db/leveldb_main.cc @@ -3,212 +3,38 @@ // found in the LICENSE file. See the AUTHORS file for names of contributors. #include <stdio.h> -#include "db/dbformat.h" -#include "db/filename.h" -#include "db/log_reader.h" -#include "db/version_edit.h" -#include "db/write_batch_internal.h" +#include "leveldb/dumpfile.h" #include "leveldb/env.h" -#include "leveldb/iterator.h" -#include "leveldb/options.h" #include "leveldb/status.h" -#include "leveldb/table.h" -#include "leveldb/write_batch.h" -#include "util/logging.h" namespace leveldb { - namespace { -bool GuessType(const std::string& fname, FileType* type) { - size_t pos = fname.rfind('/'); - std::string basename; - if (pos == std::string::npos) { - basename = fname; - } else { - basename = std::string(fname.data() + pos + 1, fname.size() - pos - 1); - } - uint64_t ignored; - return ParseFileName(basename, &ignored, type); -} - -// Notified when log reader encounters corruption. -class CorruptionReporter : public log::Reader::Reporter { - public: - virtual void Corruption(size_t bytes, const Status& status) { - printf("corruption: %d bytes; %s\n", - static_cast<int>(bytes), - status.ToString().c_str()); - } -}; - -// Print contents of a log file. (*func)() is called on every record. -bool PrintLogContents(Env* env, const std::string& fname, - void (*func)(Slice)) { - SequentialFile* file; - Status s = env->NewSequentialFile(fname, &file); - if (!s.ok()) { - fprintf(stderr, "%s\n", s.ToString().c_str()); - return false; - } - CorruptionReporter reporter; - log::Reader reader(file, &reporter, true, 0); - Slice record; - std::string scratch; - while (reader.ReadRecord(&record, &scratch)) { - printf("--- offset %llu; ", - static_cast<unsigned long long>(reader.LastRecordOffset())); - (*func)(record); - } - delete file; - return true; -} - -// Called on every item found in a WriteBatch. -class WriteBatchItemPrinter : public WriteBatch::Handler { +class StdoutPrinter : public WritableFile { public: - uint64_t offset_; - uint64_t sequence_; - - virtual void Put(const Slice& key, const Slice& value) { - printf(" put '%s' '%s'\n", - EscapeString(key).c_str(), - EscapeString(value).c_str()); - } - virtual void Delete(const Slice& key) { - printf(" del '%s'\n", - EscapeString(key).c_str()); + virtual Status Append(const Slice& data) { + fwrite(data.data(), 1, data.size(), stdout); + return Status::OK(); } + virtual Status Close() { return Status::OK(); } + virtual Status Flush() { return Status::OK(); } + virtual Status Sync() { return Status::OK(); } }; - -// Called on every log record (each one of which is a WriteBatch) -// found in a kLogFile. -static void WriteBatchPrinter(Slice record) { - if (record.size() < 12) { - printf("log record length %d is too small\n", - static_cast<int>(record.size())); - return; - } - WriteBatch batch; - WriteBatchInternal::SetContents(&batch, record); - printf("sequence %llu\n", - static_cast<unsigned long long>(WriteBatchInternal::Sequence(&batch))); - WriteBatchItemPrinter batch_item_printer; - Status s = batch.Iterate(&batch_item_printer); - if (!s.ok()) { - printf(" error: %s\n", s.ToString().c_str()); - } -} - -bool DumpLog(Env* env, const std::string& fname) { - return PrintLogContents(env, fname, WriteBatchPrinter); -} - -// Called on every log record (each one of which is a WriteBatch) -// found in a kDescriptorFile. -static void VersionEditPrinter(Slice record) { - VersionEdit edit; - Status s = edit.DecodeFrom(record); - if (!s.ok()) { - printf("%s\n", s.ToString().c_str()); - return; - } - printf("%s", edit.DebugString().c_str()); -} - -bool DumpDescriptor(Env* env, const std::string& fname) { - return PrintLogContents(env, fname, VersionEditPrinter); -} - -bool DumpTable(Env* env, const std::string& fname) { - uint64_t file_size; - RandomAccessFile* file = NULL; - Table* table = NULL; - Status s = env->GetFileSize(fname, &file_size); - if (s.ok()) { - s = env->NewRandomAccessFile(fname, &file); - } - if (s.ok()) { - // We use the default comparator, which may or may not match the - // comparator used in this database. However this should not cause - // problems since we only use Table operations that do not require - // any comparisons. In particular, we do not call Seek or Prev. - s = Table::Open(Options(), file, file_size, &table); - } - if (!s.ok()) { - fprintf(stderr, "%s\n", s.ToString().c_str()); - delete table; - delete file; - return false; - } - - ReadOptions ro; - ro.fill_cache = false; - Iterator* iter = table->NewIterator(ro); - for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { - ParsedInternalKey key; - if (!ParseInternalKey(iter->key(), &key)) { - printf("badkey '%s' => '%s'\n", - EscapeString(iter->key()).c_str(), - EscapeString(iter->value()).c_str()); - } else { - char kbuf[20]; - const char* type; - if (key.type == kTypeDeletion) { - type = "del"; - } else if (key.type == kTypeValue) { - type = "val"; - } else { - snprintf(kbuf, sizeof(kbuf), "%d", static_cast<int>(key.type)); - type = kbuf; - } - printf("'%s' @ %8llu : %s => '%s'\n", - EscapeString(key.user_key).c_str(), - static_cast<unsigned long long>(key.sequence), - type, - EscapeString(iter->value()).c_str()); - } - } - s = iter->status(); - if (!s.ok()) { - printf("iterator error: %s\n", s.ToString().c_str()); - } - - delete iter; - delete table; - delete file; - return true; -} - -bool DumpFile(Env* env, const std::string& fname) { - FileType ftype; - if (!GuessType(fname, &ftype)) { - fprintf(stderr, "%s: unknown file type\n", fname.c_str()); - return false; - } - switch (ftype) { - case kLogFile: return DumpLog(env, fname); - case kDescriptorFile: return DumpDescriptor(env, fname); - case kTableFile: return DumpTable(env, fname); - - default: { - fprintf(stderr, "%s: not a dump-able file type\n", fname.c_str()); - break; - } - } - return false; -} - bool HandleDumpCommand(Env* env, char** files, int num) { + StdoutPrinter printer; bool ok = true; for (int i = 0; i < num; i++) { - ok &= DumpFile(env, files[i]); + Status s = DumpFile(env, files[i], &printer); + if (!s.ok()) { + fprintf(stderr, "%s\n", s.ToString().c_str()); + ok = false; + } } return ok; } -} +} // namespace } // namespace leveldb static void Usage() { diff --git a/src/leveldb/db/log_format.h b/src/leveldb/db/log_format.h index 2690cb9789..a8c06efe18 100644 --- a/src/leveldb/db/log_format.h +++ b/src/leveldb/db/log_format.h @@ -26,8 +26,8 @@ static const int kMaxRecordType = kLastType; static const int kBlockSize = 32768; -// Header is checksum (4 bytes), type (1 byte), length (2 bytes). -static const int kHeaderSize = 4 + 1 + 2; +// Header is checksum (4 bytes), length (2 bytes), type (1 byte). +static const int kHeaderSize = 4 + 2 + 1; } // namespace log } // namespace leveldb diff --git a/src/leveldb/db/log_reader.cc b/src/leveldb/db/log_reader.cc index 4919216d04..e44b66c85b 100644 --- a/src/leveldb/db/log_reader.cc +++ b/src/leveldb/db/log_reader.cc @@ -167,14 +167,14 @@ uint64_t Reader::LastRecordOffset() { return last_record_offset_; } -void Reader::ReportCorruption(size_t bytes, const char* reason) { +void Reader::ReportCorruption(uint64_t bytes, const char* reason) { ReportDrop(bytes, Status::Corruption(reason)); } -void Reader::ReportDrop(size_t bytes, const Status& reason) { +void Reader::ReportDrop(uint64_t bytes, const Status& reason) { if (reporter_ != NULL && end_of_buffer_offset_ - buffer_.size() - bytes >= initial_offset_) { - reporter_->Corruption(bytes, reason); + reporter_->Corruption(static_cast<size_t>(bytes), reason); } } diff --git a/src/leveldb/db/log_reader.h b/src/leveldb/db/log_reader.h index 82d4bee68d..6aff791716 100644 --- a/src/leveldb/db/log_reader.h +++ b/src/leveldb/db/log_reader.h @@ -94,8 +94,8 @@ class Reader { // Reports dropped bytes to the reporter. // buffer_ must be updated to remove the dropped bytes prior to invocation. - void ReportCorruption(size_t bytes, const char* reason); - void ReportDrop(size_t bytes, const Status& reason); + void ReportCorruption(uint64_t bytes, const char* reason); + void ReportDrop(uint64_t bytes, const Status& reason); // No copying allowed Reader(const Reader&); diff --git a/src/leveldb/db/log_test.cc b/src/leveldb/db/log_test.cc index 91d3caafc3..dcf0562652 100644 --- a/src/leveldb/db/log_test.cc +++ b/src/leveldb/db/log_test.cc @@ -463,7 +463,7 @@ TEST(LogTest, ErrorJoinsRecords) { ASSERT_EQ("correct", Read()); ASSERT_EQ("EOF", Read()); - const int dropped = DroppedBytes(); + const size_t dropped = DroppedBytes(); ASSERT_LE(dropped, 2*kBlockSize + 100); ASSERT_GE(dropped, 2*kBlockSize); } diff --git a/src/leveldb/db/repair.cc b/src/leveldb/db/repair.cc index 7727fafc58..4cd4bb047f 100644 --- a/src/leveldb/db/repair.cc +++ b/src/leveldb/db/repair.cc @@ -186,7 +186,7 @@ class Repairer { reporter.env = env_; reporter.info_log = options_.info_log; reporter.lognum = log; - // We intentially make log::Reader do checksumming so that + // We intentionally make log::Reader do checksumming so that // corruptions cause entire commits to be skipped instead of // propagating bad information (like overly large sequence // numbers). diff --git a/src/leveldb/db/skiplist.h b/src/leveldb/db/skiplist.h index af85be6d01..ed8b092203 100644 --- a/src/leveldb/db/skiplist.h +++ b/src/leveldb/db/skiplist.h @@ -1,3 +1,6 @@ +#ifndef STORAGE_LEVELDB_DB_SKIPLIST_H_ +#define STORAGE_LEVELDB_DB_SKIPLIST_H_ + // Copyright (c) 2011 The LevelDB Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors. @@ -377,3 +380,5 @@ bool SkipList<Key,Comparator>::Contains(const Key& key) const { } } // namespace leveldb + +#endif // STORAGE_LEVELDB_DB_SKIPLIST_H_ diff --git a/src/leveldb/db/write_batch_internal.h b/src/leveldb/db/write_batch_internal.h index 4423a7f318..310a3c8912 100644 --- a/src/leveldb/db/write_batch_internal.h +++ b/src/leveldb/db/write_batch_internal.h @@ -21,10 +21,10 @@ class WriteBatchInternal { // Set the count for the number of entries in the batch. static void SetCount(WriteBatch* batch, int n); - // Return the seqeunce number for the start of this batch. + // Return the sequence number for the start of this batch. static SequenceNumber Sequence(const WriteBatch* batch); - // Store the specified number as the seqeunce number for the start of + // Store the specified number as the sequence number for the start of // this batch. static void SetSequence(WriteBatch* batch, SequenceNumber seq); diff --git a/src/leveldb/doc/bench/db_bench_tree_db.cc b/src/leveldb/doc/bench/db_bench_tree_db.cc index ed86f031c2..4ca381f11f 100644 --- a/src/leveldb/doc/bench/db_bench_tree_db.cc +++ b/src/leveldb/doc/bench/db_bench_tree_db.cc @@ -338,7 +338,7 @@ class Benchmark { bool write_sync = false; if (name == Slice("fillseq")) { Write(write_sync, SEQUENTIAL, FRESH, num_, FLAGS_value_size, 1); - + DBSynchronize(db_); } else if (name == Slice("fillrandom")) { Write(write_sync, RANDOM, FRESH, num_, FLAGS_value_size, 1); DBSynchronize(db_); diff --git a/src/leveldb/doc/impl.html b/src/leveldb/doc/impl.html index 28817fe0da..6a468be095 100644 --- a/src/leveldb/doc/impl.html +++ b/src/leveldb/doc/impl.html @@ -111,7 +111,7 @@ A compaction merges the contents of the picked files to produce a sequence of level-(L+1) files. We switch to producing a new level-(L+1) file after the current output file has reached the target file size (2MB). We also switch to a new output file when the key -range of the current output file has grown enough to overlap more then +range of the current output file has grown enough to overlap more than ten level-(L+2) files. This last rule ensures that a later compaction of a level-(L+1) file will not pick up too much data from level-(L+2). @@ -151,7 +151,7 @@ compaction cost will be approximately 0.5 second. If we throttle the background writing to something small, say 10% of the full 100MB/s speed, a compaction may take up to 5 seconds. If the user is writing at 10MB/s, we might build up lots of level-0 files -(~50 to hold the 5*10MB). This may signficantly increase the cost of +(~50 to hold the 5*10MB). This may significantly increase the cost of reads due to the overhead of merging more files together on every read. diff --git a/src/leveldb/doc/log_format.txt b/src/leveldb/doc/log_format.txt index 5228f624de..4cca5ef6ea 100644 --- a/src/leveldb/doc/log_format.txt +++ b/src/leveldb/doc/log_format.txt @@ -11,7 +11,7 @@ Each block consists of a sequence of records: A record never starts within the last six bytes of a block (since it won't fit). Any leftover bytes here form the trailer, which must -consist entirely of zero bytes and must be skipped by readers. +consist entirely of zero bytes and must be skipped by readers. Aside: if exactly seven bytes are left in the current block, and a new non-zero length record is added, the writer must emit a FIRST record @@ -33,8 +33,8 @@ The FULL record contains the contents of an entire user record. FIRST, MIDDLE, LAST are types used for user records that have been split into multiple fragments (typically because of block boundaries). FIRST is the type of the first fragment of a user record, LAST is the -type of the last fragment of a user record, and MID is the type of all -interior fragments of a user record. +type of the last fragment of a user record, and MIDDLE is the type of +all interior fragments of a user record. Example: consider a sequence of user records: A: length 1000 diff --git a/src/leveldb/helpers/memenv/memenv.cc b/src/leveldb/helpers/memenv/memenv.cc index 5879de1214..43ef2e0729 100644 --- a/src/leveldb/helpers/memenv/memenv.cc +++ b/src/leveldb/helpers/memenv/memenv.cc @@ -55,14 +55,15 @@ class FileState { } const uint64_t available = size_ - offset; if (n > available) { - n = available; + n = static_cast<size_t>(available); } if (n == 0) { *result = Slice(); return Status::OK(); } - size_t block = offset / kBlockSize; + assert(offset / kBlockSize <= SIZE_MAX); + size_t block = static_cast<size_t>(offset / kBlockSize); size_t block_offset = offset % kBlockSize; if (n <= kBlockSize - block_offset) { @@ -167,7 +168,7 @@ class SequentialFileImpl : public SequentialFile { if (pos_ > file_->Size()) { return Status::IOError("pos_ > file_->Size()"); } - const size_t available = file_->Size() - pos_; + const uint64_t available = file_->Size() - pos_; if (n > available) { n = available; } @@ -177,7 +178,7 @@ class SequentialFileImpl : public SequentialFile { private: FileState* file_; - size_t pos_; + uint64_t pos_; }; class RandomAccessFileImpl : public RandomAccessFile { diff --git a/src/leveldb/include/leveldb/cache.h b/src/leveldb/include/leveldb/cache.h index 5e3b47637d..1a201e5e0a 100644 --- a/src/leveldb/include/leveldb/cache.h +++ b/src/leveldb/include/leveldb/cache.h @@ -96,4 +96,4 @@ class Cache { } // namespace leveldb -#endif // STORAGE_LEVELDB_UTIL_CACHE_H_ +#endif // STORAGE_LEVELDB_INCLUDE_CACHE_H_ diff --git a/src/leveldb/include/leveldb/db.h b/src/leveldb/include/leveldb/db.h index 40851b2aa8..4c169bf22e 100644 --- a/src/leveldb/include/leveldb/db.h +++ b/src/leveldb/include/leveldb/db.h @@ -14,7 +14,7 @@ namespace leveldb { // Update Makefile if you change these static const int kMajorVersion = 1; -static const int kMinorVersion = 17; +static const int kMinorVersion = 18; struct Options; struct ReadOptions; diff --git a/src/leveldb/include/leveldb/dumpfile.h b/src/leveldb/include/leveldb/dumpfile.h new file mode 100644 index 0000000000..3f97fda16b --- /dev/null +++ b/src/leveldb/include/leveldb/dumpfile.h @@ -0,0 +1,25 @@ +// Copyright (c) 2014 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ +#define STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ + +#include <string> +#include "leveldb/env.h" +#include "leveldb/status.h" + +namespace leveldb { + +// Dump the contents of the file named by fname in text format to +// *dst. Makes a sequence of dst->Append() calls; each call is passed +// the newline-terminated text corresponding to a single item found +// in the file. +// +// Returns a non-OK result if fname does not name a leveldb storage +// file, or if the file cannot be read. +Status DumpFile(Env* env, const std::string& fname, WritableFile* dst); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ diff --git a/src/leveldb/include/leveldb/env.h b/src/leveldb/include/leveldb/env.h index b2072d02c1..f709514da6 100644 --- a/src/leveldb/include/leveldb/env.h +++ b/src/leveldb/include/leveldb/env.h @@ -142,7 +142,7 @@ class Env { // useful for computing deltas of time. virtual uint64_t NowMicros() = 0; - // Sleep/delay the thread for the perscribed number of micro-seconds. + // Sleep/delay the thread for the prescribed number of micro-seconds. virtual void SleepForMicroseconds(int micros) = 0; private: diff --git a/src/leveldb/include/leveldb/iterator.h b/src/leveldb/include/leveldb/iterator.h index ad543eb46c..76aced04bd 100644 --- a/src/leveldb/include/leveldb/iterator.h +++ b/src/leveldb/include/leveldb/iterator.h @@ -61,7 +61,7 @@ class Iterator { // Return the value for the current entry. The underlying storage for // the returned slice is valid only until the next modification of // the iterator. - // REQUIRES: !AtEnd() && !AtStart() + // REQUIRES: Valid() virtual Slice value() const = 0; // If an error has occurred, return it. Else return an ok status. diff --git a/src/leveldb/include/leveldb/options.h b/src/leveldb/include/leveldb/options.h index fdda718d30..7c9b973454 100644 --- a/src/leveldb/include/leveldb/options.h +++ b/src/leveldb/include/leveldb/options.h @@ -153,7 +153,7 @@ struct ReadOptions { // If "snapshot" is non-NULL, read as of the supplied snapshot // (which must belong to the DB that is being read and which must - // not have been released). If "snapshot" is NULL, use an impliicit + // not have been released). If "snapshot" is NULL, use an implicit // snapshot of the state at the beginning of this read operation. // Default: NULL const Snapshot* snapshot; diff --git a/src/leveldb/port/atomic_pointer.h b/src/leveldb/port/atomic_pointer.h index a9866b2302..9bf091f757 100644 --- a/src/leveldb/port/atomic_pointer.h +++ b/src/leveldb/port/atomic_pointer.h @@ -5,14 +5,13 @@ // AtomicPointer provides storage for a lock-free pointer. // Platform-dependent implementation of AtomicPointer: // - If the platform provides a cheap barrier, we use it with raw pointers -// - If cstdatomic is present (on newer versions of gcc, it is), we use -// a cstdatomic-based AtomicPointer. However we prefer the memory +// - If <atomic> is present (on newer versions of gcc, it is), we use +// a <atomic>-based AtomicPointer. However we prefer the memory // barrier based version, because at least on a gcc 4.4 32-bit build -// on linux, we have encountered a buggy <cstdatomic> -// implementation. Also, some <cstdatomic> implementations are much -// slower than a memory-barrier based implementation (~16ns for -// <cstdatomic> based acquire-load vs. ~1ns for a barrier based -// acquire-load). +// on linux, we have encountered a buggy <atomic> implementation. +// Also, some <atomic> implementations are much slower than a memory-barrier +// based implementation (~16ns for <atomic> based acquire-load vs. ~1ns for +// a barrier based acquire-load). // This code is based on atomicops-internals-* in Google's perftools: // http://code.google.com/p/google-perftools/source/browse/#svn%2Ftrunk%2Fsrc%2Fbase @@ -20,8 +19,8 @@ #define PORT_ATOMIC_POINTER_H_ #include <stdint.h> -#ifdef LEVELDB_CSTDATOMIC_PRESENT -#include <cstdatomic> +#ifdef LEVELDB_ATOMIC_PRESENT +#include <atomic> #endif #ifdef OS_WIN #include <windows.h> @@ -126,7 +125,7 @@ class AtomicPointer { }; // AtomicPointer based on <cstdatomic> -#elif defined(LEVELDB_CSTDATOMIC_PRESENT) +#elif defined(LEVELDB_ATOMIC_PRESENT) class AtomicPointer { private: std::atomic<void*> rep_; @@ -207,7 +206,7 @@ class AtomicPointer { inline void NoBarrier_Store(void* v) { rep_ = v; } }; -// We have neither MemoryBarrier(), nor <cstdatomic> +// We have neither MemoryBarrier(), nor <atomic> #else #error Please implement AtomicPointer for this platform. diff --git a/src/leveldb/port/port_posix.h b/src/leveldb/port/port_posix.h index 21c845e211..ccca9939d3 100644 --- a/src/leveldb/port/port_posix.h +++ b/src/leveldb/port/port_posix.h @@ -21,14 +21,11 @@ #else #define PLATFORM_IS_LITTLE_ENDIAN false #endif -#elif defined(OS_FREEBSD) +#elif defined(OS_FREEBSD) || defined(OS_OPENBSD) ||\ + defined(OS_NETBSD) || defined(OS_DRAGONFLYBSD) #include <sys/types.h> #include <sys/endian.h> #define PLATFORM_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN) -#elif defined(OS_OPENBSD) || defined(OS_NETBSD) ||\ - defined(OS_DRAGONFLYBSD) - #include <sys/types.h> - #include <sys/endian.h> #elif defined(OS_HPUX) #define PLATFORM_IS_LITTLE_ENDIAN false #elif defined(OS_ANDROID) @@ -55,7 +52,7 @@ #if defined(OS_MACOSX) || defined(OS_SOLARIS) || defined(OS_FREEBSD) ||\ defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD) ||\ - defined(OS_ANDROID) || defined(OS_HPUX) + defined(OS_ANDROID) || defined(OS_HPUX) || defined(CYGWIN) // Use fread/fwrite/fflush on platforms without _unlocked variants #define fread_unlocked fread #define fwrite_unlocked fwrite diff --git a/src/leveldb/port/thread_annotations.h b/src/leveldb/port/thread_annotations.h index 6f9b6a7924..9470ef587c 100644 --- a/src/leveldb/port/thread_annotations.h +++ b/src/leveldb/port/thread_annotations.h @@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors. -#ifndef STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H +#ifndef STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_ +#define STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_ // Some environments provide custom macros to aid in static thread-safety // analysis. Provide empty definitions of such macros unless they are already @@ -56,4 +57,4 @@ #define NO_THREAD_SAFETY_ANALYSIS #endif -#endif // STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H +#endif // STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_ diff --git a/src/leveldb/table/block.cc b/src/leveldb/table/block.cc index 79ea9d9ee5..43e402c9c0 100644 --- a/src/leveldb/table/block.cc +++ b/src/leveldb/table/block.cc @@ -46,7 +46,7 @@ Block::~Block() { // Helper routine: decode the next block entry starting at "p", // storing the number of shared key bytes, non_shared key bytes, // and the length of the value in "*shared", "*non_shared", and -// "*value_length", respectively. Will not derefence past "limit". +// "*value_length", respectively. Will not dereference past "limit". // // If any errors are detected, returns NULL. Otherwise, returns a // pointer to the key delta (just past the three decoded values). diff --git a/src/leveldb/table/block_builder.h b/src/leveldb/table/block_builder.h index 5b545bd1af..4fbcb33972 100644 --- a/src/leveldb/table/block_builder.h +++ b/src/leveldb/table/block_builder.h @@ -21,7 +21,7 @@ class BlockBuilder { // Reset the contents as if the BlockBuilder was just constructed. void Reset(); - // REQUIRES: Finish() has not been callled since the last call to Reset(). + // REQUIRES: Finish() has not been called since the last call to Reset(). // REQUIRES: key is larger than any previously added key void Add(const Slice& key, const Slice& value); diff --git a/src/leveldb/table/format.cc b/src/leveldb/table/format.cc index cda1decdf3..aa63144c9e 100644 --- a/src/leveldb/table/format.cc +++ b/src/leveldb/table/format.cc @@ -48,7 +48,7 @@ Status Footer::DecodeFrom(Slice* input) { const uint64_t magic = ((static_cast<uint64_t>(magic_hi) << 32) | (static_cast<uint64_t>(magic_lo))); if (magic != kTableMagicNumber) { - return Status::InvalidArgument("not an sstable (bad magic number)"); + return Status::Corruption("not an sstable (bad magic number)"); } Status result = metaindex_handle_.DecodeFrom(input); diff --git a/src/leveldb/table/table.cc b/src/leveldb/table/table.cc index 71c1756e5f..dff8a82590 100644 --- a/src/leveldb/table/table.cc +++ b/src/leveldb/table/table.cc @@ -41,7 +41,7 @@ Status Table::Open(const Options& options, Table** table) { *table = NULL; if (size < Footer::kEncodedLength) { - return Status::InvalidArgument("file is too short to be an sstable"); + return Status::Corruption("file is too short to be an sstable"); } char footer_space[Footer::kEncodedLength]; @@ -58,7 +58,11 @@ Status Table::Open(const Options& options, BlockContents contents; Block* index_block = NULL; if (s.ok()) { - s = ReadBlock(file, ReadOptions(), footer.index_handle(), &contents); + ReadOptions opt; + if (options.paranoid_checks) { + opt.verify_checksums = true; + } + s = ReadBlock(file, opt, footer.index_handle(), &contents); if (s.ok()) { index_block = new Block(contents); } @@ -92,6 +96,9 @@ void Table::ReadMeta(const Footer& footer) { // TODO(sanjay): Skip this if footer.metaindex_handle() size indicates // it is an empty block. ReadOptions opt; + if (rep_->options.paranoid_checks) { + opt.verify_checksums = true; + } BlockContents contents; if (!ReadBlock(rep_->file, opt, footer.metaindex_handle(), &contents).ok()) { // Do not propagate errors since meta info is not needed for operation @@ -120,6 +127,9 @@ void Table::ReadFilter(const Slice& filter_handle_value) { // We might want to unify with ReadBlock() if we start // requiring checksum verification in Table::Open. ReadOptions opt; + if (rep_->options.paranoid_checks) { + opt.verify_checksums = true; + } BlockContents block; if (!ReadBlock(rep_->file, opt, filter_handle, &block).ok()) { return; diff --git a/src/leveldb/util/bloom.cc b/src/leveldb/util/bloom.cc index d7941cd21f..a27a2ace28 100644 --- a/src/leveldb/util/bloom.cc +++ b/src/leveldb/util/bloom.cc @@ -29,7 +29,7 @@ class BloomFilterPolicy : public FilterPolicy { } virtual const char* Name() const { - return "leveldb.BuiltinBloomFilter"; + return "leveldb.BuiltinBloomFilter2"; } virtual void CreateFilter(const Slice* keys, int n, std::string* dst) const { diff --git a/src/leveldb/util/env_posix.cc b/src/leveldb/util/env_posix.cc index 93eadb1a4f..ba2667864a 100644 --- a/src/leveldb/util/env_posix.cc +++ b/src/leveldb/util/env_posix.cc @@ -3,8 +3,6 @@ // found in the LICENSE file. See the AUTHORS file for names of contributors. #if !defined(LEVELDB_PLATFORM_WINDOWS) -#include <deque> -#include <set> #include <dirent.h> #include <errno.h> #include <fcntl.h> @@ -18,9 +16,8 @@ #include <sys/types.h> #include <time.h> #include <unistd.h> -#if defined(LEVELDB_PLATFORM_ANDROID) -#include <sys/stat.h> -#endif +#include <deque> +#include <set> #include "leveldb/env.h" #include "leveldb/slice.h" #include "port/port.h" @@ -296,7 +293,8 @@ class PosixEnv : public Env { public: PosixEnv(); virtual ~PosixEnv() { - fprintf(stderr, "Destroying Env::Default()\n"); + char msg[] = "Destroying Env::Default()\n"; + fwrite(msg, 1, sizeof(msg), stderr); abort(); } diff --git a/src/leveldb/util/hash.cc b/src/leveldb/util/hash.cc index 07cf022060..ed439ce7a2 100644 --- a/src/leveldb/util/hash.cc +++ b/src/leveldb/util/hash.cc @@ -34,13 +34,13 @@ uint32_t Hash(const char* data, size_t n, uint32_t seed) { // Pick up remaining bytes switch (limit - data) { case 3: - h += data[2] << 16; + h += static_cast<unsigned char>(data[2]) << 16; FALLTHROUGH_INTENDED; case 2: - h += data[1] << 8; + h += static_cast<unsigned char>(data[1]) << 8; FALLTHROUGH_INTENDED; case 1: - h += data[0]; + h += static_cast<unsigned char>(data[0]); h *= m; h ^= (h >> r); break; diff --git a/src/leveldb/util/hash_test.cc b/src/leveldb/util/hash_test.cc new file mode 100644 index 0000000000..eaa1c92c23 --- /dev/null +++ b/src/leveldb/util/hash_test.cc @@ -0,0 +1,54 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#include "util/hash.h" +#include "util/testharness.h" + +namespace leveldb { + +class HASH { }; + +TEST(HASH, SignedUnsignedIssue) { + const unsigned char data1[1] = {0x62}; + const unsigned char data2[2] = {0xc3, 0x97}; + const unsigned char data3[3] = {0xe2, 0x99, 0xa5}; + const unsigned char data4[4] = {0xe1, 0x80, 0xb9, 0x32}; + const unsigned char data5[48] = { + 0x01, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x18, + 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + + ASSERT_EQ(Hash(0, 0, 0xbc9f1d34), 0xbc9f1d34); + ASSERT_EQ( + Hash(reinterpret_cast<const char*>(data1), sizeof(data1), 0xbc9f1d34), + 0xef1345c4); + ASSERT_EQ( + Hash(reinterpret_cast<const char*>(data2), sizeof(data2), 0xbc9f1d34), + 0x5b663814); + ASSERT_EQ( + Hash(reinterpret_cast<const char*>(data3), sizeof(data3), 0xbc9f1d34), + 0x323c078f); + ASSERT_EQ( + Hash(reinterpret_cast<const char*>(data4), sizeof(data4), 0xbc9f1d34), + 0xed21633a); + ASSERT_EQ( + Hash(reinterpret_cast<const char*>(data5), sizeof(data5), 0x12345678), + 0xf333dabb); +} + +} // namespace leveldb + +int main(int argc, char** argv) { + return leveldb::test::RunAllTests(); +} diff --git a/src/leveldb/util/logging.cc b/src/leveldb/util/logging.cc index 22cf278512..ca6b324403 100644 --- a/src/leveldb/util/logging.cc +++ b/src/leveldb/util/logging.cc @@ -45,15 +45,6 @@ std::string EscapeString(const Slice& value) { return r; } -bool ConsumeChar(Slice* in, char c) { - if (!in->empty() && (*in)[0] == c) { - in->remove_prefix(1); - return true; - } else { - return false; - } -} - bool ConsumeDecimalNumber(Slice* in, uint64_t* val) { uint64_t v = 0; int digits = 0; diff --git a/src/leveldb/util/logging.h b/src/leveldb/util/logging.h index b0c5da813e..1b450d2480 100644 --- a/src/leveldb/util/logging.h +++ b/src/leveldb/util/logging.h @@ -32,10 +32,6 @@ extern std::string NumberToString(uint64_t num); // Escapes any non-printable characters found in "value". extern std::string EscapeString(const Slice& value); -// If *in starts with "c", advances *in past the first character and -// returns true. Otherwise, returns false. -extern bool ConsumeChar(Slice* in, char c); - // Parse a human-readable number from "*in" into *value. On success, // advances "*in" past the consumed number and sets "*val" to the // numeric value. Otherwise, returns false and leaves *in in an diff --git a/src/leveldbwrapper.cpp b/src/leveldbwrapper.cpp index 8ce3e7b470..c353dfa6d9 100644 --- a/src/leveldbwrapper.cpp +++ b/src/leveldbwrapper.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2012-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-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 "leveldbwrapper.h" @@ -7,6 +7,7 @@ #include "util.h" #include <boost/filesystem.hpp> + #include <leveldb/cache.h> #include <leveldb/env.h> #include <leveldb/filter_policy.h> diff --git a/src/leveldbwrapper.h b/src/leveldbwrapper.h index da5ba61c7b..c65e842704 100644 --- a/src/leveldbwrapper.h +++ b/src/leveldbwrapper.h @@ -1,11 +1,13 @@ -// Copyright (c) 2012-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-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_LEVELDBWRAPPER_H #define BITCOIN_LEVELDBWRAPPER_H +#include "clientversion.h" #include "serialize.h" +#include "streams.h" #include "util.h" #include "version.h" @@ -22,7 +24,7 @@ public: void HandleError(const leveldb::Status& status) throw(leveldb_error); -// Batch of changes queued to be written to a CLevelDBWrapper +/** Batch of changes queued to be written to a CLevelDBWrapper */ class CLevelDBBatch { friend class CLevelDBWrapper; @@ -62,25 +64,25 @@ public: class CLevelDBWrapper { private: - // custom environment this database is using (may be NULL in case of default environment) + //! custom environment this database is using (may be NULL in case of default environment) leveldb::Env* penv; - // database options used + //! database options used leveldb::Options options; - // options used when reading from the database + //! options used when reading from the database leveldb::ReadOptions readoptions; - // options used when iterating over values of the database + //! options used when iterating over values of the database leveldb::ReadOptions iteroptions; - // options used when writing to the database + //! options used when writing to the database leveldb::WriteOptions writeoptions; - // options used when sync writing to the database + //! options used when sync writing to the database leveldb::WriteOptions syncoptions; - // the database itself + //! the database itself leveldb::DB* pdb; public: diff --git a/src/limitedmap.h b/src/limitedmap.h index 4bc8d9e5aa..e8ea549653 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -1,11 +1,11 @@ -// Copyright (c) 2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-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_LIMITEDMAP_H #define BITCOIN_LIMITEDMAP_H -#include <assert.h> // TODO: remove +#include <assert.h> #include <map> /** STL-like map container that only keeps the N elements with the highest value. */ @@ -59,12 +59,11 @@ public: return; } // Shouldn't ever get here - assert(0); //TODO remove me - map.erase(itTarget); + assert(0); } void update(const_iterator itIn, const mapped_type& v) { - //TODO: When we switch to C++11, use map.erase(itIn, itIn) to get the non-const iterator + // TODO: When we switch to C++11, use map.erase(itIn, itIn) to get the non-const iterator. iterator itTarget = map.find(itIn->first); if (itTarget == map.end()) return; @@ -77,9 +76,7 @@ public: return; } // Shouldn't ever get here - assert(0); //TODO remove me - itTarget->second = v; - rmap.insert(make_pair(v, itTarget)); + assert(0); } size_type max_size() const { return nMaxSize; } size_type max_size(size_type s) diff --git a/src/main.cpp b/src/main.cpp index 15c3916a6f..f6033566ef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "main.h" @@ -11,12 +11,15 @@ #include "checkpoints.h" #include "checkqueue.h" #include "init.h" +#include "merkleblock.h" #include "net.h" #include "pow.h" #include "txdb.h" #include "txmempool.h" #include "ui_interface.h" +#include "undo.h" #include "util.h" +#include "utilmoneystr.h" #include <sstream> @@ -25,21 +28,22 @@ #include <boost/filesystem/fstream.hpp> #include <boost/thread.hpp> -using namespace std; using namespace boost; +using namespace std; #if defined(NDEBUG) # error "Bitcoin cannot be compiled without assertions." #endif -// -// Global state -// +/** + * Global state + */ CCriticalSection cs_main; BlockMap mapBlockIndex; CChain chainActive; +CBlockIndex *pindexBestHeader = NULL; int64_t nTimeBestReceived = 0; CWaitableCriticalSection csBestBlock; CConditionVariable cvBlockChange; @@ -50,19 +54,12 @@ bool fTxIndex = false; bool fIsBareMultisigStd = true; unsigned int nCoinCacheSize = 5000; + /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */ CFeeRate minRelayTxFee = CFeeRate(1000); CTxMemPool mempool(::minRelayTxFee); -struct COrphanBlock { - uint256 hashBlock; - uint256 hashPrev; - vector<unsigned char> vchBlock; -}; -map<uint256, COrphanBlock*> mapOrphanBlocks; -multimap<uint256, COrphanBlock*> mapOrphanBlocksByPrev; - struct COrphanTx { CTransaction tx; NodeId fromPeer; @@ -71,7 +68,14 @@ map<uint256, COrphanTx> mapOrphanTransactions; map<uint256, set<uint256> > mapOrphanTransactionsByPrev; void EraseOrphansFor(NodeId peer); -// Constant stuff for coinbase transactions we create: +/** + * 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. + */ +static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired); + +/** Constant stuff for coinbase transactions we create: */ CScript COINBASE_FLAGS; const string strMessageMagic = "Bitcoin Signed Message:\n"; @@ -102,34 +106,50 @@ namespace { CBlockIndex *pindexBestInvalid; - // The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS or better that are at least - // as good as our current tip. Entries may be failed, though. - set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexValid; + /** + * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS or better that are at least + * as good as our current tip. Entries may be failed, though. + */ + set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates; + /** Number of nodes with fSyncStarted. */ + int nSyncStarted = 0; + /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions. */ + multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked; CCriticalSection cs_LastBlockFile; - CBlockFileInfo infoLastBlockFile; + std::vector<CBlockFileInfo> vinfoBlockFile; int nLastBlockFile = 0; - // Every received block is assigned a unique and increasing identifier, so we - // know which one to give priority in case of a fork. + /** + * Every received block is assigned a unique and increasing identifier, so we + * know which one to give priority in case of a fork. + */ CCriticalSection cs_nBlockSequenceId; - // Blocks loaded from disk are assigned id 0, so start the counter at 1. + /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */ 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, to be able to send them reject messages or ban + * them, if processing happens afterwards. Protected by cs_main. + */ map<uint256, NodeId> mapBlockSource; - // Blocks that are in flight, and that are in the queue to be downloaded. - // Protected by cs_main. + /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */ struct QueuedBlock { uint256 hash; - int64_t nTime; // Time of "getdata" request in microseconds. - int nQueuedBefore; // Number of blocks in flight at the time of request. + CBlockIndex *pindex; //! Optional. + int64_t nTime; //! Time of "getdata" request in microseconds. }; map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight; - map<uint256, pair<NodeId, list<uint256>::iterator> > mapBlocksToDownload; + /** Number of preferable block download peers. */ + int nPreferredDownload = 0; + + /** Dirty block index entries. */ + set<CBlockIndex*> setDirtyBlockIndex; + + /** Dirty block file entries. */ + set<int> setDirtyFileInfo; } // anon namespace ////////////////////////////////////////////////////////////////////////////// @@ -142,41 +162,46 @@ namespace { namespace { struct CMainSignals { - // Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. + /** 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). + /** 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). + /** 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. + /** Notifies listeners of a new active block chain. */ boost::signals2::signal<void (const CBlockLocator &)> SetBestChain; - // Notifies listeners about an inventory item being seen on the network. + /** Notifies listeners about an inventory item being seen on the network. */ boost::signals2::signal<void (const uint256 &)> Inventory; - // Tells listeners to broadcast their data. + /** Tells listeners to broadcast their data. */ boost::signals2::signal<void ()> Broadcast; + /** Notifies listeners of a block validation result */ + boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked; } g_signals; } // anon namespace -void RegisterWallet(CWalletInterface* pwalletIn) { - g_signals.SyncTransaction.connect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2)); - g_signals.EraseTransaction.connect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1)); - g_signals.UpdatedTransaction.connect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1)); - g_signals.SetBestChain.connect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1)); - g_signals.Inventory.connect(boost::bind(&CWalletInterface::Inventory, pwalletIn, _1)); - g_signals.Broadcast.connect(boost::bind(&CWalletInterface::ResendWalletTransactions, pwalletIn)); +void RegisterValidationInterface(CValidationInterface* pwalletIn) { + 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)); + g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); } -void UnregisterWallet(CWalletInterface* pwalletIn) { - g_signals.Broadcast.disconnect(boost::bind(&CWalletInterface::ResendWalletTransactions, pwalletIn)); - g_signals.Inventory.disconnect(boost::bind(&CWalletInterface::Inventory, pwalletIn, _1)); - g_signals.SetBestChain.disconnect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1)); - g_signals.UpdatedTransaction.disconnect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1)); - g_signals.EraseTransaction.disconnect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1)); - g_signals.SyncTransaction.disconnect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2)); +void UnregisterValidationInterface(CValidationInterface* pwalletIn) { + g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); + g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn)); + g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); + g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); + g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); + g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); + g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); } -void UnregisterAllWallets() { +void UnregisterAllValidationInterfaces() { + g_signals.BlockChecked.disconnect_all_slots(); g_signals.Broadcast.disconnect_all_slots(); g_signals.Inventory.disconnect_all_slots(); g_signals.SetBestChain.disconnect_all_slots(); @@ -202,43 +227,50 @@ struct CBlockReject { uint256 hashBlock; }; -// Maintain validation-specific state about nodes, protected by cs_main, instead -// by CNode's own locks. This simplifies asynchronous operation, where -// processing of incoming data is done after the ProcessMessage call returns, -// and we're no longer holding the node's locks. +/** + * Maintain validation-specific state about nodes, protected by cs_main, instead + * by CNode's own locks. This simplifies asynchronous operation, where + * processing of incoming data is done after the ProcessMessage call returns, + * and we're no longer holding the node's locks. + */ struct CNodeState { - // Accumulated misbehaviour score for this peer. + //! Accumulated misbehaviour score for this peer. int nMisbehavior; - // Whether this peer should be disconnected and banned (unless whitelisted). + //! Whether this peer should be disconnected and banned (unless whitelisted). bool fShouldBan; - // String name of this peer (debugging/logging purposes). + //! String name of this peer (debugging/logging purposes). std::string name; - // List of asynchronously-determined block rejections to notify this peer about. + //! List of asynchronously-determined block rejections to notify this peer about. std::vector<CBlockReject> rejects; - // The best known block we know this peer has announced. + //! The best known block we know this peer has announced. CBlockIndex *pindexBestKnownBlock; - // The hash of the last unknown block this peer has announced. + //! The hash of the last unknown block this peer has announced. uint256 hashLastUnknownBlock; + //! The last full block we both have. + CBlockIndex *pindexLastCommonBlock; + //! Whether we've started headers synchronization with this peer. + bool fSyncStarted; + //! Since when we're stalling block download progress (in microseconds), or 0. + int64_t nStallingSince; list<QueuedBlock> vBlocksInFlight; int nBlocksInFlight; - list<uint256> vBlocksToDownload; - int nBlocksToDownload; - int64_t nLastBlockReceive; - int64_t nLastBlockProcess; + //! Whether we consider this a preferred download peer. + bool fPreferredDownload; CNodeState() { nMisbehavior = 0; fShouldBan = false; pindexBestKnownBlock = NULL; hashLastUnknownBlock = uint256(0); - nBlocksToDownload = 0; + pindexLastCommonBlock = NULL; + fSyncStarted = false; + nStallingSince = 0; nBlocksInFlight = 0; - nLastBlockReceive = 0; - nLastBlockProcess = 0; + fPreferredDownload = false; } }; -// Map maintaining per-node state. Requires cs_main. +/** Map maintaining per-node state. Requires cs_main. */ map<NodeId, CNodeState> mapNodeState; // Requires cs_main. @@ -255,6 +287,16 @@ int GetHeight() return chainActive.Height(); } +void UpdatePreferredDownload(CNode* node, CNodeState* state) +{ + nPreferredDownload -= state->fPreferredDownload; + + // Whether this node should be marked as a preferred download node. + state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient; + + nPreferredDownload += state->fPreferredDownload; +} + void InitializeNode(NodeId nodeid, const CNode *pnode) { LOCK(cs_main); CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second; @@ -265,64 +307,38 @@ void FinalizeNode(NodeId nodeid) { LOCK(cs_main); CNodeState *state = State(nodeid); + if (state->fSyncStarted) + nSyncStarted--; + BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight) mapBlocksInFlight.erase(entry.hash); - BOOST_FOREACH(const uint256& hash, state->vBlocksToDownload) - mapBlocksToDownload.erase(hash); EraseOrphansFor(nodeid); + nPreferredDownload -= state->fPreferredDownload; mapNodeState.erase(nodeid); } // Requires cs_main. -void MarkBlockAsReceived(const uint256 &hash, NodeId nodeFrom = -1) { - map<uint256, pair<NodeId, list<uint256>::iterator> >::iterator itToDownload = mapBlocksToDownload.find(hash); - if (itToDownload != mapBlocksToDownload.end()) { - CNodeState *state = State(itToDownload->second.first); - state->vBlocksToDownload.erase(itToDownload->second.second); - state->nBlocksToDownload--; - mapBlocksToDownload.erase(itToDownload); - } - +void 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); state->vBlocksInFlight.erase(itInFlight->second.second); state->nBlocksInFlight--; - if (itInFlight->second.first == nodeFrom) - state->nLastBlockReceive = GetTimeMicros(); + state->nStallingSince = 0; mapBlocksInFlight.erase(itInFlight); } } // Requires cs_main. -bool AddBlockToQueue(NodeId nodeid, const uint256 &hash) { - if (mapBlocksToDownload.count(hash) || mapBlocksInFlight.count(hash)) - return false; - - CNodeState *state = State(nodeid); - if (state == NULL) - return false; - - list<uint256>::iterator it = state->vBlocksToDownload.insert(state->vBlocksToDownload.end(), hash); - state->nBlocksToDownload++; - if (state->nBlocksToDownload > 5000) - Misbehaving(nodeid, 10); - mapBlocksToDownload[hash] = std::make_pair(nodeid, it); - return true; -} - -// Requires cs_main. -void MarkBlockAsInFlight(NodeId nodeid, const uint256 &hash) { +void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex *pindex = NULL) { CNodeState *state = State(nodeid); assert(state != NULL); // Make sure it's not listed somewhere already. MarkBlockAsReceived(hash); - QueuedBlock newentry = {hash, GetTimeMicros(), state->nBlocksInFlight}; - if (state->nBlocksInFlight == 0) - state->nLastBlockReceive = newentry.nTime; // Reset when a first request is sent. + QueuedBlock newentry = {hash, pindex, GetTimeMicros()}; list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry); state->nBlocksInFlight++; mapBlocksInFlight[hash] = std::make_pair(nodeid, it); @@ -361,6 +377,108 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) { } } +/** Find the last common ancestor two blocks have. + * Both pa and pb must be non-NULL. */ +CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) { + if (pa->nHeight > pb->nHeight) { + pa = pa->GetAncestor(pb->nHeight); + } else if (pb->nHeight > pa->nHeight) { + pb = pb->GetAncestor(pa->nHeight); + } + + while (pa != pb && pa && pb) { + pa = pa->pprev; + pb = pb->pprev; + } + + // Eventually all chain branches meet at the genesis block. + assert(pa == pb); + return pa; +} + +/** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has + * at most count entries. */ +void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBlockIndex*>& vBlocks, NodeId& nodeStaller) { + if (count == 0) + return; + + vBlocks.reserve(vBlocks.size() + count); + CNodeState *state = State(nodeid); + assert(state != NULL); + + // Make sure pindexBestKnownBlock is up to date, we'll need it. + ProcessBlockAvailability(nodeid); + + if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) { + // This peer has nothing interesting. + return; + } + + if (state->pindexLastCommonBlock == NULL) { + // Bootstrap quickly by guessing a parent of our best tip is the forking point. + // Guessing wrong in either direction is not a problem. + state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())]; + } + + // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor + // of their current tip anymore. Go back enough to fix that. + state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock); + if (state->pindexLastCommonBlock == state->pindexBestKnownBlock) + return; + + std::vector<CBlockIndex*> vToFetch; + CBlockIndex *pindexWalk = state->pindexLastCommonBlock; + // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last + // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to + // download that next block if the window were 1 larger. + int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW; + int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1); + NodeId waitingfor = -1; + while (pindexWalk->nHeight < nMaxHeight) { + // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards + // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive + // as iterating over ~100 CBlockIndex* entries anyway. + int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max<int>(count - vBlocks.size(), 128)); + vToFetch.resize(nToFetch); + pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch); + vToFetch[nToFetch - 1] = pindexWalk; + for (unsigned int i = nToFetch - 1; i > 0; i--) { + vToFetch[i - 1] = vToFetch[i]->pprev; + } + + // 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. + 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->nChainTx) + state->pindexLastCommonBlock = pindex; + } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) { + // The block is not already downloaded, and not yet in flight. + if (pindex->nHeight > nWindowEnd) { + // We reached the end of the window. + if (vBlocks.size() == 0 && waitingfor != nodeid) { + // We aren't able to fetch anything, but we would be if the download window was one larger. + nodeStaller = waitingfor; + } + return; + } + vBlocks.push_back(pindex); + if (vBlocks.size() == count) { + return; + } + } else if (waitingfor == -1) { + // This is the first already-in-flight block. + waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first; + } + } + } +} + } // anon namespace bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) { @@ -370,6 +488,11 @@ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) { return false; stats.nMisbehavior = state->nMisbehavior; stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1; + stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1; + BOOST_FOREACH(const QueuedBlock& queue, state->vBlocksInFlight) { + if (queue.pindex) + stats.vHeightInFlight.push_back(queue.pindex->nHeight); + } return true; } @@ -391,72 +514,19 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals) nodeSignals.FinalizeNode.disconnect(&FinalizeNode); } -////////////////////////////////////////////////////////////////////////////// -// -// CChain implementation -// - -CBlockIndex *CChain::SetTip(CBlockIndex *pindex) { - if (pindex == NULL) { - vChain.clear(); - return NULL; - } - vChain.resize(pindex->nHeight + 1); - while (pindex && vChain[pindex->nHeight] != pindex) { - vChain[pindex->nHeight] = pindex; - pindex = pindex->pprev; - } - return pindex; -} - -CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { - int nStep = 1; - std::vector<uint256> vHave; - vHave.reserve(32); - - if (!pindex) - pindex = Tip(); - while (pindex) { - vHave.push_back(pindex->GetBlockHash()); - // Stop when we have added the genesis block. - if (pindex->nHeight == 0) - break; - // Exponentially larger steps back, plus the genesis block. - int nHeight = std::max(pindex->nHeight - nStep, 0); - if (Contains(pindex)) { - // Use O(1) CChain index if possible. - pindex = (*this)[nHeight]; - } else { - // Otherwise, use O(log n) skiplist. - pindex = pindex->GetAncestor(nHeight); - } - if (vHave.size() > 10) - nStep *= 2; - } - - return CBlockLocator(vHave); -} - -CBlockIndex *CChain::FindFork(const CBlockLocator &locator) const { +CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator) +{ // Find the first block the caller has in the main chain BOOST_FOREACH(const uint256& hash, locator.vHave) { BlockMap::iterator mi = mapBlockIndex.find(hash); if (mi != mapBlockIndex.end()) { CBlockIndex* pindex = (*mi).second; - if (Contains(pindex)) + if (chain.Contains(pindex)) return pindex; } } - return Genesis(); -} - -const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { - if (pindex->nHeight > Height()) - pindex = pindex->GetAncestor(Height()); - while (pindex && !Contains(pindex)) - pindex = pindex->pprev; - return pindex; + return chain.Genesis(); } CCoinsViewCache *pcoinsTip = NULL; @@ -610,10 +680,6 @@ bool IsStandardTx(const CTransaction& tx, string& reason) reason = "scriptsig-not-pushonly"; return false; } - if (!txin.scriptSig.HasCanonicalPushes()) { - reason = "scriptsig-non-canonical-push"; - return false; - } } unsigned int nDataOut = 0; @@ -662,15 +728,15 @@ 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 -// +/** + * 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) { if (tx.IsCoinBase()) @@ -697,7 +763,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) // IsStandard() will have already returned false // and this method isn't called. vector<vector<unsigned char> > stack; - if (!EvalScript(stack, tx.vin[i].scriptSig, tx, i, false)) + if (!EvalScript(stack, tx.vin[i].scriptSig, false, BaseSignatureChecker())) return false; if (whichType == TX_SCRIPTHASH) @@ -781,7 +847,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) REJECT_INVALID, "bad-txns-oversize"); // Check for negative or overflow output values - int64_t nValueOut = 0; + CAmount nValueOut = 0; BOOST_FOREACH(const CTxOut& txout, tx.vout) { if (txout.nValue < 0) @@ -823,19 +889,19 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) return true; } -int64_t GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree) +CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree) { { LOCK(mempool.cs); uint256 hash = tx.GetHash(); double dPriorityDelta = 0; - int64_t nFeeDelta = 0; + CAmount nFeeDelta = 0; mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta); if (dPriorityDelta > 0 || nFeeDelta > 0) return 0; } - int64_t nMinFee = ::minRelayTxFee.GetFee(nBytes); + CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes); if (fAllowFree) { @@ -896,12 +962,12 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa { CCoinsView dummy; - CCoinsViewCache view(dummy); + CCoinsViewCache view(&dummy); - int64_t nValueIn = 0; + CAmount nValueIn = 0; { LOCK(pool.cs); - CCoinsViewMemPool viewMemPool(*pcoinsTip, pool); + CCoinsViewMemPool viewMemPool(pcoinsTip, pool); view.SetBackend(viewMemPool); // do we already have it? @@ -950,21 +1016,21 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa hash.ToString(), nSigOps, MAX_TX_SIGOPS), REJECT_NONSTANDARD, "bad-txns-too-many-sigops"); - int64_t nValueOut = tx.GetValueOut(); - int64_t nFees = nValueIn-nValueOut; + CAmount nValueOut = tx.GetValueOut(); + CAmount nFees = nValueIn-nValueOut; double dPriority = view.GetPriority(tx, chainActive.Height()); CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height()); unsigned int nSize = entry.GetTxSize(); // Don't accept it if it can't get into a block - int64_t txMinFee = GetMinRelayFee(tx, nSize, true); + 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"); - // Continuously rate-limit free (really, very-low-fee)transactions + // Continuously rate-limit free (really, very-low-fee) transactions // This mitigates 'penny-flooding' -- sending thousands of free transactions just to // be annoying or make others' transactions take longer to confirm. if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize)) @@ -989,16 +1055,31 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000) - return error("AcceptToMemoryPool: : insane fees %s, %d > %d", + return error("AcceptToMemoryPool: insane fees %s, %d > %d", hash.ToString(), nFees, ::minRelayTxFee.GetFee(nSize) * 10000); // 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)) + if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true)) { - return error("AcceptToMemoryPool: : ConnectInputs failed %s", hash.ToString()); + return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString()); } + + // Check again against just the consensus-critical mandatory script + // verification flags, in case of bugs in the standard flags that cause + // transactions to pass as valid when they're actually invalid. For + // instance the STRICTENC flag was incorrectly allowing certain + // CHECKSIG NOT scripts to pass, even though they were invalid. + // + // There is a similar check in CreateNewBlock() to prevent creating + // invalid blocks, however allowing such transactions into the mempool + // can be exploited as a DoS attack. + if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) + { + return error("AcceptToMemoryPool: : BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString()); + } + // Store transaction in memory pool.addUnchecked(hash, entry); } @@ -1008,7 +1089,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return true; } -// Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock +/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) { CBlockIndex *pindexSlow = NULL; @@ -1025,12 +1106,14 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock 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, postx.nTxOffset, SEEK_CUR); + fseek(file.Get(), postx.nTxOffset, SEEK_CUR); file >> txOut; - } catch (std::exception &e) { + } catch (const std::exception& e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); } hashBlock = header.GetHash(); @@ -1082,8 +1165,8 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos) { // Open history file to append - CAutoFile fileout = CAutoFile(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); - if (!fileout) + CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); + if (fileout.IsNull()) return error("WriteBlockToDisk : OpenBlockFile failed"); // Write index header @@ -1091,17 +1174,12 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos) fileout << FLATDATA(Params().MessageStart()) << nSize; // Write block - long fileOutPos = ftell(fileout); + long fileOutPos = ftell(fileout.Get()); if (fileOutPos < 0) return error("WriteBlockToDisk : ftell failed"); pos.nPos = (unsigned int)fileOutPos; fileout << block; - // Flush stdio buffers and commit to disk before returning - fflush(fileout); - if (!IsInitialBlockDownload()) - FileCommit(fileout); - return true; } @@ -1110,15 +1188,15 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) block.SetNull(); // Open history file to read - CAutoFile filein = CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); - if (!filein) + CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); + if (filein.IsNull()) return error("ReadBlockFromDisk : OpenBlockFile failed"); // Read block try { filein >> block; } - catch (std::exception &e) { + catch (const std::exception& e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); } @@ -1138,49 +1216,9 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex) return true; } -uint256 static GetOrphanRoot(const uint256& hash) -{ - map<uint256, COrphanBlock*>::iterator it = mapOrphanBlocks.find(hash); - if (it == mapOrphanBlocks.end()) - return hash; - - // Work back to the first block in the orphan chain - do { - map<uint256, COrphanBlock*>::iterator it2 = mapOrphanBlocks.find(it->second->hashPrev); - if (it2 == mapOrphanBlocks.end()) - return it->first; - it = it2; - } while(true); -} - -// Remove a random orphan block (which does not have any dependent orphans). -void static PruneOrphanBlocks() -{ - if (mapOrphanBlocksByPrev.size() <= (size_t)std::max((int64_t)0, GetArg("-maxorphanblocks", DEFAULT_MAX_ORPHAN_BLOCKS))) - return; - - // Pick a random orphan block. - int pos = insecure_rand() % mapOrphanBlocksByPrev.size(); - std::multimap<uint256, COrphanBlock*>::iterator it = mapOrphanBlocksByPrev.begin(); - while (pos--) it++; - - // As long as this block has other orphans depending on it, move to one of those successors. - do { - std::multimap<uint256, COrphanBlock*>::iterator it2 = mapOrphanBlocksByPrev.find(it->second->hashBlock); - if (it2 == mapOrphanBlocksByPrev.end()) - break; - it = it2; - } while(1); - - uint256 hash = it->second->hashBlock; - delete it->second; - mapOrphanBlocksByPrev.erase(it); - mapOrphanBlocks.erase(hash); -} - -int64_t GetBlockValue(int nHeight, int64_t nFees) +CAmount GetBlockValue(int nHeight, const CAmount& nFees) { - int64_t nSubsidy = 50 * COIN; + CAmount nSubsidy = 50 * COIN; int halvings = nHeight / Params().SubsidyHalvingInterval(); // Force block reward to zero when right shift is undefined. @@ -1198,15 +1236,14 @@ bool IsInitialBlockDownload() LOCK(cs_main); if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate()) return true; - static int64_t nLastUpdate; - static CBlockIndex* pindexLastBest; - if (chainActive.Tip() != pindexLastBest) - { - pindexLastBest = chainActive.Tip(); - nLastUpdate = GetTime(); - } - return (GetTime() - nLastUpdate < 10 && - chainActive.Tip()->GetBlockTime() < GetTime() - 24 * 60 * 60); + static bool lockIBDState = false; + if (lockIBDState) + return false; + bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 || + pindexBestHeader->GetBlockTime() < GetTime() - 24 * 60 * 60); + if (!state) + lockIBDState = true; + return state; } bool fLargeWorkForkFound = false; @@ -1226,20 +1263,15 @@ void CheckForkWarningConditions() if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 72) pindexBestForkTip = NULL; - if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.Tip()->nChainWork + (chainActive.Tip()->GetBlockWork() * 6))) + if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.Tip()->nChainWork + (GetBlockProof(*chainActive.Tip()) * 6))) { - if (!fLargeWorkForkFound) + if (!fLargeWorkForkFound && pindexBestForkBase) { - std::string strCmd = GetArg("-alertnotify", ""); - if (!strCmd.empty()) - { - std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") + - pindexBestForkBase->phashBlock->ToString() + std::string("'"); - boost::replace_all(strCmd, "%s", warning); - boost::thread t(runCommand, strCmd); // thread runs free - } + std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") + + pindexBestForkBase->phashBlock->ToString() + std::string("'"); + CAlert::Notify(warning, true); } - if (pindexBestForkTip) + if (pindexBestForkTip && pindexBestForkBase) { LogPrintf("CheckForkWarningConditions: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n", pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(), @@ -1282,7 +1314,7 @@ void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip) // We define it this way because it allows us to only store the highest fork tip (+ base) which meets // the 7-block condition and from this always have the most-likely-to-cause-warning fork if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->nHeight > pindexBestForkTip->nHeight)) && - pindexNewForkTip->nChainWork - pfork->nChainWork > (pfork->GetBlockWork() * 7) && + pindexNewForkTip->nChainWork - pfork->nChainWork > (GetBlockProof(*pfork) * 7) && chainActive.Height() - pindexNewForkTip->nHeight < 72) { pindexBestForkTip = pindexNewForkTip; @@ -1332,7 +1364,7 @@ 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(), pindex->GetBlockHash()}; + CBlockReject reject = {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); @@ -1340,40 +1372,54 @@ void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state } if (!state.CorruptionPossible()) { pindex->nStatus |= BLOCK_FAILED_VALID; - pblocktree->WriteBlockIndex(CDiskBlockIndex(pindex)); - setBlockIndexValid.erase(pindex); + setDirtyBlockIndex.insert(pindex); + setBlockIndexCandidates.erase(pindex); InvalidChainFound(pindex); } } void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight) { - bool ret; // mark inputs spent if (!tx.IsCoinBase()) { txundo.vprevout.reserve(tx.vin.size()); - for (unsigned int i = 0; i < tx.vin.size(); i++) { - const CTxIn &txin = tx.vin[i]; - CCoins &coins = inputs.GetCoins(txin.prevout.hash); - txundo.vprevout.push_back(CTxInUndo()); - ret = coins.Spend(txin.prevout, txundo.vprevout.back()); - assert(ret); + BOOST_FOREACH(const CTxIn &txin, tx.vin) { + CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash); + unsigned nPos = txin.prevout.n; + + if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull()) + assert(false); + // mark an outpoint spent, and construct undo information + txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos])); + coins->Spend(nPos); + if (coins->vout.size() == 0) { + CTxInUndo& undo = txundo.vprevout.back(); + undo.nHeight = coins->nHeight; + undo.fCoinBase = coins->fCoinBase; + undo.nVersion = coins->nVersion; + } } } // add outputs - ret = inputs.SetCoins(tx.GetHash(), CCoins(tx, nHeight)); - assert(ret); + inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); } -bool CScriptCheck::operator()() const { +void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight) +{ + CTxUndo txundo; + UpdateCoins(tx, state, inputs, txundo, nHeight); +} + +bool CScriptCheck::operator()() { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; - if (!VerifyScript(scriptSig, scriptPubKey, *ptxTo, nIn, nFlags)) - return error("CScriptCheck() : %s VerifySignature failed", ptxTo->GetHash().ToString()); + if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingSignatureChecker(*ptxTo, nIn, cacheStore), &error)) { + return ::error("CScriptCheck() : %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error)); + } return true; } -bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, std::vector<CScriptCheck> *pvChecks) +bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks) { if (!tx.IsCoinBase()) { @@ -1389,8 +1435,8 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // This is also true for mempool checks. CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second; int nSpendHeight = pindexPrev->nHeight + 1; - int64_t nValueIn = 0; - int64_t nFees = 0; + CAmount nValueIn = 0; + CAmount nFees = 0; for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; @@ -1414,11 +1460,12 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi } if (nValueIn < tx.GetValueOut()) - return state.DoS(100, error("CheckInputs() : %s value in < value out", tx.GetHash().ToString()), + 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"); // Tally transaction fees - int64_t nTxFee = nValueIn - tx.GetValueOut(); + 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"); @@ -1441,7 +1488,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi assert(coins); // Verify signature - CScriptCheck check(*coins, tx, i, flags); + CScriptCheck check(*coins, tx, i, flags, cacheStore); if (pvChecks) { pvChecks->push_back(CScriptCheck()); check.swap(pvChecks->back()); @@ -1454,9 +1501,9 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // avoid splitting the network between upgraded and // non-upgraded nodes. CScriptCheck check(*coins, tx, i, - flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS); + flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore); if (check()) - return state.Invalid(false, REJECT_NONSTANDARD, "non-mandatory-script-verify-flag"); + return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); } // Failures of other flags indicate a transaction that is // invalid in new blocks, e.g. a invalid P2SH. We DoS ban @@ -1465,7 +1512,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // as to the correct behavior - we may want to continue // peering with non-upgraded nodes even after a soft-fork // super-majority vote has passed. - return state.DoS(100,false, REJECT_INVALID, "mandatory-script-verify-flag-failed"); + return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError()))); } } } @@ -1474,7 +1521,63 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi return true; } +namespace { + +bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock) +{ + // Open history file to append + CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); + if (fileout.IsNull()) + return error("%s : OpenUndoFile failed", __func__); + + // Write index header + unsigned int nSize = fileout.GetSerializeSize(blockundo); + fileout << FLATDATA(Params().MessageStart()) << nSize; + + // Write undo data + long fileOutPos = ftell(fileout.Get()); + if (fileOutPos < 0) + return error("%s : ftell failed", __func__); + pos.nPos = (unsigned int)fileOutPos; + fileout << blockundo; + + // calculate & write checksum + CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); + hasher << hashBlock; + hasher << blockundo; + fileout << hasher.GetHash(); + + return true; +} +bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock) +{ + // Open history file to read + CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); + if (filein.IsNull()) + return error("%s : OpenBlockFile failed", __func__); + + // Read block + uint256 hashChecksum; + try { + filein >> blockundo; + filein >> hashChecksum; + } + catch (const std::exception& e) { + return error("%s : Deserialize or I/O error - %s", __func__, e.what()); + } + + // Verify checksum + CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); + hasher << hashBlock; + hasher << blockundo; + if (hashChecksum != hasher.GetHash()) + return error("%s : Checksum mismatch", __func__); + + return true; +} + +} // anon namespace bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean) { @@ -1489,7 +1592,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex CDiskBlockPos pos = pindex->GetUndoPos(); if (pos.IsNull()) return error("DisconnectBlock() : no undo data available"); - if (!blockUndo.ReadFromDisk(pos, pindex->pprev->GetBlockHash())) + if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash())) return error("DisconnectBlock() : failure reading undo data"); if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) @@ -1504,21 +1607,23 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex // exactly. Note that transactions with only provably unspendable outputs won't // have outputs available even in the block itself, so we handle that case // specially with outsEmpty. + { CCoins outsEmpty; - CCoins &outs = view.HaveCoins(hash) ? view.GetCoins(hash) : outsEmpty; - outs.ClearUnspendable(); + CCoinsModifier outs = view.ModifyCoins(hash); + outs->ClearUnspendable(); - CCoins outsBlock = CCoins(tx, pindex->nHeight); + CCoins outsBlock(tx, pindex->nHeight); // The CCoins serialization does not serialize negative numbers. // No network rules currently depend on the version here, so an inconsistency is harmless // but it must be corrected before txout nversion ever influences a network rule. if (outsBlock.nVersion < 0) - outs.nVersion = outsBlock.nVersion; - if (outs != outsBlock) + outs->nVersion = outsBlock.nVersion; + if (*outs != outsBlock) fClean = fClean && error("DisconnectBlock() : added transaction mismatch? database corrupted"); // remove outputs - outs = CCoins(); + outs->Clear(); + } // restore inputs if (i > 0) { // not coinbases @@ -1528,27 +1633,24 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex for (unsigned int j = tx.vin.size(); j-- > 0;) { const COutPoint &out = tx.vin[j].prevout; const CTxInUndo &undo = txundo.vprevout[j]; - CCoins coins; - view.GetCoins(out.hash, coins); // this can fail if the prevout was already entirely spent + CCoinsModifier coins = view.ModifyCoins(out.hash); if (undo.nHeight != 0) { // undo data contains height: this is the last output of the prevout tx being spent - if (!coins.IsPruned()) + if (!coins->IsPruned()) fClean = fClean && error("DisconnectBlock() : undo data overwriting existing transaction"); - coins = CCoins(); - coins.fCoinBase = undo.fCoinBase; - coins.nHeight = undo.nHeight; - coins.nVersion = undo.nVersion; + coins->Clear(); + coins->fCoinBase = undo.fCoinBase; + coins->nHeight = undo.nHeight; + coins->nVersion = undo.nVersion; } else { - if (coins.IsPruned()) + if (coins->IsPruned()) fClean = fClean && error("DisconnectBlock() : undo data adding output to missing transaction"); } - if (coins.IsAvailable(out.n)) + if (coins->IsAvailable(out.n)) fClean = fClean && error("DisconnectBlock() : undo data overwriting existing output"); - if (coins.vout.size() < out.n+1) - coins.vout.resize(out.n+1); - coins.vout[out.n] = undo.txout; - if (!view.SetCoins(out.hash, coins)) - return error("DisconnectBlock() : cannot restore coin inputs"); + if (coins->vout.size() < out.n+1) + coins->vout.resize(out.n+1); + coins->vout[out.n] = undo.txout; } } } @@ -1573,7 +1675,7 @@ void static FlushBlockFile(bool fFinalize = false) FILE *fileOld = OpenBlockFile(posOld); if (fileOld) { if (fFinalize) - TruncateFile(fileOld, infoLastBlockFile.nSize); + TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize); FileCommit(fileOld); fclose(fileOld); } @@ -1581,7 +1683,7 @@ void static FlushBlockFile(bool fFinalize = false) fileOld = OpenUndoFile(posOld); if (fileOld) { if (fFinalize) - TruncateFile(fileOld, infoLastBlockFile.nUndoSize); + TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize); FileCommit(fileOld); fclose(fileOld); } @@ -1602,7 +1704,7 @@ static int64_t nTimeIndex = 0; static int64_t nTimeCallbacks = 0; static int64_t nTimeTotal = 0; -bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck) +bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck) { AssertLockHeld(cs_main); // Check it again in case a previous version let a bad block in @@ -1650,15 +1752,14 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C int64_t nBIP16SwitchTime = 1333238400; bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime); - unsigned int flags = SCRIPT_VERIFY_NOCACHE | - (fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE); + unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE; CBlockUndo blockundo; CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); int64_t nTimeStart = GetTimeMicros(); - int64_t nFees = 0; + CAmount nFees = 0; int nInputs = 0; unsigned int nSigOps = 0; CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size())); @@ -1695,7 +1796,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C nFees += view.GetValueIn(tx)-tx.GetValueOut(); std::vector<CScriptCheck> vChecks; - if (!CheckInputs(tx, state, view, fScriptChecks, flags, nScriptCheckThreads ? &vChecks : NULL)) + if (!CheckInputs(tx, state, view, fScriptChecks, flags, false, nScriptCheckThreads ? &vChecks : NULL)) return false; control.Add(vChecks); } @@ -1726,11 +1827,6 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C if (fJustCheck) return true; - // Correct transaction counts. - pindex->nTx = block.vtx.size(); - if (pindex->pprev) - pindex->nChainTx = pindex->pprev->nChainTx + block.vtx.size(); - // Write undo information to disk if (pindex->GetUndoPos().IsNull() || !pindex->IsValid(BLOCK_VALID_SCRIPTS)) { @@ -1738,8 +1834,8 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C CDiskBlockPos pos; if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) return error("ConnectBlock() : FindUndoPos failed"); - if (!blockundo.WriteToDisk(pos, pindex->pprev->GetBlockHash())) - return state.Abort(_("Failed to write undo data")); + if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash())) + return state.Abort("Failed to write undo data"); // update nUndoPos in block index pindex->nUndoPos = pos.nPos; @@ -1747,20 +1843,15 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C } pindex->RaiseValidity(BLOCK_VALID_SCRIPTS); - - CDiskBlockIndex blockindex(pindex); - if (!pblocktree->WriteBlockIndex(blockindex)) - return state.Abort(_("Failed to write block index")); + setDirtyBlockIndex.insert(pindex); } if (fTxIndex) if (!pblocktree->WriteTxIndex(vPos)) - return state.Abort(_("Failed to write transaction index")); + return state.Abort("Failed to write transaction index"); // add this block to the view's block chain - bool ret; - ret = view.SetBestBlock(pindex->GetBlockHash()); - assert(ret); + view.SetBestBlock(pindex->GetBlockHash()); int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2; LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001); @@ -1776,10 +1867,23 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C return true; } -// Update the on-disk chain state. -bool static WriteChainState(CValidationState &state) { +enum FlushStateMode { + FLUSH_STATE_IF_NEEDED, + FLUSH_STATE_PERIODIC, + FLUSH_STATE_ALWAYS +}; + +/** + * Update the on-disk chain state. + * The caches and indexes are flushed if either they're too large, forceWrite is set, or + * fast is not set and it's been a while since the last write. + */ +bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { + LOCK(cs_main); static int64_t nLastWrite = 0; - if (pcoinsTip->GetCacheSize() > nCoinCacheSize || (!IsInitialBlockDownload() && GetTimeMicros() > nLastWrite + 600*1000000)) { + 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)) { // 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 @@ -1787,16 +1891,44 @@ bool static WriteChainState(CValidationState &state) { // overwrite one. Still, use a conservative safety factor of 2. if (!CheckDiskSpace(100 * 2 * 2 * pcoinsTip->GetCacheSize())) return state.Error("out of disk space"); + // First make sure all block and undo data is flushed to disk. FlushBlockFile(); - pblocktree->Sync(); + // Then update all block file information (which may refer to block and undo files). + { + std::vector<std::pair<int, const CBlockFileInfo*> > vFiles; + vFiles.reserve(setDirtyFileInfo.size()); + for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) { + vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it])); + setDirtyFileInfo.erase(it++); + } + std::vector<const CBlockIndex*> vBlocks; + vBlocks.reserve(setDirtyBlockIndex.size()); + for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) { + vBlocks.push_back(*it); + setDirtyBlockIndex.erase(it++); + } + if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) { + return state.Abort("Files to write to block index database"); + } + } + // Finally flush the chainstate (which may refer to block index entries). if (!pcoinsTip->Flush()) - return state.Abort(_("Failed to write to coin database")); + return state.Abort("Failed to write to coin database"); + // Update best block in wallet (so we can detect restored wallets). + if (mode != FLUSH_STATE_IF_NEEDED) { + g_signals.SetBestChain(chainActive.GetLocator()); + } nLastWrite = GetTimeMicros(); } return true; } -// Update chainActive and related internal data structures. +void FlushStateToDisk() { + CValidationState state; + FlushStateToDisk(state, FLUSH_STATE_ALWAYS); +} + +/** Update chainActive and related internal data structures. */ void static UpdateTip(CBlockIndex *pindexNew) { chainActive.SetTip(pindexNew); @@ -1804,15 +1936,16 @@ void static UpdateTip(CBlockIndex *pindexNew) { nTimeBestReceived = GetTime(); mempool.AddTransactionsUpdated(1); - LogPrintf("UpdateTip: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f\n", + LogPrintf("UpdateTip: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%u\n", 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())); + Checkpoints::GuessVerificationProgress(chainActive.Tip()), (unsigned int)pcoinsTip->GetCacheSize()); cvBlockChange.notify_all(); // Check the version of the last 100 blocks to see if we need to upgrade: - if (!IsInitialBlockDownload()) + static bool fWarned = false; + if (!IsInitialBlockDownload() && !fWarned) { int nUpgraded = 0; const CBlockIndex* pindex = chainActive.Tip(); @@ -1825,12 +1958,16 @@ void static UpdateTip(CBlockIndex *pindexNew) { if (nUpgraded > 0) LogPrintf("SetBestChain: %d of last 100 blocks above version %d\n", nUpgraded, (int)CBlock::CURRENT_VERSION); if (nUpgraded > 100/2) + { // strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user: strMiscWarning = _("Warning: This version is obsolete, upgrade required!"); + CAlert::Notify(strMiscWarning, true); + fWarned = true; + } } } -// Disconnect chainActive's tip. +/** Disconnect chainActive's tip. */ bool static DisconnectTip(CValidationState &state) { CBlockIndex *pindexDelete = chainActive.Tip(); assert(pindexDelete); @@ -1838,28 +1975,28 @@ bool static DisconnectTip(CValidationState &state) { // Read block from disk. CBlock block; if (!ReadBlockFromDisk(block, pindexDelete)) - return state.Abort(_("Failed to read block")); + return state.Abort("Failed to read block"); // Apply the block atomically to the chain state. int64_t nStart = GetTimeMicros(); { - CCoinsViewCache view(*pcoinsTip, true); + CCoinsViewCache view(pcoinsTip); if (!DisconnectBlock(block, state, pindexDelete, view)) return error("DisconnectTip() : DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString()); assert(view.Flush()); } LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001); // Write the chain state to disk, if necessary. - if (!WriteChainState(state)) + if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED)) return false; // Resurrect mempool transactions from the disconnected block. BOOST_FOREACH(const CTransaction &tx, block.vtx) { // ignore validation errors in resurrected transactions list<CTransaction> removed; CValidationState stateDummy; - if (!tx.IsCoinBase()) - if (!AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) - mempool.remove(tx, removed, true); + if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) + mempool.remove(tx, removed, true); } + mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight); mempool.check(pcoinsTip); // Update chainActive and related variables. UpdateTip(pindexDelete->pprev); @@ -1877,8 +2014,10 @@ 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. +/** + * 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) { assert(pindexNew->pprev == chainActive.Tip()); mempool.check(pcoinsTip); @@ -1887,7 +2026,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 state.Abort("Failed to read block"); pblock = █ } // Apply the block atomically to the chain state. @@ -1895,9 +2034,11 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * int64_t nTime3; LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001); { - CCoinsViewCache view(*pcoinsTip, true); + CCoinsViewCache view(pcoinsTip); CInv inv(MSG_BLOCK, pindexNew->GetBlockHash()); - if (!ConnectBlock(*pblock, state, pindexNew, view)) { + bool rv = ConnectBlock(*pblock, state, pindexNew, view); + g_signals.BlockChecked(*pblock, state); + if (!rv) { if (state.IsInvalid()) InvalidBlockFound(pindexNew, state); return error("ConnectTip() : ConnectBlock %s failed", pindexNew->GetBlockHash().ToString()); @@ -1910,7 +2051,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3; LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001); // Write the chain state to disk, if necessary. - if (!WriteChainState(state)) + if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED)) return false; int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4; LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001); @@ -1929,10 +2070,6 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * BOOST_FOREACH(const CTransaction &tx, pblock->vtx) { SyncWithWallets(tx, pblock); } - // Update best block in wallet (so we can detect restored wallets) - // Emit this signal after the SyncWithWallets signals as the wallet relies on that everything up to this point has been synced - if ((chainActive.Height() % 20160) == 0 || ((chainActive.Height() % 144) == 0 && !IsInitialBlockDownload())) - g_signals.SetBestChain(chainActive.GetLocator()); int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1; LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001); @@ -1940,16 +2077,18 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * return true; } -// Return the tip of the chain with the most work in it, that isn't -// known to be invalid (it's however far from certain to be valid). +/** + * Return the tip of the chain with the most work in it, that isn't + * known to be invalid (it's however far from certain to be valid). + */ static CBlockIndex* FindMostWorkChain() { do { CBlockIndex *pindexNew = NULL; // Find the best candidate header. { - std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexValid.rbegin(); - if (it == setBlockIndexValid.rend()) + std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin(); + if (it == setBlockIndexCandidates.rend()) return NULL; pindexNew = *it; } @@ -1959,6 +2098,8 @@ static CBlockIndex* FindMostWorkChain() { CBlockIndex *pindexTest = pindexNew; bool fInvalidAncestor = false; while (pindexTest && !chainActive.Contains(pindexTest)) { + assert(pindexTest->nStatus & BLOCK_HAVE_DATA); + assert(pindexTest->nChainTx || pindexTest->nHeight == 0); if (pindexTest->nStatus & BLOCK_FAILED_MASK) { // Candidate has an invalid ancestor, remove entire chain from the set. if (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork) @@ -1966,10 +2107,10 @@ static CBlockIndex* FindMostWorkChain() { CBlockIndex *pindexFailed = pindexNew; while (pindexTest != pindexFailed) { pindexFailed->nStatus |= BLOCK_FAILED_CHILD; - setBlockIndexValid.erase(pindexFailed); + setBlockIndexCandidates.erase(pindexFailed); pindexFailed = pindexFailed->pprev; } - setBlockIndexValid.erase(pindexTest); + setBlockIndexCandidates.erase(pindexTest); fInvalidAncestor = true; break; } @@ -1980,8 +2121,22 @@ static CBlockIndex* FindMostWorkChain() { } while(true); } -// Try to make some progress towards making pindexMostWork the active block. -// pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. +/** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */ +static void PruneBlockIndexCandidates() { + // Note that we can't delete the current block itself, as we may need to return to it later in case a + // reorganization to a better block fails. + std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin(); + while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.Tip())) { + setBlockIndexCandidates.erase(it++); + } + // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates. + assert(!setBlockIndexCandidates.empty()); +} + +/** + * 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) { AssertLockHeld(cs_main); bool fInvalidFound = false; @@ -1996,12 +2151,20 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo // Build list of new blocks to connect. std::vector<CBlockIndex*> vpindexToConnect; - vpindexToConnect.reserve(pindexMostWork->nHeight - (pindexFork ? pindexFork->nHeight : -1)); - CBlockIndex *pindexIter = pindexMostWork; - while (pindexIter && pindexIter != pindexFork) { + bool fContinue = true; + int nHeight = pindexFork ? pindexFork->nHeight : -1; + while (fContinue && nHeight != pindexMostWork->nHeight) { + // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need + // a few blocks along the way. + int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight); + vpindexToConnect.clear(); + vpindexToConnect.reserve(nTargetHeight - nHeight); + CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight); + while (pindexIter && pindexIter->nHeight != nHeight) { vpindexToConnect.push_back(pindexIter); pindexIter = pindexIter->pprev; } + nHeight = nTargetHeight; // Connect new blocks. BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { @@ -2012,27 +2175,22 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo InvalidChainFound(vpindexToConnect.back()); state = CValidationState(); fInvalidFound = true; + fContinue = false; break; } else { // A system error occurred (disk space, database error, ...). return false; } } else { - // Delete all entries in setBlockIndexValid that are worse than our new current block. - // Note that we can't delete the current block itself, as we may need to return to it later in case a - // reorganization to a better block fails. - std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexValid.begin(); - while (setBlockIndexValid.value_comp()(*it, chainActive.Tip())) { - setBlockIndexValid.erase(it++); - } - // Either the current tip or a successor of it we're working towards is left in setBlockIndexValid. - assert(!setBlockIndexValid.empty()); + PruneBlockIndexCandidates(); if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) { // We're in a better position than we were. Return temporarily to release the lock. + fContinue = false; break; } } } + } // Callbacks/notifications for a new best chain. if (fInvalidFound) @@ -2040,15 +2198,14 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo else CheckForkWarningConditions(); - if (!pblocktree->Flush()) - return state.Abort(_("Failed to sync block index")); - return true; } -// Make the best chain active, in multiple steps. The result is either failure -// or an activated best chain. pblock is either NULL or a pointer to a block -// that is already loaded (to avoid loading it again from disk). +/** + * Make the best chain active, in multiple steps. The result is either failure + * or an activated best chain. pblock is either NULL or a pointer to a block + * that is already loaded (to avoid loading it again from disk). + */ bool ActivateBestChain(CValidationState &state, CBlock *pblock) { CBlockIndex *pindexNewTip = NULL; CBlockIndex *pindexMostWork = NULL; @@ -2078,20 +2235,92 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) { // Relay inventory, but don't relay old inventory during initial block download. int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(); { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) - pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip)); + 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. uiInterface.NotifyBlockTip(hashNewTip); } } while(pindexMostWork != chainActive.Tip()); + // Write changes periodically to disk, after relay. + if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) { + return false; + } + + return true; +} + +bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { + AssertLockHeld(cs_main); + + // Mark the block itself as invalid. + pindex->nStatus |= BLOCK_FAILED_VALID; + setDirtyBlockIndex.insert(pindex); + setBlockIndexCandidates.erase(pindex); + + while (chainActive.Contains(pindex)) { + CBlockIndex *pindexWalk = chainActive.Tip(); + pindexWalk->nStatus |= BLOCK_FAILED_CHILD; + setDirtyBlockIndex.insert(pindexWalk); + setBlockIndexCandidates.erase(pindexWalk); + // ActivateBestChain considers blocks already in chainActive + // unconditionally valid already, so force disconnect away from it. + if (!DisconnectTip(state)) { + return false; + } + } + + // The resulting new best tip may not be in setBlockIndexCandidates anymore, so + // add them again. + BlockMap::iterator it = mapBlockIndex.begin(); + while (it != mapBlockIndex.end()) { + if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) { + setBlockIndexCandidates.insert(pindex); + } + it++; + } + + InvalidChainFound(pindex); + return true; +} + +bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) { + AssertLockHeld(cs_main); + + int nHeight = pindex->nHeight; + + // Remove the invalidity flag from this block and all its descendants. + BlockMap::iterator it = mapBlockIndex.begin(); + while (it != mapBlockIndex.end()) { + if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) { + it->second->nStatus &= ~BLOCK_FAILED_MASK; + setDirtyBlockIndex.insert(it->second); + if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) { + setBlockIndexCandidates.insert(it->second); + } + if (it->second == pindexBestInvalid) { + // Reset invalid block marker if it was pointing to one of those. + pindexBestInvalid = NULL; + } + } + it++; + } + + // Remove the invalidity flag from all ancestors too. + while (pindex != NULL) { + if (pindex->nStatus & BLOCK_FAILED_MASK) { + pindex->nStatus &= ~BLOCK_FAILED_MASK; + setDirtyBlockIndex.insert(pindex); + } + pindex = pindex->pprev; + } return true; } -CBlockIndex* AddToBlockIndex(CBlockHeader& block) +CBlockIndex* AddToBlockIndex(const CBlockHeader& block) { // Check for duplicate uint256 hash = block.GetHash(); @@ -2102,10 +2331,10 @@ CBlockIndex* AddToBlockIndex(CBlockHeader& block) // Construct new block index object CBlockIndex* pindexNew = new CBlockIndex(block); assert(pindexNew); - { - LOCK(cs_nBlockSequenceId); - pindexNew->nSequenceId = nBlockSequenceId++; - } + // We assign the sequence id to blocks only when the full data is available, + // to avoid miners withholding blocks but broadcasting headers, to get a + // competitive advantage. + pindexNew->nSequenceId = 0; BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; pindexNew->phashBlock = &((*mi).first); BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock); @@ -2115,76 +2344,89 @@ CBlockIndex* AddToBlockIndex(CBlockHeader& block) pindexNew->nHeight = pindexNew->pprev->nHeight + 1; pindexNew->BuildSkip(); } - pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + pindexNew->GetBlockWork(); + pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew); pindexNew->RaiseValidity(BLOCK_VALID_TREE); + if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork) + pindexBestHeader = pindexNew; + + setDirtyBlockIndex.insert(pindexNew); return pindexNew; } -// Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). +/** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos) { pindexNew->nTx = block.vtx.size(); - if (pindexNew->pprev) { - // Not the genesis block. - if (pindexNew->pprev->nChainTx) { - // This parent's block's total number transactions is known, so compute outs. - pindexNew->nChainTx = pindexNew->pprev->nChainTx + pindexNew->nTx; - } else { - // The total number of transactions isn't known yet. - // We will compute it when the block is connected. - pindexNew->nChainTx = 0; - } - } else { - // Genesis block. - pindexNew->nChainTx = pindexNew->nTx; - } + pindexNew->nChainTx = 0; pindexNew->nFile = pos.nFile; pindexNew->nDataPos = pos.nPos; pindexNew->nUndoPos = 0; pindexNew->nStatus |= BLOCK_HAVE_DATA; - - if (pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS)) - setBlockIndexValid.insert(pindexNew); - - if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew))) - return state.Abort(_("Failed to write block index")); + pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS); + { + LOCK(cs_nBlockSequenceId); + pindexNew->nSequenceId = nBlockSequenceId++; + } + setDirtyBlockIndex.insert(pindexNew); + + if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) { + // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS. + deque<CBlockIndex*> queue; + queue.push_back(pindexNew); + + // Recursively process any descendant blocks that now may be eligible to be connected. + while (!queue.empty()) { + CBlockIndex *pindex = queue.front(); + queue.pop_front(); + pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx; + setBlockIndexCandidates.insert(pindex); + std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex); + while (range.first != range.second) { + std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first; + queue.push_back(it->second); + range.first++; + mapBlocksUnlinked.erase(it); + } + } + } else { + if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) { + mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew)); + } + } return true; } bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false) { - bool fUpdatedLast = false; - LOCK(cs_LastBlockFile); - if (fKnown) { - if (nLastBlockFile != pos.nFile) { - nLastBlockFile = pos.nFile; - infoLastBlockFile.SetNull(); - pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); - fUpdatedLast = true; - } - } else { - while (infoLastBlockFile.nSize + nAddSize >= MAX_BLOCKFILE_SIZE) { - LogPrintf("Leaving block file %i: %s\n", nLastBlockFile, infoLastBlockFile.ToString()); + unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile; + if (vinfoBlockFile.size() <= nFile) { + vinfoBlockFile.resize(nFile + 1); + } + + if (!fKnown) { + while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) { + LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString()); FlushBlockFile(true); - nLastBlockFile++; - infoLastBlockFile.SetNull(); - pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); // check whether data for the new file somehow already exist; can fail just fine - fUpdatedLast = true; + nFile++; + if (vinfoBlockFile.size() <= nFile) { + vinfoBlockFile.resize(nFile + 1); + } } - pos.nFile = nLastBlockFile; - pos.nPos = infoLastBlockFile.nSize; + pos.nFile = nFile; + pos.nPos = vinfoBlockFile[nFile].nSize; } - infoLastBlockFile.nSize += nAddSize; - infoLastBlockFile.AddBlock(nHeight, nTime); + nLastBlockFile = nFile; + vinfoBlockFile[nFile].nSize += nAddSize; + vinfoBlockFile[nFile].AddBlock(nHeight, nTime); if (!fKnown) { unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; - unsigned int nNewChunks = (infoLastBlockFile.nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; + unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; if (nNewChunks > nOldChunks) { if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) { FILE *file = OpenBlockFile(pos); @@ -2199,11 +2441,7 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd } } - if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile)) - return state.Abort(_("Failed to write file info")); - if (fUpdatedLast) - pblocktree->WriteLastBlockFile(nLastBlockFile); - + setDirtyFileInfo.insert(nFile); return true; } @@ -2214,20 +2452,9 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne LOCK(cs_LastBlockFile); unsigned int nNewSize; - if (nFile == nLastBlockFile) { - pos.nPos = infoLastBlockFile.nUndoSize; - nNewSize = (infoLastBlockFile.nUndoSize += nAddSize); - if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile)) - return state.Abort(_("Failed to write block info")); - } else { - CBlockFileInfo info; - if (!pblocktree->ReadBlockFileInfo(nFile, info)) - return state.Abort(_("Failed to read block info")); - pos.nPos = info.nUndoSize; - nNewSize = (info.nUndoSize += nAddSize); - if (!pblocktree->WriteBlockFileInfo(nFile, info)) - return state.Abort(_("Failed to write block info")); - } + pos.nPos = vinfoBlockFile[nFile].nUndoSize; + nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize; + setDirtyFileInfo.insert(nFile); unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; @@ -2264,12 +2491,33 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot) { - // These are checks that are independent of context - // that can be verified before saving an orphan block. + // These are checks that are independent of context. + // Check that the header is valid (particularly PoW). This is mostly + // redundant with the call in AcceptBlockHeader. if (!CheckBlockHeader(block, state, fCheckPOW)) return false; + // Check the merkle root. + if (fCheckMerkleRoot) { + bool mutated; + uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated); + if (block.hashMerkleRoot != hashMerkleRoot2) + return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"), + REJECT_INVALID, "bad-txnmrklroot", true); + + // Check for merkle tree malleability (CVE-2012-2459): repeating sequences + // of transactions in a block without affecting the merkle root of a block, + // while still invalidating it. + if (mutated) + return state.DoS(100, error("CheckBlock() : duplicate transaction"), + REJECT_INVALID, "bad-txns-duplicate", true); + } + + // All potential-corruption validation must be done before we do any + // transaction validation, as otherwise we may mark the header as invalid + // because we receive the wrong transactions for it. + // Size limits if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) return state.DoS(100, error("CheckBlock() : size limits failed"), @@ -2289,16 +2537,6 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo if (!CheckTransaction(tx, state)) return error("CheckBlock() : CheckTransaction failed"); - // Check for duplicate txids. This is caught by ConnectInputs(), - // but catching it earlier avoids a potential DoS attack: - set<uint256> uniqueTx; - BOOST_FOREACH(const CTransaction &tx, block.vtx) { - uniqueTx.insert(tx.GetHash()); - } - if (uniqueTx.size() != block.vtx.size()) - return state.DoS(100, error("CheckBlock() : duplicate transaction"), - REJECT_INVALID, "bad-txns-duplicate", true); - unsigned int nSigOps = 0; BOOST_FOREACH(const CTransaction& tx, block.vtx) { @@ -2308,15 +2546,75 @@ 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); - // Check merkle root - if (fCheckMerkleRoot && block.hashMerkleRoot != block.BuildMerkleTree()) - return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"), - REJECT_INVALID, "bad-txnmrklroot", true); + return true; +} + +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev) +{ + uint256 hash = block.GetHash(); + if (hash == Params().HashGenesisBlock()) + return true; + + assert(pindexPrev); + + int nHeight = pindexPrev->nHeight+1; + + // Check proof of work + if ((!Params().SkipProofOfWorkCheck()) && + (block.nBits != GetNextWorkRequired(pindexPrev, &block))) + return state.DoS(100, error("%s : incorrect proof of work", __func__), + REJECT_INVALID, "bad-diffbits"); + + // Check timestamp against prev + if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) + return state.Invalid(error("%s : block's timestamp is too early", __func__), + REJECT_INVALID, "time-too-old"); + + // 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())) + { + return state.Invalid(error("%s : rejected nVersion=1 block", __func__), + REJECT_OBSOLETE, "bad-version"); + } + + return true; +} + +bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev) +{ + const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1; + + // Check that all transactions are finalized + BOOST_FOREACH(const CTransaction& tx, block.vtx) + if (!IsFinalTx(tx, nHeight, block.GetBlockTime())) { + return state.DoS(10, error("%s : contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal"); + } + + // 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())) + { + CScript expect = CScript() << nHeight; + if (block.vtx[0].vin[0].scriptSig.size() < expect.size() || + !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) { + return state.DoS(100, error("%s : block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height"); + } + } return true; } -bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex) +bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex) { AssertLockHeld(cs_main); // Check for duplicate @@ -2324,67 +2622,32 @@ bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex 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("AcceptBlock() : block is marked invalid"), 0, "duplicate"); + return state.Invalid(error("%s : block is marked invalid", __func__), 0, "duplicate"); + return true; } - CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(); - if (pcheckpoint && block.hashPrevBlock != (chainActive.Tip() ? chainActive.Tip()->GetBlockHash() : uint256(0))) - { - // Extra checks to prevent "fill up memory by spamming with bogus blocks" - int64_t deltaTime = block.GetBlockTime() - pcheckpoint->GetBlockTime(); - if (deltaTime < 0) - { - return state.DoS(100, error("CheckBlockHeader() : block with timestamp before last checkpoint"), - REJECT_CHECKPOINT, "time-too-old"); - } - if (!CheckMinWork(block.nBits, pcheckpoint->nBits, deltaTime)) - { - return state.DoS(100, error("CheckBlockHeader() : block with too little proof-of-work"), - REJECT_INVALID, "bad-diffbits"); - } - } + if (!CheckBlockHeader(block, state)) + return false; // Get prev block index CBlockIndex* pindexPrev = NULL; - int nHeight = 0; if (hash != Params().HashGenesisBlock()) { BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); if (mi == mapBlockIndex.end()) - return state.DoS(10, error("AcceptBlock() : prev block not found"), 0, "bad-prevblk"); + return state.DoS(10, error("%s : prev block not found", __func__), 0, "bad-prevblk"); pindexPrev = (*mi).second; - nHeight = pindexPrev->nHeight+1; - - // Check proof of work - if (block.nBits != GetNextWorkRequired(pindexPrev, &block)) - return state.DoS(100, error("AcceptBlock() : incorrect proof of work"), - REJECT_INVALID, "bad-diffbits"); - - // Check timestamp against prev - if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) - return state.Invalid(error("AcceptBlock() : block's timestamp is too early"), - 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("AcceptBlock() : rejected by checkpoint lock-in at %d", 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("AcceptBlock() : forked chain older than last checkpoint (height %d)", nHeight)); - - // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 2 && - CBlockIndex::IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority())) - { - return state.Invalid(error("AcceptBlock() : rejected nVersion=1 block"), - REJECT_OBSOLETE, "bad-version"); - } + 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; + if (pindex == NULL) pindex = AddToBlockIndex(block); @@ -2403,36 +2666,22 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, if (!AcceptBlockHeader(block, state, &pindex)) return false; - if (!CheckBlock(block, state)) { + if (pindex->nStatus & BLOCK_HAVE_DATA) { + // 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; + } + + if ((!CheckBlock(block, state)) || !ContextualCheckBlock(block, state, pindex->pprev)) { if (state.IsInvalid() && !state.CorruptionPossible()) { pindex->nStatus |= BLOCK_FAILED_VALID; + setDirtyBlockIndex.insert(pindex); } return false; } int nHeight = pindex->nHeight; - // Check that all transactions are finalized - BOOST_FOREACH(const CTransaction& tx, block.vtx) - if (!IsFinalTx(tx, nHeight, block.GetBlockTime())) { - pindex->nStatus |= BLOCK_FAILED_VALID; - return state.DoS(10, error("AcceptBlock() : contains a non-final transaction"), - REJECT_INVALID, "bad-txns-nonfinal"); - } - - // 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 && - CBlockIndex::IsSuperMajority(2, pindex->pprev, Params().EnforceBlockUpgradeMajority())) - { - CScript expect = CScript() << nHeight; - if (block.vtx[0].vin[0].scriptSig.size() < expect.size() || - !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) { - pindex->nStatus |= BLOCK_FAILED_VALID; - return state.DoS(100, error("AcceptBlock() : block height mismatch in coinbase"), REJECT_INVALID, "bad-cb-height"); - } - } - // Write block to history file try { unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); @@ -2443,17 +2692,17 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, return error("AcceptBlock() : FindBlockPos failed"); if (dbp == NULL) if (!WriteBlockToDisk(block, blockPos)) - return state.Abort(_("Failed to write block")); + return state.Abort("Failed to write block"); if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) return error("AcceptBlock() : ReceivedBlockTransactions failed"); - } catch(std::runtime_error &e) { - return state.Abort(_("System error: ") + e.what()); + } catch (const std::runtime_error& e) { + return state.Abort(std::string("System error: ") + e.what()); } return true; } -bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired) +static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired) { unsigned int nToCheck = Params().ToCheckBlockUpgradeMajority(); unsigned int nFound = 0; @@ -2466,303 +2715,59 @@ bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, uns return (nFound >= nRequired); } -/** Turn the lowest '1' bit in the binary representation of a number into a '0'. */ -int static inline InvertLowestOne(int n) { return n & (n - 1); } - -/** Compute what height to jump back to with the CBlockIndex::pskip pointer. */ -int static inline GetSkipHeight(int height) { - if (height < 2) - return 0; - - // Determine which height to jump back to. Any number strictly lower than height is acceptable, - // but the following expression seems to perform well in simulations (max 110 steps to go back - // up to 2**18 blocks). - return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 : InvertLowestOne(height); -} -CBlockIndex* CBlockIndex::GetAncestor(int height) +bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp) { - if (height > nHeight || height < 0) - return NULL; - - CBlockIndex* pindexWalk = this; - int heightWalk = nHeight; - while (heightWalk > height) { - int heightSkip = GetSkipHeight(heightWalk); - int heightSkipPrev = GetSkipHeight(heightWalk - 1); - if (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; - } else { - pindexWalk = pindexWalk->pprev; - heightWalk--; - } - } - return pindexWalk; -} - -const CBlockIndex* CBlockIndex::GetAncestor(int height) const -{ - return const_cast<CBlockIndex*>(this)->GetAncestor(height); -} - -void CBlockIndex::BuildSkip() -{ - if (pprev) - pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); -} - -void PushGetBlocks(CNode* pnode, CBlockIndex* pindexBegin, uint256 hashEnd) -{ - AssertLockHeld(cs_main); - // Filter out duplicate requests - if (pindexBegin == pnode->pindexLastGetBlocksBegin && hashEnd == pnode->hashLastGetBlocksEnd) - return; - pnode->pindexLastGetBlocksBegin = pindexBegin; - pnode->hashLastGetBlocksEnd = hashEnd; - - pnode->PushMessage("getblocks", chainActive.GetLocator(pindexBegin), hashEnd); -} - -bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp) -{ - // Check for duplicate - uint256 hash = pblock->GetHash(); - - { - LOCK(cs_main); - if (mapBlockIndex.count(hash)) - return state.Invalid(error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString()), 0, "duplicate"); - if (mapOrphanBlocks.count(hash)) - return state.Invalid(error("ProcessBlock() : already have block (orphan) %s", hash.ToString()), 0, "duplicate"); - // Preliminary checks - if (!CheckBlock(*pblock, state)) - return error("ProcessBlock() : CheckBlock FAILED"); + bool checked = CheckBlock(*pblock, state); - // If we don't already have its previous block (with full data), shunt it off to holding area until we get it - BlockMap::iterator it = mapBlockIndex.find(pblock->hashPrevBlock); - if (pblock->hashPrevBlock != 0 && (it == mapBlockIndex.end() || !(it->second->nStatus & BLOCK_HAVE_DATA))) { - LogPrintf("ProcessBlock: ORPHAN BLOCK %lu, prev=%s\n", (unsigned long)mapOrphanBlocks.size(), pblock->hashPrevBlock.ToString()); - - // Accept orphans as long as there is a node to request its parents from - if (pfrom) { - PruneOrphanBlocks(); - COrphanBlock* pblock2 = new COrphanBlock(); - { - CDataStream ss(SER_DISK, CLIENT_VERSION); - ss << *pblock; - pblock2->vchBlock = std::vector<unsigned char>(ss.begin(), ss.end()); - } - pblock2->hashBlock = hash; - pblock2->hashPrev = pblock->hashPrevBlock; - mapOrphanBlocks.insert(make_pair(hash, pblock2)); - mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrev, pblock2)); - - // Ask this guy to fill in what we're missing - PushGetBlocks(pfrom, chainActive.Tip(), GetOrphanRoot(hash)); + LOCK(cs_main); + MarkBlockAsReceived(pblock->GetHash()); + if (!checked) { + return error("%s : CheckBlock FAILED", __func__); } - return true; - } - // Store to disk - CBlockIndex *pindex = NULL; - bool ret = AcceptBlock(*pblock, state, &pindex, dbp); - if (!ret) - return error("ProcessBlock() : AcceptBlock FAILED"); - - // Recursively process any orphan blocks that depended on this one - vector<uint256> vWorkQueue; - vWorkQueue.push_back(hash); - for (unsigned int i = 0; i < vWorkQueue.size(); i++) - { - uint256 hashPrev = vWorkQueue[i]; - for (multimap<uint256, COrphanBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev); - mi != mapOrphanBlocksByPrev.upper_bound(hashPrev); - ++mi) - { - CBlock block; - { - CDataStream ss(mi->second->vchBlock, SER_DISK, CLIENT_VERSION); - ss >> block; - } - block.BuildMerkleTree(); - // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan resolution (that is, feeding people an invalid block based on LegitBlockX in order to get anyone relaying LegitBlockX banned) - CValidationState stateDummy; - CBlockIndex *pindexChild = NULL; - if (AcceptBlock(block, stateDummy, &pindexChild)) - vWorkQueue.push_back(mi->second->hashBlock); - mapOrphanBlocks.erase(mi->second->hashBlock); - delete mi->second; + // Store to disk + CBlockIndex *pindex = NULL; + bool ret = AcceptBlock(*pblock, state, &pindex, dbp); + if (pindex && pfrom) { + mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId(); } - mapOrphanBlocksByPrev.erase(hashPrev); - } - + if (!ret) + return error("%s : AcceptBlock FAILED", __func__); } if (!ActivateBestChain(state, pblock)) - return error("ProcessBlock() : ActivateBestChain failed"); + return error("%s : ActivateBestChain failed", __func__); return true; } - - - - - - - -CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter) +bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) { - header = block.GetBlockHeader(); - - vector<bool> vMatch; - vector<uint256> vHashes; - - vMatch.reserve(block.vtx.size()); - vHashes.reserve(block.vtx.size()); - - for (unsigned int i = 0; i < block.vtx.size(); i++) - { - const uint256& hash = block.vtx[i].GetHash(); - if (filter.IsRelevantAndUpdate(block.vtx[i])) - { - vMatch.push_back(true); - vMatchedTxn.push_back(make_pair(i, hash)); - } - else - vMatch.push_back(false); - vHashes.push_back(hash); - } - - txn = CPartialMerkleTree(vHashes, vMatch); -} - - - - - - - - -uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) { - if (height == 0) { - // hash at height 0 is the txids themself - return vTxid[pos]; - } else { - // calculate left hash - uint256 left = CalcHash(height-1, pos*2, vTxid), right; - // calculate right hash if not beyong the end of the array - copy left hash otherwise1 - if (pos*2+1 < CalcTreeWidth(height-1)) - right = CalcHash(height-1, pos*2+1, vTxid); - else - right = left; - // combine subhashes - return Hash(BEGIN(left), END(left), BEGIN(right), END(right)); - } -} - -void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) { - // determine whether this node is the parent of at least one matched txid - bool fParentOfMatch = false; - for (unsigned int p = pos << height; p < (pos+1) << height && p < nTransactions; p++) - fParentOfMatch |= vMatch[p]; - // store as flag bit - vBits.push_back(fParentOfMatch); - if (height==0 || !fParentOfMatch) { - // if at height 0, or nothing interesting below, store hash and stop - vHash.push_back(CalcHash(height, pos, vTxid)); - } else { - // otherwise, don't store any hash, but descend into the subtrees - TraverseAndBuild(height-1, pos*2, vTxid, vMatch); - if (pos*2+1 < CalcTreeWidth(height-1)) - TraverseAndBuild(height-1, pos*2+1, vTxid, vMatch); - } -} - -uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch) { - if (nBitsUsed >= vBits.size()) { - // overflowed the bits array - failure - fBad = true; - return 0; - } - bool fParentOfMatch = vBits[nBitsUsed++]; - if (height==0 || !fParentOfMatch) { - // if at height 0, or nothing interesting below, use stored hash and do not descend - if (nHashUsed >= vHash.size()) { - // overflowed the hash array - failure - fBad = true; - return 0; - } - const uint256 &hash = vHash[nHashUsed++]; - if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid - vMatch.push_back(hash); - return hash; - } else { - // otherwise, descend into the subtrees to extract matched txids and hashes - uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch), right; - if (pos*2+1 < CalcTreeWidth(height-1)) - right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch); - else - right = left; - // and combine them before returning - return Hash(BEGIN(left), END(left), BEGIN(right), END(right)); - } -} + AssertLockHeld(cs_main); + assert(pindexPrev == chainActive.Tip()); -CPartialMerkleTree::CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) { - // reset state - vBits.clear(); - vHash.clear(); + CCoinsViewCache viewNew(pcoinsTip); + CBlockIndex indexDummy(block); + indexDummy.pprev = pindexPrev; + indexDummy.nHeight = pindexPrev->nHeight + 1; - // calculate height of tree - int nHeight = 0; - while (CalcTreeWidth(nHeight) > 1) - nHeight++; + // NOTE: CheckBlockHeader is called by CheckBlock + if (!ContextualCheckBlockHeader(block, state, pindexPrev)) + return false; + if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot)) + return false; + if (!ContextualCheckBlock(block, state, pindexPrev)) + return false; + if (!ConnectBlock(block, state, &indexDummy, viewNew, true)) + return false; + assert(state.IsValid()); - // traverse the partial tree - TraverseAndBuild(nHeight, 0, vTxid, vMatch); + return true; } -CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {} - -uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) { - vMatch.clear(); - // An empty set will not work - if (nTransactions == 0) - return 0; - // check for excessively high numbers of transactions - if (nTransactions > MAX_BLOCK_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction - return 0; - // there can never be more hashes provided than one for every txid - if (vHash.size() > nTransactions) - return 0; - // there must be at least one bit per node in the partial tree, and at least one node per hash - if (vBits.size() < vHash.size()) - return 0; - // calculate height of tree - int nHeight = 0; - while (CalcTreeWidth(nHeight) > 1) - nHeight++; - // 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 - if (fBad) - return 0; - // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence) - if ((nBitsUsed+7)/8 != (vBits.size()+7)/8) - return 0; - // verify that all hashes were consumed - if (nHashUsed != vHash.size()) - return 0; - return hashMerkleRoot; -} @@ -2770,10 +2775,12 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) { -bool AbortNode(const std::string &strMessage) { +bool AbortNode(const std::string &strMessage, const std::string &userMessage) { strMiscWarning = strMessage; LogPrintf("*** %s\n", strMessage); - uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_ERROR); + uiInterface.ThreadSafeMessageBox( + userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage, + "", CClientUIInterface::MSG_ERROR); StartShutdown(); return false; } @@ -2784,7 +2791,7 @@ bool CheckDiskSpace(uint64_t nAdditionalBytes) // Check for nMinDiskSpace bytes (currently 50MB) if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) - return AbortNode(_("Error: Disk space is low!")); + return AbortNode("Disk space is low!", _("Error: Disk space is low!")); return true; } @@ -2864,21 +2871,45 @@ bool static LoadBlockIndexDB() BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) { CBlockIndex* pindex = item.second; - pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + pindex->GetBlockWork(); - pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx; - if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS)) - setBlockIndexValid.insert(pindex); + pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex); + if (pindex->nStatus & BLOCK_HAVE_DATA) { + if (pindex->pprev) { + if (pindex->pprev->nChainTx) { + pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx; + } else { + pindex->nChainTx = 0; + mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex)); + } + } else { + pindex->nChainTx = pindex->nTx; + } + } + if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL)) + setBlockIndexCandidates.insert(pindex); if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork)) pindexBestInvalid = pindex; if (pindex->pprev) pindex->BuildSkip(); + if (pindex->IsValid(BLOCK_VALID_TREE) && (pindexBestHeader == NULL || CBlockIndexWorkComparator()(pindexBestHeader, pindex))) + pindexBestHeader = pindex; } // Load block file info pblocktree->ReadLastBlockFile(nLastBlockFile); - LogPrintf("LoadBlockIndexDB(): last block file = %i\n", nLastBlockFile); - if (pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile)) - LogPrintf("LoadBlockIndexDB(): last block file info: %s\n", infoLastBlockFile.ToString()); + vinfoBlockFile.resize(nLastBlockFile + 1); + LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile); + for (int nFile = 0; nFile <= nLastBlockFile; nFile++) { + pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]); + } + LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString()); + for (int nFile = nLastBlockFile + 1; true; nFile++) { + CBlockFileInfo info; + if (pblocktree->ReadBlockFileInfo(nFile, info)) { + vinfoBlockFile.push_back(info); + } else { + break; + } + } // Check presence of blk files LogPrintf("Checking all blk files are present...\n"); @@ -2893,7 +2924,7 @@ bool static LoadBlockIndexDB() for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++) { CDiskBlockPos pos(*it, 0); - if (!CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION)) { + if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) { return false; } } @@ -2912,6 +2943,9 @@ bool static LoadBlockIndexDB() if (it == mapBlockIndex.end()) return true; chainActive.SetTip(it->second); + + PruneBlockIndexCandidates(); + LogPrintf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s progress=%f\n", chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), @@ -2943,7 +2977,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth nCheckDepth = chainActive.Height(); nCheckLevel = std::max(0, std::min(4, nCheckLevel)); LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel); - CCoinsViewCache coins(*coinsview, true); + CCoinsViewCache coins(coinsview); CBlockIndex* pindexState = chainActive.Tip(); CBlockIndex* pindexFailure = NULL; int nGoodTransactions = 0; @@ -2966,7 +3000,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth CBlockUndo undo; CDiskBlockPos pos = pindex->GetUndoPos(); if (!pos.IsNull()) { - if (!undo.ReadFromDisk(pos, pindex->pprev->GetBlockHash())) + if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash())) return error("VerifyDB() : *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); } } @@ -3009,7 +3043,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth void UnloadBlockIndex() { mapBlockIndex.clear(); - setBlockIndexValid.clear(); + setBlockIndexCandidates.clear(); chainActive.SetTip(NULL); pindexBestInvalid = NULL; } @@ -3051,7 +3085,9 @@ bool InitBlockIndex() { return error("LoadBlockIndex() : genesis block not accepted"); if (!ActivateBestChain(state, &block)) return error("LoadBlockIndex() : genesis block cannot be activated"); - } catch(std::runtime_error &e) { + // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data + return FlushStateToDisk(state, FLUSH_STATE_ALWAYS); + } catch (const std::runtime_error& e) { return error("LoadBlockIndex() : failed to initialize block database: %s", e.what()); } } @@ -3061,91 +3097,16 @@ bool InitBlockIndex() { -void PrintBlockTree() -{ - AssertLockHeld(cs_main); - // pre-compute tree structure - map<CBlockIndex*, vector<CBlockIndex*> > mapNext; - for (BlockMap::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) - { - CBlockIndex* pindex = (*mi).second; - mapNext[pindex->pprev].push_back(pindex); - // test - //while (rand() % 3 == 0) - // mapNext[pindex->pprev].push_back(pindex); - } - - vector<pair<int, CBlockIndex*> > vStack; - vStack.push_back(make_pair(0, chainActive.Genesis())); - - int nPrevCol = 0; - while (!vStack.empty()) - { - int nCol = vStack.back().first; - CBlockIndex* pindex = vStack.back().second; - vStack.pop_back(); - - // print split or gap - if (nCol > nPrevCol) - { - for (int i = 0; i < nCol-1; i++) - LogPrintf("| "); - LogPrintf("|\\\n"); - } - else if (nCol < nPrevCol) - { - for (int i = 0; i < nCol; i++) - LogPrintf("| "); - LogPrintf("|\n"); - } - nPrevCol = nCol; - - // print columns - for (int i = 0; i < nCol; i++) - LogPrintf("| "); - - // print item - CBlock block; - ReadBlockFromDisk(block, pindex); - LogPrintf("%d (blk%05u.dat:0x%x) %s tx %u\n", - pindex->nHeight, - pindex->GetBlockPos().nFile, pindex->GetBlockPos().nPos, - DateTimeStrFormat("%Y-%m-%d %H:%M:%S", block.GetBlockTime()), - block.vtx.size()); - - // put the main time-chain first - vector<CBlockIndex*>& vNext = mapNext[pindex]; - for (unsigned int i = 0; i < vNext.size(); i++) - { - if (chainActive.Next(vNext[i])) - { - swap(vNext[0], vNext[i]); - break; - } - } - - // iterate children - for (unsigned int i = 0; i < vNext.size(); i++) - vStack.push_back(make_pair(nCol+i, vNext[i])); - } -} - bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) { + // Map of disk positions for blocks with unknown parent (only used for reindex) + static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent; int64_t nStart = GetTimeMillis(); int nLoaded = 0; try { + // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION); - uint64_t nStartByte = 0; - if (dbp) { - // (try to) skip already indexed part - CBlockFileInfo info; - if (pblocktree->ReadBlockFileInfo(dbp->nFile, info)) { - nStartByte = info.nSize; - blkdat.Seek(info.nSize); - } - } uint64_t nRewind = blkdat.GetPos(); while (!blkdat.eof()) { boost::this_thread::interruption_point(); @@ -3166,35 +3127,72 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) blkdat >> nSize; if (nSize < 80 || nSize > MAX_BLOCK_SIZE) continue; - } catch (const std::exception &) { + } catch (const std::exception&) { // no valid block header found; don't complain break; } try { // read block uint64_t nBlockPos = blkdat.GetPos(); + if (dbp) + dbp->nPos = nBlockPos; blkdat.SetLimit(nBlockPos + nSize); + blkdat.SetPos(nBlockPos); CBlock block; blkdat >> block; nRewind = blkdat.GetPos(); - // process block - if (nBlockPos >= nStartByte) { + // detect out of order blocks, and store them for later + uint256 hash = block.GetHash(); + if (hash != Params().HashGenesisBlock() && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) { + LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(), + block.hashPrevBlock.ToString()); if (dbp) - dbp->nPos = nBlockPos; + mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp)); + continue; + } + + // process in case the block isn't known yet + if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) { CValidationState state; - if (ProcessBlock(state, NULL, &block, dbp)) + if (ProcessNewBlock(state, NULL, &block, dbp)) nLoaded++; if (state.IsError()) break; + } else if (hash != Params().HashGenesisBlock() && mapBlockIndex[hash]->nHeight % 1000 == 0) { + LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight); } - } catch (std::exception &e) { + + // Recursively process earlier encountered successors of this block + deque<uint256> queue; + queue.push_back(hash); + while (!queue.empty()) { + uint256 head = queue.front(); + queue.pop_front(); + std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, std::multimap<uint256, CDiskBlockPos>::iterator> range = mapBlocksUnknownParent.equal_range(head); + while (range.first != range.second) { + std::multimap<uint256, CDiskBlockPos>::iterator it = range.first; + if (ReadBlockFromDisk(block, it->second)) + { + 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)) + { + nLoaded++; + queue.push_back(block.GetHash()); + } + } + range.first++; + mapBlocksUnknownParent.erase(it); + } + } + } catch (const std::exception& e) { LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what()); } } - fclose(fileIn); - } catch(std::runtime_error &e) { - AbortNode(_("Error: system error: ") + e.what()); + } catch (const std::runtime_error& e) { + AbortNode(std::string("System error: ") + e.what()); } if (nLoaded > 0) LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart); @@ -3212,12 +3210,12 @@ string GetWarnings(string strFor) string strStatusBar; string strRPC; - if (GetBoolArg("-testsafemode", false)) - strRPC = "test"; - if (!CLIENT_VERSION_IS_RELEASE) strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications"); + if (GetBoolArg("-testsafemode", false)) + strStatusBar = strRPC = "testsafemode enabled"; + // Misc warnings like out of disk space and clock is wrong if (strMiscWarning != "") { @@ -3283,8 +3281,7 @@ bool static AlreadyHave(const CInv& inv) pcoinsTip->HaveCoins(inv.hash); } case MSG_BLOCK: - return mapBlockIndex.count(inv.hash) || - mapOrphanBlocks.count(inv.hash); + return mapBlockIndex.count(inv.hash); } // Don't know what it is, just say we already got one return true; @@ -3432,10 +3429,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } - { - LOCK(cs_main); - State(pfrom->GetId())->nLastBlockProcess = GetTimeMicros(); - } @@ -3479,12 +3472,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else pfrom->fRelayTxes = true; - if (pfrom->fInbound && addrMe.IsRoutable()) - { - pfrom->addrLocal = addrMe; - SeenLocal(addrMe); - } - // Disconnect if we connected to ourself if (nNonce == nLocalHostNonce && nNonce > 1) { @@ -3493,12 +3480,20 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } + pfrom->addrLocal = addrMe; + if (pfrom->fInbound && addrMe.IsRoutable()) + { + SeenLocal(addrMe); + } + // Be shy and don't send version until we hear if (pfrom->fInbound) pfrom->PushVersion(); pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); + // Potentially mark this peer as a preferred download peer. + UpdatePreferredDownload(pfrom, State(pfrom->GetId())); // Change version pfrom->PushMessage("verack"); @@ -3511,7 +3506,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { CAddress addr = GetLocalAddress(&pfrom->addr); if (addr.IsRoutable()) + { + pfrom->PushAddress(addr); + } else if (IsPeerAddrLocalGood(pfrom)) { + addr.SetIP(pfrom->addrLocal); pfrom->PushAddress(addr); + } } // Get recent addresses @@ -3644,6 +3644,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LOCK(cs_main); + std::vector<CInv> vToFetch; + for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) { const CInv &inv = vInv[nInv]; @@ -3654,19 +3656,32 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, bool fAlreadyHave = AlreadyHave(inv); LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id); - if (!fAlreadyHave) { - if (!fImporting && !fReindex) { - if (inv.type == MSG_BLOCK) - AddBlockToQueue(pfrom->GetId(), inv.hash); - else - pfrom->AskFor(inv); - } - } else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) { - PushGetBlocks(pfrom, chainActive.Tip(), GetOrphanRoot(inv.hash)); - } + if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK) + pfrom->AskFor(inv); - if (inv.type == MSG_BLOCK) + 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 + // 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, + // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the + // time the block arrives, the header chain leading up to it is already validated. Not + // doing this will result in the received block being rejected as an orphan in case it is + // not a direct successor. + pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash); + CNodeState *nodestate = State(pfrom->GetId()); + if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20 && + nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { + 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); + } + LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id); + } + } // Track requests for our stuff g_signals.Inventory(inv.hash); @@ -3676,6 +3691,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return error("send buffer size() = %u", pfrom->nSendSize); } } + + if (!vToFetch.empty()) + pfrom->PushMessage("getdata", vToFetch); } @@ -3709,7 +3727,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LOCK(cs_main); // Find the last block the caller has in the main chain - CBlockIndex* pindex = chainActive.FindFork(locator); + CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator); // Send the rest of the chain if (pindex) @@ -3756,15 +3774,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else { // Find the last block the caller has in the main chain - pindex = chainActive.FindFork(locator); + pindex = FindForkInGlobalIndex(chainActive, locator); if (pindex) pindex = chainActive.Next(pindex); } // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end vector<CBlock> vHeaders; - int nLimit = 2000; - LogPrint("net", "getheaders %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString()); + int nLimit = MAX_HEADERS_RESULTS; + LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->id); for (; pindex; pindex = chainActive.Next(pindex)) { vHeaders.push_back(pindex->GetBlockHeader()); @@ -3876,36 +3894,81 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->id, pfrom->cleanSubVer, state.GetRejectReason()); pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), - state.GetRejectReason(), inv.hash); + state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) Misbehaving(pfrom->GetId(), nDoS); } } + else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing + { + std::vector<CBlockHeader> headers; + + // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks. + unsigned int nCount = ReadCompactSize(vRecv); + if (nCount > MAX_HEADERS_RESULTS) { + Misbehaving(pfrom->GetId(), 20); + return error("headers message size = %u", nCount); + } + headers.resize(nCount); + for (unsigned int n = 0; n < nCount; n++) { + vRecv >> headers[n]; + ReadCompactSize(vRecv); // ignore tx count; assume it is 0. + } + + LOCK(cs_main); + + if (nCount == 0) { + // Nothing interesting. Stop asking this peers for more headers. + return true; + } + + CBlockIndex *pindexLast = NULL; + BOOST_FOREACH(const CBlockHeader& header, headers) { + CValidationState state; + if (pindexLast != NULL && header.hashPrevBlock != pindexLast->GetBlockHash()) { + Misbehaving(pfrom->GetId(), 20); + return error("non-continuous headers sequence"); + } + if (!AcceptBlockHeader(header, state, &pindexLast)) { + int nDoS; + if (state.IsInvalid(nDoS)) { + if (nDoS > 0) + Misbehaving(pfrom->GetId(), nDoS); + return error("invalid header received"); + } + } + } + + if (pindexLast) + UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash()); + + if (nCount == MAX_HEADERS_RESULTS && pindexLast) { + // Headers message had its maximum size; the peer may have more headers. + // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue + // from there instead. + LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight); + pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256(0)); + } + } + else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing { CBlock block; vRecv >> block; - LogPrint("net", "received block %s peer=%d\n", block.GetHash().ToString(), pfrom->id); - CInv inv(MSG_BLOCK, block.GetHash()); - pfrom->AddInventoryKnown(inv); + LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id); - { - LOCK(cs_main); - // Remember who we got this block from. - mapBlockSource[inv.hash] = pfrom->GetId(); - MarkBlockAsReceived(inv.hash, pfrom->GetId()); - } + pfrom->AddInventoryKnown(inv); CValidationState state; - ProcessBlock(state, pfrom, &block); + ProcessNewBlock(state, pfrom, &block); int nDoS; if (state.IsInvalid(nDoS)) { pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), - state.GetRejectReason(), inv.hash); + state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) { LOCK(cs_main); Misbehaving(pfrom->GetId(), nDoS); @@ -4112,7 +4175,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (fDebug) { try { string strMsg; unsigned char ccode; string strReason; - vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, 111); + vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH); ostringstream ss; ss << strMsg << " code " << itostr(ccode) << ": " << strReason; @@ -4124,7 +4187,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, ss << ": hash " << hash.ToString(); } LogPrint("net", "Reject %s\n", SanitizeString(ss.str())); - } catch (std::ios_base::failure& e) { + } catch (const std::ios_base::failure&) { // Avoid feedback loops by preventing reject messages from triggering a new reject message. LogPrint("net", "Unparseable reject message received\n"); } @@ -4228,7 +4291,7 @@ bool ProcessMessages(CNode* pfrom) fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime); boost::this_thread::interruption_point(); } - catch (std::ios_base::failure& e) + catch (const std::ios_base::failure& e) { pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message")); if (strstr(e.what(), "end of data")) @@ -4246,10 +4309,10 @@ bool ProcessMessages(CNode* pfrom) PrintExceptionContinue(&e, "ProcessMessages()"); } } - catch (boost::thread_interrupted) { + catch (const boost::thread_interrupted&) { throw; } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, "ProcessMessages()"); } catch (...) { PrintExceptionContinue(NULL, "ProcessMessages()"); @@ -4313,24 +4376,18 @@ bool SendMessages(CNode* pto, bool fSendTrickle) static int64_t nLastRebroadcast; if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60)) { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - { - // Periodically clear setAddrKnown to allow refresh broadcasts - if (nLastRebroadcast) - pnode->setAddrKnown.clear(); + // Periodically clear setAddrKnown to allow refresh broadcasts + if (nLastRebroadcast) + pnode->setAddrKnown.clear(); - // Rebroadcast our address - if (fListen) - { - CAddress addr = GetLocalAddress(&pnode->addr); - if (addr.IsRoutable()) - pnode->PushAddress(addr); - } - } + // Rebroadcast our address + AdvertizeLocal(pnode); } - nLastRebroadcast = GetTime(); + if (!vNodes.empty()) + nLastRebroadcast = GetTime(); } // @@ -4380,9 +4437,18 @@ bool SendMessages(CNode* pto, bool fSendTrickle) state.rejects.clear(); // Start block sync - if (pto->fStartSync && !fImporting && !fReindex) { - pto->fStartSync = false; - PushGetBlocks(pto, chainActive.Tip(), uint256(0)); + if (pindexBestHeader == NULL) + pindexBestHeader = chainActive.Tip(); + bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do. + if (!state.fSyncStarted && !pto->fClient && fFetch && !fImporting && !fReindex) { + // Only actively request headers from a single peer, unless we're close to today. + if (nSyncStarted == 0 || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) { + state.fSyncStarted = true; + nSyncStarted++; + CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader; + LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight); + pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256(0)); + } } // Resend wallet transactions that haven't gotten in a block yet @@ -4441,35 +4507,35 @@ bool SendMessages(CNode* pto, bool fSendTrickle) if (!vInv.empty()) pto->PushMessage("inv", vInv); - - // Detect stalled peers. Require that blocks are in flight, we haven't - // received a (requested) block in one minute, and that all blocks are - // in flight for over two minutes, since we first had a chance to - // process an incoming block. + // Detect whether we're stalling int64_t nNow = GetTimeMicros(); - if (!pto->fDisconnect && state.nBlocksInFlight && - state.nLastBlockReceive < state.nLastBlockProcess - BLOCK_DOWNLOAD_TIMEOUT*1000000 && - state.vBlocksInFlight.front().nTime < state.nLastBlockProcess - 2*BLOCK_DOWNLOAD_TIMEOUT*1000000) { - LogPrintf("Peer %s is stalling block download, disconnecting\n", state.name); + if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) { + // Stalling only triggers when the block download window cannot move. During normal steady state, + // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection + // should only happen during initial block download. + LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id); pto->fDisconnect = true; } - // Update knowledge of peer's block availability. - ProcessBlockAvailability(pto->GetId()); - // // Message: getdata (blocks) // vector<CInv> vGetData; - while (!pto->fDisconnect && state.nBlocksToDownload && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { - uint256 hash = state.vBlocksToDownload.front(); - vGetData.push_back(CInv(MSG_BLOCK, hash)); - MarkBlockAsInFlight(pto->GetId(), hash); - LogPrint("net", "Requesting block %s peer=%d\n", hash.ToString(), pto->id); - if (vGetData.size() >= 1000) - { - pto->PushMessage("getdata", vGetData); - vGetData.clear(); + if (!pto->fDisconnect && !pto->fClient && fFetch && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { + vector<CBlockIndex*> vToDownload; + NodeId staller = -1; + FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller); + BOOST_FOREACH(CBlockIndex *pindex, vToDownload) { + vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash())); + MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), pindex); + LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(), + pindex->nHeight, pto->id); + } + if (state.nBlocksInFlight == 0 && staller != -1) { + if (State(staller)->nStallingSince == 0) { + State(staller)->nStallingSince = nNow; + LogPrint("net", "Stall started peer=%d\n", staller); + } } } @@ -4499,66 +4565,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle) return true; } - -bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock) -{ - // Open history file to append - CAutoFile fileout = CAutoFile(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); - if (!fileout) - return error("CBlockUndo::WriteToDisk : OpenUndoFile failed"); - - // Write index header - unsigned int nSize = fileout.GetSerializeSize(*this); - fileout << FLATDATA(Params().MessageStart()) << nSize; - - // Write undo data - long fileOutPos = ftell(fileout); - if (fileOutPos < 0) - return error("CBlockUndo::WriteToDisk : ftell failed"); - pos.nPos = (unsigned int)fileOutPos; - fileout << *this; - - // calculate & write checksum - CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); - hasher << hashBlock; - hasher << *this; - fileout << hasher.GetHash(); - - // Flush stdio buffers and commit to disk before returning - fflush(fileout); - if (!IsInitialBlockDownload()) - FileCommit(fileout); - - return true; -} - -bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock) -{ - // Open history file to read - CAutoFile filein = CAutoFile(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); - if (!filein) - return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed"); - - // Read block - uint256 hashChecksum; - try { - filein >> *this; - filein >> hashChecksum; - } - catch (std::exception &e) { - return error("%s : Deserialize or I/O error - %s", __func__, e.what()); - } - - // Verify checksum - CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION); - hasher << hashBlock; - hasher << *this; - if (hashChecksum != hasher.GetHash()) - return error("CBlockUndo::ReadFromDisk : Checksum mismatch"); - - return true; -} - std::string CBlockFileInfo::ToString() const { return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst), DateTimeStrFormat("%Y-%m-%d", nTimeLast)); } @@ -4576,12 +4582,6 @@ public: delete (*it1).second; mapBlockIndex.clear(); - // orphan blocks - std::map<uint256, COrphanBlock*>::iterator it2 = mapOrphanBlocks.begin(); - for (; it2 != mapOrphanBlocks.end(); it2++) - delete (*it2).second; - mapOrphanBlocks.clear(); - // orphan transactions mapOrphanTransactions.clear(); mapOrphanTransactionsByPrev.clear(); diff --git a/src/main.h b/src/main.h index 5acc551793..9049f5bb7d 100644 --- a/src/main.h +++ b/src/main.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_MAIN_H @@ -10,14 +10,19 @@ #include "config/bitcoin-config.h" #endif +#include "amount.h" +#include "chain.h" #include "chainparams.h" #include "coins.h" -#include "core.h" +#include "primitives/block.h" +#include "primitives/transaction.h" #include "net.h" #include "pow.h" #include "script/script.h" +#include "script/sigcache.h" #include "script/standard.h" #include "sync.h" +#include "tinyformat.h" #include "txmempool.h" #include "uint256.h" @@ -33,11 +38,16 @@ #include <boost/unordered_map.hpp> class CBlockIndex; +class CBlockTreeDB; class CBloomFilter; class CInv; +class CScriptCheck; +class CValidationInterface; +class CValidationState; + +struct CBlockTemplate; +struct CNodeStateStats; -/** The maximum allowed size for a serialized block, in bytes (network rule) */ -static const unsigned int MAX_BLOCK_SIZE = 1000000; /** 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; @@ -47,14 +57,12 @@ static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 50000; static const unsigned int MAX_STANDARD_TX_SIZE = 100000; /** The maximum allowed number of signature check operations in a block (network rule) */ static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; -/** Maxiumum number of signature check operations in an IsStandard() P2SH script */ +/** 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_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; -/** Default for -maxorphanblocks, maximum number of orphan blocks kept in memory */ -static const unsigned int DEFAULT_MAX_ORPHAN_BLOCKS = 750; /** 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) */ @@ -70,11 +78,23 @@ static const int MAX_SCRIPTCHECK_THREADS = 16; /** -par default (number of script-checking threads, 0 = auto) */ static const int DEFAULT_SCRIPTCHECK_THREADS = 0; /** Number of blocks that can be requested at any given time from a single peer. */ -static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 128; -/** Timeout in seconds before considering a block download peer unresponsive. */ -static const unsigned int BLOCK_DOWNLOAD_TIMEOUT = 60; - -/** "reject" message codes **/ +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. */ +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; +/** 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; @@ -108,26 +128,18 @@ extern bool fIsBareMultisigStd; extern unsigned int nCoinCacheSize; extern CFeeRate minRelayTxFee; -// Minimum disk space required - used in CheckDiskSpace() -static const uint64_t nMinDiskSpace = 52428800; - - -class CBlockTreeDB; -struct CDiskBlockPos; -class CTxUndo; -class CScriptCheck; -class CValidationState; -class CWalletInterface; -struct CNodeStateStats; +/** Best header we've seen so far (used for getheaders queries' starting points). */ +extern CBlockIndex *pindexBestHeader; -struct CBlockTemplate; +/** Minimum disk space required - used in CheckDiskSpace() */ +static const uint64_t nMinDiskSpace = 52428800; /** Register a wallet to receive updates from core */ -void RegisterWallet(CWalletInterface* pwalletIn); +void RegisterValidationInterface(CValidationInterface* pwalletIn); /** Unregister a wallet from core */ -void UnregisterWallet(CWalletInterface* pwalletIn); +void UnregisterValidationInterface(CValidationInterface* pwalletIn); /** Unregister all wallets from core */ -void UnregisterAllWallets(); +void UnregisterAllValidationInterfaces(); /** Push an updated transaction to all registered wallets */ void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL); @@ -136,10 +148,18 @@ void RegisterNodeSignals(CNodeSignals& nodeSignals); /** Unregister a network node */ void UnregisterNodeSignals(CNodeSignals& nodeSignals); -void PushGetBlocks(CNode* pnode, CBlockIndex* pindexBegin, uint256 hashEnd); - -/** Process an incoming block */ -bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp = NULL); +/** + * Process an incoming block. This only returns after the best known valid + * block is made active. Note that it does not, however, guarantee that the + * specific block passed to it has been checked for validity! + * + * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface - 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[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); /** Check whether enough disk space is available for an incoming block */ bool CheckDiskSpace(uint64_t nAdditionalBytes = 0); /** Open a block file (blk?????.dat) */ @@ -156,8 +176,6 @@ bool InitBlockIndex(); bool LoadBlockIndex(); /** Unload database information */ void UnloadBlockIndex(); -/** Print the loaded block tree */ -void PrintBlockTree(); /** Process protocol messages received from a given node */ bool ProcessMessages(CNode* pfrom); /** Send queued protocol messages to be sent to a give node */ @@ -172,16 +190,18 @@ std::string GetWarnings(std::string strFor); 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); -int64_t GetBlockValue(int nHeight, int64_t nFees); +CAmount GetBlockValue(int nHeight, const CAmount& nFees); /** 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); +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. */ void Misbehaving(NodeId nodeid, int howmuch); +/** Flush all state, indexes and buffers to disk. */ +void FlushStateToDisk(); /** (try to) add transaction to memory pool **/ @@ -189,49 +209,11 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa bool* pfMissingInputs, bool fRejectInsaneFee=false); - - - - - - struct CNodeStateStats { int nMisbehavior; int nSyncHeight; -}; - -struct CDiskBlockPos -{ - int nFile; - unsigned int nPos; - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(VARINT(nFile)); - READWRITE(VARINT(nPos)); - } - - CDiskBlockPos() { - SetNull(); - } - - CDiskBlockPos(int nFileIn, unsigned int nPosIn) { - nFile = nFileIn; - nPos = nPosIn; - } - - friend bool operator==(const CDiskBlockPos &a, const CDiskBlockPos &b) { - return (a.nFile == b.nFile && a.nPos == b.nPos); - } - - friend bool operator!=(const CDiskBlockPos &a, const CDiskBlockPos &b) { - return !(a == b); - } - - void SetNull() { nFile = -1; nPos = 0; } - bool IsNull() const { return (nFile == -1); } + int nCommonHeight; + std::vector<int> vHeightInFlight; }; struct CDiskTxPos : public CDiskBlockPos @@ -260,81 +242,69 @@ struct CDiskTxPos : public CDiskBlockPos }; -int64_t GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree); +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 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 -*/ +/** + * 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 - @see CTransaction::FetchInputs -*/ +/** + * Count ECDSA signature operations the old-fashioned (pre-0.6) way + * @return number of sigops this transaction's outputs will produce when spent + * @see CTransaction::FetchInputs + */ unsigned int GetLegacySigOpCount(const CTransaction& tx); -/** Count ECDSA signature operations in pay-to-script-hash inputs. - - @param[in] mapInputs Map of previous transactions that have outputs we're spending - @return maximum number of sigops required to validate this transaction's inputs - @see CTransaction::FetchInputs +/** + * Count ECDSA signature operations in pay-to-script-hash inputs. + * + * @param[in] mapInputs Map of previous transactions that have outputs we're spending + * @return maximum number of sigops required to validate this transaction's inputs + * @see CTransaction::FetchInputs */ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& mapInputs); -// Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts) -// This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it -// instead of being performed inline. -bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks = true, - unsigned int flags = STANDARD_SCRIPT_VERIFY_FLAGS, - std::vector<CScriptCheck> *pvChecks = NULL); +/** + * Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts) + * This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it + * instead of being performed inline. + */ +bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks, + unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks = NULL); -// Apply the effects of this transaction on the UTXO set represented by view -void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight); +/** Apply the effects of this transaction on the UTXO set represented by view */ +void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight); -// Context-independent validity checks +/** 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 -*/ + * @return True if all outputs (scriptPubKeys) use only standard transaction forms + */ bool IsStandardTx(const CTransaction& tx, std::string& reason); bool IsFinalTx(const CTransaction &tx, int nBlockHeight = 0, int64_t nBlockTime = 0); -/** Undo information for a CBlock */ -class CBlockUndo -{ -public: - std::vector<CTxUndo> vtxundo; // for all but the coinbase - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(vtxundo); - } - - bool WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock); - bool ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock); -}; - - -/** Closure representing one script verification - * Note that this stores references to the spending transaction */ +/** + * Closure representing one script verification + * Note that this stores references to the spending transaction + */ class CScriptCheck { private: @@ -342,124 +312,30 @@ private: const CTransaction *ptxTo; unsigned int nIn; unsigned int nFlags; + bool cacheStore; + ScriptError error; public: - CScriptCheck(): ptxTo(0), nIn(0), nFlags(0) {} - CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn) : + CScriptCheck(): ptxTo(0), nIn(0), nFlags(0), cacheStore(false), error(SCRIPT_ERR_UNKNOWN_ERROR) {} + CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn) : scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey), - ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn) { } + ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), error(SCRIPT_ERR_UNKNOWN_ERROR) { } - bool operator()() const; + bool operator()(); void swap(CScriptCheck &check) { scriptPubKey.swap(check.scriptPubKey); std::swap(ptxTo, check.ptxTo); std::swap(nIn, check.nIn); std::swap(nFlags, check.nFlags); + std::swap(cacheStore, check.cacheStore); + std::swap(error, check.error); } -}; - -/** Data structure that represents a partial merkle tree. - * - * It respresents a subset of the txid's of a known block, in a way that - * allows recovery of the list of txid's and the merkle root, in an - * authenticated way. - * - * The encoding works as follows: we traverse the tree in depth-first order, - * storing a bit for each traversed node, signifying whether the node is the - * parent of at least one matched leaf txid (or a matched txid itself). In - * case we are at the leaf level, or this bit is 0, its merkle node hash is - * stored, and its children are not explorer further. Otherwise, no hash is - * stored, but we recurse into both (or the only) child branch. During - * decoding, the same depth-first traversal is performed, consuming bits and - * hashes as they written during encoding. - * - * The serialization is fixed and provides a hard guarantee about the - * encoded size: - * - * SIZE <= 10 + ceil(32.25*N) - * - * Where N represents the number of leaf nodes of the partial tree. N itself - * is bounded by: - * - * N <= total_transactions - * N <= 1 + matched_transactions*tree_height - * - * The serialization format: - * - uint32 total_transactions (4 bytes) - * - varint number of hashes (1-3 bytes) - * - uint256[] hashes in depth-first order (<= 32*N bytes) - * - varint number of bytes of flag bits (1-3 bytes) - * - byte[] flag bits, packed per 8 in a byte, least significant bit first (<= 2*N-1 bits) - * The size constraints follow from this. - */ -class CPartialMerkleTree -{ -protected: - // the total number of transactions in the block - unsigned int nTransactions; - - // node-is-parent-of-matched-txid bits - std::vector<bool> vBits; - - // txids and internal hashes - std::vector<uint256> vHash; - - // flag set when encountering invalid data - bool fBad; - - // helper function to efficiently calculate the number of nodes at given height in the merkle tree - unsigned int CalcTreeWidth(int height) { - return (nTransactions+(1 << height)-1) >> height; - } - - // calculate the hash of a node in the merkle tree (at leaf level: the txid's themself) - uint256 CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid); - - // recursive function that traverses tree nodes, storing the data as bits and hashes - void TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch); - - // recursive function that traverses tree nodes, consuming the bits and hashes produced by TraverseAndBuild. - // it returns the hash of the respective node. - uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch); - -public: - - // serialization implementation - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(nTransactions); - READWRITE(vHash); - std::vector<unsigned char> vBytes; - if (ser_action.ForRead()) { - READWRITE(vBytes); - CPartialMerkleTree &us = *(const_cast<CPartialMerkleTree*>(this)); - us.vBits.resize(vBytes.size() * 8); - for (unsigned int p = 0; p < us.vBits.size(); p++) - us.vBits[p] = (vBytes[p / 8] & (1 << (p % 8))) != 0; - us.fBad = false; - } else { - vBytes.resize((vBits.size()+7)/8); - for (unsigned int p = 0; p < vBits.size(); p++) - vBytes[p / 8] |= vBits[p] << (p % 8); - READWRITE(vBytes); - } - } - - // Construct a partial merkle tree from a list of transaction id's, and a mask that selects a subset of them - CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch); - - CPartialMerkleTree(); - // extract the matching txid's represented by this partial merkle tree. - // returns the merkle root, or 0 in case of failure - uint256 ExtractMatches(std::vector<uint256> &vMatch); + ScriptError GetScriptError() const { return error; } }; - /** Functions for disk access for blocks */ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos); bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos); @@ -474,33 +350,36 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex); * of problems. Note that in any case, coins may be modified. */ bool DisconnectBlock(CBlock& block, CValidationState& state, 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(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false); - -// Add this block to the block index, and if necessary, switch the active block chain to this -bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos& pos); +/** Apply the effects of this block (with given index) on the UTXO set represented by coins */ +bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false); -// Context-independent validity checks +/** Context-independent validity checks */ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true); bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true); -// Store block on disk -// if dbp is provided, the file is known to already reside on disk +/** Context-dependent validity checks */ +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev); +bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev); + +/** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */ +bool TestBlockValidity(CValidationState &state, const 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); -bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL); +bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL); class CBlockFileInfo { public: - unsigned int nBlocks; // number of blocks stored in file - unsigned int nSize; // number of used bytes of block file - unsigned int nUndoSize; // number of used bytes in the undo file - unsigned int nHeightFirst; // lowest height of block in file - unsigned int nHeightLast; // highest height of block in file - uint64_t nTimeFirst; // earliest time of block in file - uint64_t nTimeLast; // latest time of block in file + unsigned int nBlocks; //! number of blocks stored in file + unsigned int nSize; //! number of used bytes of block file + unsigned int nUndoSize; //! number of used bytes in the undo file + unsigned int nHeightFirst; //! lowest height of block in file + unsigned int nHeightLast; //! highest height of block in file + uint64_t nTimeFirst; //! earliest time of block in file + uint64_t nTimeLast; //! latest time of block in file ADD_SERIALIZE_METHODS; @@ -531,7 +410,7 @@ public: std::string ToString() const; - // update statistics (does not update nSize) + /** update statistics (does not update nSize) */ void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) { if (nBlocks==0 || nHeightFirst > nHeightIn) nHeightFirst = nHeightIn; @@ -545,295 +424,13 @@ public: } }; -enum BlockStatus { - BLOCK_VALID_UNKNOWN = 0, - BLOCK_VALID_HEADER = 1, // parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future - BLOCK_VALID_TREE = 2, // parent found, difficulty matches, timestamp >= median previous, checkpoint - BLOCK_VALID_TRANSACTIONS = 3, // only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids, sigops, size, merkle root - BLOCK_VALID_CHAIN = 4, // outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30 - BLOCK_VALID_SCRIPTS = 5, // scripts/signatures ok - BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS | - BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS, - - BLOCK_HAVE_DATA = 8, // full block available in blk*.dat - BLOCK_HAVE_UNDO = 16, // undo data available in rev*.dat - BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO, - - BLOCK_FAILED_VALID = 32, // stage after last reached validness failed - BLOCK_FAILED_CHILD = 64, // descends from failed block - BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, -}; - -/** The block chain is a tree shaped structure starting with the - * genesis block at the root, with each block potentially having multiple - * candidates to be the next block. A blockindex may have multiple pprev pointing - * to it, but at most one of them can be part of the currently active branch. - */ -class CBlockIndex -{ -public: - // pointer to the hash of the block, if any. memory is owned by this CBlockIndex - const uint256* phashBlock; - - // pointer to the index of the predecessor of this block - CBlockIndex* pprev; - - // pointer to the index of some further predecessor of this block - CBlockIndex* pskip; - - // height of the entry in the chain. The genesis block has height 0 - int nHeight; - - // Which # file this block is stored in (blk?????.dat) - int nFile; - - // Byte offset within blk?????.dat where this block's data is stored - unsigned int nDataPos; - - // Byte offset within rev?????.dat where this block's undo data is stored - unsigned int nUndoPos; - - // (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block - uint256 nChainWork; - - // Number of transactions in this block. - // Note: in a potential headers-first mode, this number cannot be relied upon - unsigned int nTx; - - // (memory only) Number of transactions in the chain up to and including this block - unsigned int nChainTx; // change to 64-bit type when necessary; won't happen before 2030 - - // Verification status of this block. See enum BlockStatus - unsigned int nStatus; - - // block header - int nVersion; - uint256 hashMerkleRoot; - unsigned int nTime; - unsigned int nBits; - unsigned int nNonce; - - // (memory only) Sequencial id assigned to distinguish order in which blocks are received. - uint32_t nSequenceId; - - void SetNull() - { - phashBlock = NULL; - pprev = NULL; - pskip = NULL; - nHeight = 0; - nFile = 0; - nDataPos = 0; - nUndoPos = 0; - nChainWork = 0; - nTx = 0; - nChainTx = 0; - nStatus = 0; - nSequenceId = 0; - - nVersion = 0; - hashMerkleRoot = 0; - nTime = 0; - nBits = 0; - nNonce = 0; - } - - CBlockIndex() - { - SetNull(); - } - - CBlockIndex(CBlockHeader& block) - { - SetNull(); - - nVersion = block.nVersion; - hashMerkleRoot = block.hashMerkleRoot; - nTime = block.nTime; - nBits = block.nBits; - nNonce = block.nNonce; - } - - CDiskBlockPos GetBlockPos() const { - CDiskBlockPos ret; - if (nStatus & BLOCK_HAVE_DATA) { - ret.nFile = nFile; - ret.nPos = nDataPos; - } - return ret; - } - - CDiskBlockPos GetUndoPos() const { - CDiskBlockPos ret; - if (nStatus & BLOCK_HAVE_UNDO) { - ret.nFile = nFile; - ret.nPos = nUndoPos; - } - return ret; - } - - CBlockHeader GetBlockHeader() const - { - CBlockHeader block; - block.nVersion = nVersion; - if (pprev) - block.hashPrevBlock = pprev->GetBlockHash(); - block.hashMerkleRoot = hashMerkleRoot; - block.nTime = nTime; - block.nBits = nBits; - block.nNonce = nNonce; - return block; - } - - uint256 GetBlockHash() const - { - return *phashBlock; - } - - int64_t GetBlockTime() const - { - return (int64_t)nTime; - } - - uint256 GetBlockWork() const - { - return GetProofIncrement(nBits); - } - - enum { nMedianTimeSpan=11 }; - - int64_t GetMedianTimePast() const - { - int64_t pmedian[nMedianTimeSpan]; - int64_t* pbegin = &pmedian[nMedianTimeSpan]; - int64_t* pend = &pmedian[nMedianTimeSpan]; - - const CBlockIndex* pindex = this; - for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) - *(--pbegin) = pindex->GetBlockTime(); - - std::sort(pbegin, pend); - return pbegin[(pend - pbegin)/2]; - } - - /** - * 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. - */ - static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, - unsigned int nRequired); - - std::string ToString() const - { - return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", - pprev, nHeight, - hashMerkleRoot.ToString(), - GetBlockHash().ToString()); - } - - // Check whether this block index entry is valid up to the passed validity level. - bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const - { - assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed. - if (nStatus & BLOCK_FAILED_MASK) - return false; - return ((nStatus & BLOCK_VALID_MASK) >= nUpTo); - } - - // Raise the validity level of this block index entry. - // Returns true if the validity was changed. - bool RaiseValidity(enum BlockStatus nUpTo) - { - assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed. - if (nStatus & BLOCK_FAILED_MASK) - return false; - if ((nStatus & BLOCK_VALID_MASK) < nUpTo) { - nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo; - return true; - } - return false; - } - - // Build the skiplist pointer for this entry. - void BuildSkip(); - - // Efficiently find an ancestor of this block. - CBlockIndex* GetAncestor(int height); - const CBlockIndex* GetAncestor(int height) const; -}; - -/** Used to marshal pointers into hashes for db storage. */ -class CDiskBlockIndex : public CBlockIndex -{ -public: - uint256 hashPrev; - - CDiskBlockIndex() { - hashPrev = 0; - } - - explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) { - hashPrev = (pprev ? pprev->GetBlockHash() : 0); - } - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - if (!(nType & SER_GETHASH)) - READWRITE(VARINT(nVersion)); - - READWRITE(VARINT(nHeight)); - READWRITE(VARINT(nStatus)); - READWRITE(VARINT(nTx)); - if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO)) - READWRITE(VARINT(nFile)); - if (nStatus & BLOCK_HAVE_DATA) - READWRITE(VARINT(nDataPos)); - if (nStatus & BLOCK_HAVE_UNDO) - READWRITE(VARINT(nUndoPos)); - - // block header - READWRITE(this->nVersion); - READWRITE(hashPrev); - READWRITE(hashMerkleRoot); - READWRITE(nTime); - READWRITE(nBits); - READWRITE(nNonce); - } - - uint256 GetBlockHash() const - { - CBlockHeader block; - block.nVersion = nVersion; - block.hashPrevBlock = hashPrev; - block.hashMerkleRoot = hashMerkleRoot; - block.nTime = nTime; - block.nBits = nBits; - block.nNonce = nNonce; - return block.GetHash(); - } - - - std::string ToString() const - { - std::string str = "CDiskBlockIndex("; - str += CBlockIndex::ToString(); - str += strprintf("\n hashBlock=%s, hashPrev=%s)", - GetBlockHash().ToString(), - hashPrev.ToString()); - return str; - } -}; - /** 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_VALID, //! everything ok + MODE_INVALID, //! network rule violation (DoS value may be set) + MODE_ERROR, //! run-time error } mode; int nDoS; std::string strRejectReason; @@ -898,65 +495,14 @@ public: bool VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth); }; -/** An in-memory indexed chain of blocks. */ -class CChain { -private: - std::vector<CBlockIndex*> vChain; - -public: - /** Returns the index entry for the genesis block of this chain, or NULL if none. */ - CBlockIndex *Genesis() const { - return vChain.size() > 0 ? vChain[0] : NULL; - } - - /** Returns the index entry for the tip of this chain, or NULL if none. */ - CBlockIndex *Tip() const { - return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL; - } - - /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */ - CBlockIndex *operator[](int nHeight) const { - if (nHeight < 0 || nHeight >= (int)vChain.size()) - return NULL; - return vChain[nHeight]; - } +/** Find the last common block between the parameter chain and a locator. */ +CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator); - /** Compare two chains efficiently. */ - friend bool operator==(const CChain &a, const CChain &b) { - return a.vChain.size() == b.vChain.size() && - a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1]; - } +/** Mark a block as invalid. */ +bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex); - /** Efficiently check whether a block is present in this chain. */ - bool Contains(const CBlockIndex *pindex) const { - return (*this)[pindex->nHeight] == pindex; - } - - /** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */ - CBlockIndex *Next(const CBlockIndex *pindex) const { - if (Contains(pindex)) - return (*this)[pindex->nHeight + 1]; - else - return NULL; - } - - /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */ - int Height() const { - return vChain.size() - 1; - } - - /** Set/initialize a chain with a given tip. Returns the forking point. */ - CBlockIndex *SetTip(CBlockIndex *pindex); - - /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */ - CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const; - - /** Find the last common block between this chain and a locator. */ - CBlockIndex *FindFork(const CBlockLocator &locator) const; - - /** Find the last common block between this chain and a block index entry. */ - const CBlockIndex *FindFork(const CBlockIndex *pindex) const; -}; +/** Remove invalidity status from a block and its descendants. */ +bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex); /** The currently-connected chain of blocks. */ extern CChain chainActive; @@ -970,7 +516,7 @@ extern CBlockTreeDB *pblocktree; struct CBlockTemplate { CBlock block; - std::vector<int64_t> vTxFees; + std::vector<CAmount> vTxFees; std::vector<int64_t> vTxSigOps; }; @@ -979,47 +525,18 @@ struct CBlockTemplate -/** Used to relay blocks as header + vector<merkle branch> - * to filtered nodes. - */ -class CMerkleBlock -{ -public: - // Public only for unit testing - CBlockHeader header; - CPartialMerkleTree txn; - -public: - // Public only for unit testing and relay testing - // (not relayed) - std::vector<std::pair<unsigned int, uint256> > vMatchedTxn; - - // Create from a CBlock, filtering transactions according to filter - // Note that this will call IsRelevantAndUpdate on the filter for each transaction, - // thus the filter will likely be modified. - CMerkleBlock(const CBlock& block, CBloomFilter& filter); - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(header); - READWRITE(txn); - } -}; - - -class CWalletInterface { +class CValidationInterface { protected: - virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) =0; - virtual void EraseFromWallet(const uint256 &hash) =0; - virtual void SetBestChain(const CBlockLocator &locator) =0; - virtual void UpdatedTransaction(const uint256 &hash) =0; - virtual void Inventory(const uint256 &hash) =0; - virtual void ResendWalletTransactions() =0; - friend void ::RegisterWallet(CWalletInterface*); - friend void ::UnregisterWallet(CWalletInterface*); - friend void ::UnregisterAllWallets(); + 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() {}; + virtual void BlockChecked(const CBlock&, const CValidationState&) {}; + friend void ::RegisterValidationInterface(CValidationInterface*); + friend void ::UnregisterValidationInterface(CValidationInterface*); + friend void ::UnregisterAllValidationInterfaces(); }; #endif // BITCOIN_MAIN_H diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp new file mode 100644 index 0000000000..1b7ee27e02 --- /dev/null +++ b/src/merkleblock.cpp @@ -0,0 +1,152 @@ +// 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. + +#include "merkleblock.h" + +#include "hash.h" +#include "primitives/block.h" // for MAX_BLOCK_SIZE +#include "utilstrencodings.h" + +using namespace std; + +CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter) +{ + header = block.GetBlockHeader(); + + vector<bool> vMatch; + vector<uint256> vHashes; + + vMatch.reserve(block.vtx.size()); + vHashes.reserve(block.vtx.size()); + + for (unsigned int i = 0; i < block.vtx.size(); i++) + { + const uint256& hash = block.vtx[i].GetHash(); + if (filter.IsRelevantAndUpdate(block.vtx[i])) + { + vMatch.push_back(true); + vMatchedTxn.push_back(make_pair(i, hash)); + } + else + vMatch.push_back(false); + vHashes.push_back(hash); + } + + txn = CPartialMerkleTree(vHashes, vMatch); +} + +uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) { + if (height == 0) { + // hash at height 0 is the txids themself + return vTxid[pos]; + } else { + // calculate left hash + uint256 left = CalcHash(height-1, pos*2, vTxid), right; + // calculate right hash if not beyond the end of the array - copy left hash otherwise1 + if (pos*2+1 < CalcTreeWidth(height-1)) + right = CalcHash(height-1, pos*2+1, vTxid); + else + right = left; + // combine subhashes + return Hash(BEGIN(left), END(left), BEGIN(right), END(right)); + } +} + +void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) { + // determine whether this node is the parent of at least one matched txid + bool fParentOfMatch = false; + for (unsigned int p = pos << height; p < (pos+1) << height && p < nTransactions; p++) + fParentOfMatch |= vMatch[p]; + // store as flag bit + vBits.push_back(fParentOfMatch); + if (height==0 || !fParentOfMatch) { + // if at height 0, or nothing interesting below, store hash and stop + vHash.push_back(CalcHash(height, pos, vTxid)); + } else { + // otherwise, don't store any hash, but descend into the subtrees + TraverseAndBuild(height-1, pos*2, vTxid, vMatch); + if (pos*2+1 < CalcTreeWidth(height-1)) + TraverseAndBuild(height-1, pos*2+1, vTxid, vMatch); + } +} + +uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch) { + if (nBitsUsed >= vBits.size()) { + // overflowed the bits array - failure + fBad = true; + return 0; + } + bool fParentOfMatch = vBits[nBitsUsed++]; + if (height==0 || !fParentOfMatch) { + // if at height 0, or nothing interesting below, use stored hash and do not descend + if (nHashUsed >= vHash.size()) { + // overflowed the hash array - failure + fBad = true; + return 0; + } + const uint256 &hash = vHash[nHashUsed++]; + if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid + vMatch.push_back(hash); + return hash; + } else { + // otherwise, descend into the subtrees to extract matched txids and hashes + uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch), right; + if (pos*2+1 < CalcTreeWidth(height-1)) + right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch); + else + right = left; + // and combine them before returning + return Hash(BEGIN(left), END(left), BEGIN(right), END(right)); + } +} + +CPartialMerkleTree::CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) { + // reset state + vBits.clear(); + vHash.clear(); + + // calculate height of tree + int nHeight = 0; + while (CalcTreeWidth(nHeight) > 1) + nHeight++; + + // traverse the partial tree + TraverseAndBuild(nHeight, 0, vTxid, vMatch); +} + +CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {} + +uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) { + vMatch.clear(); + // An empty set will not work + if (nTransactions == 0) + return 0; + // check for excessively high numbers of transactions + if (nTransactions > MAX_BLOCK_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction + return 0; + // there can never be more hashes provided than one for every txid + if (vHash.size() > nTransactions) + return 0; + // there must be at least one bit per node in the partial tree, and at least one node per hash + if (vBits.size() < vHash.size()) + return 0; + // calculate height of tree + int nHeight = 0; + while (CalcTreeWidth(nHeight) > 1) + nHeight++; + // 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 + if (fBad) + return 0; + // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence) + if ((nBitsUsed+7)/8 != (vBits.size()+7)/8) + return 0; + // verify that all hashes were consumed + if (nHashUsed != vHash.size()) + return 0; + return hashMerkleRoot; +} diff --git a/src/merkleblock.h b/src/merkleblock.h new file mode 100644 index 0000000000..52c914967f --- /dev/null +++ b/src/merkleblock.h @@ -0,0 +1,151 @@ +// 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_MERKLEBLOCK_H +#define BITCOIN_MERKLEBLOCK_H + +#include "serialize.h" +#include "uint256.h" +#include "primitives/block.h" +#include "bloom.h" + +#include <vector> + +/** Data structure that represents a partial merkle tree. + * + * It represents a subset of the txid's of a known block, in a way that + * allows recovery of the list of txid's and the merkle root, in an + * authenticated way. + * + * The encoding works as follows: we traverse the tree in depth-first order, + * storing a bit for each traversed node, signifying whether the node is the + * parent of at least one matched leaf txid (or a matched txid itself). In + * case we are at the leaf level, or this bit is 0, its merkle node hash is + * stored, and its children are not explorer further. Otherwise, no hash is + * stored, but we recurse into both (or the only) child branch. During + * decoding, the same depth-first traversal is performed, consuming bits and + * hashes as they written during encoding. + * + * The serialization is fixed and provides a hard guarantee about the + * encoded size: + * + * SIZE <= 10 + ceil(32.25*N) + * + * Where N represents the number of leaf nodes of the partial tree. N itself + * is bounded by: + * + * N <= total_transactions + * N <= 1 + matched_transactions*tree_height + * + * The serialization format: + * - uint32 total_transactions (4 bytes) + * - varint number of hashes (1-3 bytes) + * - uint256[] hashes in depth-first order (<= 32*N bytes) + * - varint number of bytes of flag bits (1-3 bytes) + * - byte[] flag bits, packed per 8 in a byte, least significant bit first (<= 2*N-1 bits) + * The size constraints follow from this. + */ +class CPartialMerkleTree +{ +protected: + /** the total number of transactions in the block */ + unsigned int nTransactions; + + /** node-is-parent-of-matched-txid bits */ + std::vector<bool> vBits; + + /** txids and internal hashes */ + std::vector<uint256> vHash; + + /** flag set when encountering invalid data */ + bool fBad; + + /** helper function to efficiently calculate the number of nodes at given height in the merkle tree */ + unsigned int CalcTreeWidth(int height) { + return (nTransactions+(1 << height)-1) >> height; + } + + /** calculate the hash of a node in the merkle tree (at leaf level: the txid's themselves) */ + uint256 CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid); + + /** recursive function that traverses tree nodes, storing the data as bits and hashes */ + void TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch); + + /** + * recursive function that traverses tree nodes, consuming the bits and hashes produced by TraverseAndBuild. + * it returns the hash of the respective node. + */ + uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch); + +public: + + /** serialization implementation */ + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(nTransactions); + READWRITE(vHash); + std::vector<unsigned char> vBytes; + if (ser_action.ForRead()) { + READWRITE(vBytes); + CPartialMerkleTree &us = *(const_cast<CPartialMerkleTree*>(this)); + us.vBits.resize(vBytes.size() * 8); + for (unsigned int p = 0; p < us.vBits.size(); p++) + us.vBits[p] = (vBytes[p / 8] & (1 << (p % 8))) != 0; + us.fBad = false; + } else { + vBytes.resize((vBits.size()+7)/8); + for (unsigned int p = 0; p < vBits.size(); p++) + vBytes[p / 8] |= vBits[p] << (p % 8); + READWRITE(vBytes); + } + } + + /** Construct a partial merkle tree from a list of transaction id's, and a mask that selects a subset of them */ + CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch); + + CPartialMerkleTree(); + + /** + * extract the matching txid's represented by this partial merkle tree. + * returns the merkle root, or 0 in case of failure + */ + uint256 ExtractMatches(std::vector<uint256> &vMatch); +}; + + +/** + * Used to relay blocks as header + vector<merkle branch> + * to filtered nodes. + */ +class CMerkleBlock +{ +public: + /** Public only for unit testing */ + CBlockHeader header; + CPartialMerkleTree txn; + +public: + /** Public only for unit testing and relay testing (not relayed) */ + std::vector<std::pair<unsigned int, uint256> > vMatchedTxn; + + /** + * Create from a CBlock, filtering transactions according to filter + * Note that this will call IsRelevantAndUpdate on the filter for each transaction, + * thus the filter will likely be modified. + */ + CMerkleBlock(const CBlock& block, CBloomFilter& filter); + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(header); + READWRITE(txn); + } +}; + +#endif // BITCOIN_MERKLEBLOCK_H diff --git a/src/miner.cpp b/src/miner.cpp index d05ddbeb1f..0ac974d6e1 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1,15 +1,18 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "miner.h" -#include "core.h" +#include "amount.h" +#include "primitives/block.h" +#include "primitives/transaction.h" #include "hash.h" #include "main.h" #include "net.h" #include "pow.h" +#include "timedata.h" #include "util.h" #include "utilmoneystr.h" #ifdef ENABLE_WALLET @@ -17,6 +20,7 @@ #endif #include <boost/thread.hpp> +#include <boost/tuple/tuple.hpp> using namespace std; @@ -75,6 +79,15 @@ public: } }; +void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev) +{ + pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + + // Updating time can change work required on testnet: + if (Params().AllowMinDifficultyBlocks()) + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock); +} + CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) { // Create new block @@ -83,6 +96,11 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) return NULL; CBlock *pblock = &pblocktemplate->block; // pointer for convenience + // -regtest only: allow overriding block.nVersion with + // -blockversion=N to test forking scenarios + if (Params().MineBlocksOnDemand()) + pblock->nVersion = GetArg("-blockversion", pblock->nVersion); + // Create coinbase tx CMutableTransaction txNew; txNew.vin.resize(1); @@ -111,12 +129,13 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); // Collect memory pool transactions into the block - int64_t nFees = 0; + CAmount nFees = 0; { LOCK2(cs_main, mempool.cs); CBlockIndex* pindexPrev = chainActive.Tip(); - CCoinsViewCache view(*pcoinsTip, true); + const int nHeight = pindexPrev->nHeight + 1; + CCoinsViewCache view(pcoinsTip); // Priority order to process transactions list<COrphan> vOrphan; // list memory doesn't move @@ -130,12 +149,12 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) mi != mempool.mapTx.end(); ++mi) { const CTransaction& tx = mi->second.GetTx(); - if (tx.IsCoinBase() || !IsFinalTx(tx, pindexPrev->nHeight + 1)) + if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight)) continue; COrphan* porphan = NULL; double dPriority = 0; - int64_t nTotalIn = 0; + CAmount nTotalIn = 0; bool fMissingInputs = false; BOOST_FOREACH(const CTxIn& txin, tx.vin) { @@ -170,10 +189,10 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) const CCoins* coins = view.AccessCoins(txin.prevout.hash); assert(coins); - int64_t nValueIn = coins->vout[txin.prevout.n].nValue; + CAmount nValueIn = coins->vout[txin.prevout.n].nValue; nTotalIn += nValueIn; - int nConf = pindexPrev->nHeight - coins->nHeight + 1; + int nConf = nHeight - coins->nHeight; dPriority += (double)nValueIn * nConf; } @@ -229,7 +248,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // Skip free transactions if we're past the minimum block size: const uint256& hash = tx.GetHash(); double dPriorityDelta = 0; - int64_t nFeeDelta = 0; + CAmount nFeeDelta = 0; mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta); if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize)) continue; @@ -247,7 +266,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) if (!view.HaveInputs(tx)) continue; - int64_t nTxFees = view.GetValueIn(tx)-tx.GetValueOut(); + CAmount nTxFees = view.GetValueIn(tx)-tx.GetValueOut(); nTxSigOps += GetP2SHSigOpCount(tx, view); if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) @@ -257,11 +276,10 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // policy here, but we still have to ensure that the block we // create only contains transactions that are valid in new blocks. CValidationState state; - if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS)) + if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) continue; - CTxUndo txundo; - UpdateCoins(tx, state, view, txundo, pindexPrev->nHeight+1); + UpdateCoins(tx, state, view, nHeight); // Added pblock->vtx.push_back(tx); @@ -301,8 +319,8 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize); // Compute final coinbase transaction. - txNew.vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees); - txNew.vin[0].scriptSig = CScript() << OP_0 << OP_0; + txNew.vout[0].nValue = GetBlockValue(nHeight, nFees); + txNew.vin[0].scriptSig = CScript() << nHeight << OP_0; pblock->vtx[0] = txNew; pblocktemplate->vTxFees[0] = -nFees; @@ -313,13 +331,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) pblock->nNonce = 0; pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); - CBlockIndex indexDummy(*pblock); - indexDummy.pprev = pindexPrev; - indexDummy.nHeight = pindexPrev->nHeight + 1; - CCoinsViewCache viewNew(*pcoinsTip, true); CValidationState state; - if (!ConnectBlock(*pblock, state, &indexDummy, viewNew, true)) - throw std::runtime_error("CreateNewBlock() : ConnectBlock failed"); + if (!TestBlockValidity(state, *pblock, pindexPrev, false, false)) + throw std::runtime_error("CreateNewBlock() : TestBlockValidity failed"); } return pblocktemplate.release(); @@ -393,7 +407,7 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) if (!reservekey.GetReservedKey(pubkey)) return NULL; - CScript scriptPubKey = CScript() << pubkey << OP_CHECKSIG; + CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; return CreateNewBlock(scriptPubKey); } @@ -420,8 +434,8 @@ bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) // Process this block the same as if we had received it from another node CValidationState state; - if (!ProcessBlock(state, NULL, pblock)) - return error("BitcoinMiner : ProcessBlock, block not accepted"); + if (!ProcessNewBlock(state, NULL, pblock)) + return error("BitcoinMiner : ProcessNewBlock, block not accepted"); return true; } @@ -550,7 +564,7 @@ void static BitcoinMiner(CWallet *pwallet) } } } - catch (boost::thread_interrupted) + catch (const boost::thread_interrupted&) { LogPrintf("BitcoinMiner terminated\n"); throw; diff --git a/src/miner.h b/src/miner.h index 1fa499dc5b..02dedb1712 100644 --- a/src/miner.h +++ b/src/miner.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-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_MINER_H @@ -9,6 +9,7 @@ #include <stdint.h> class CBlock; +class CBlockHeader; class CBlockIndex; class CReserveKey; class CScript; @@ -25,6 +26,7 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); /** Check mined block */ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); +void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); extern double dHashesPerSec; extern int64_t nHPSTimerStart; diff --git a/src/mruset.h b/src/mruset.h index 1691875f57..1969f419cb 100644 --- a/src/mruset.h +++ b/src/mruset.h @@ -1,5 +1,5 @@ -// Copyright (c) 2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_MRUSET_H diff --git a/src/net.cpp b/src/net.cpp index ab547e2fd7..474a3e4288 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #if defined(HAVE_CONFIG_H) @@ -11,7 +11,8 @@ #include "addrman.h" #include "chainparams.h" -#include "core.h" +#include "clientversion.h" +#include "primitives/transaction.h" #include "ui_interface.h" #ifdef WIN32 @@ -73,11 +74,11 @@ map<CNetAddr, LocalServiceInfo> mapLocalHost; static bool vfReachable[NET_MAX] = {}; static bool vfLimited[NET_MAX] = {}; static CNode* pnodeLocalHost = NULL; -static CNode* pnodeSync = NULL; uint64_t nLocalHostNonce = 0; static std::vector<ListenSocket> vhListenSocket; CAddrMan addrman; int nMaxConnections = 125; +bool fAddressesInitialized = false; vector<CNode*> vNodes; CCriticalSection cs_vNodes; @@ -141,16 +142,19 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer) } // get best local address for a particular peer as a CAddress +// Otherwise, return the unroutable 0.0.0.0 but filled in with +// the normal parameters, since the IP may be changed to a useful +// one by discovery. CAddress GetLocalAddress(const CNetAddr *paddrPeer) { - CAddress ret(CService("0.0.0.0",0),0); + CAddress ret(CService("0.0.0.0",GetListenPort()),0); CService addr; if (GetLocal(addr, paddrPeer)) { ret = CAddress(addr); - ret.nServices = nLocalServices; - ret.nTime = GetAdjustedTime(); } + ret.nServices = nLocalServices; + ret.nTime = GetAdjustedTime(); return ret; } @@ -204,21 +208,38 @@ bool RecvLine(SOCKET hSocket, string& strLine) } } -// used when scores of local addresses may have changed -// pushes better local address to peers -void static AdvertizeLocal() +int GetnScore(const CService& addr) { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) + LOCK(cs_mapLocalHost); + if (mapLocalHost.count(addr) == LOCAL_NONE) + return 0; + return mapLocalHost[addr].nScore; +} + +// Is our peer's addrLocal potentially useful as an external IP source? +bool IsPeerAddrLocalGood(CNode *pnode) +{ + return fDiscover && pnode->addr.IsRoutable() && pnode->addrLocal.IsRoutable() && + !IsLimited(pnode->addrLocal.GetNetwork()); +} + +// pushes our own address to a peer +void AdvertizeLocal(CNode *pnode) +{ + if (fListen && pnode->fSuccessfullyConnected) { - if (pnode->fSuccessfullyConnected) + CAddress addrLocal = GetLocalAddress(&pnode->addr); + // If discovery is enabled, sometimes give our peer the address it + // tells us that it sees us as in case it has a better idea of our + // address than we do. + if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() || + GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8:2) == 0)) { - CAddress addrLocal = GetLocalAddress(&pnode->addr); - if (addrLocal.IsRoutable() && (CService)addrLocal != (CService)pnode->addrLocal) - { - pnode->PushAddress(addrLocal); - pnode->addrLocal = addrLocal; - } + addrLocal.SetIP(pnode->addrLocal); + } + if (addrLocal.IsRoutable()) + { + pnode->PushAddress(addrLocal); } } } @@ -256,8 +277,6 @@ bool AddLocal(const CService& addr, int nScore) SetReachable(addr.GetNetwork()); } - AdvertizeLocal(); - return true; } @@ -295,12 +314,10 @@ bool SeenLocal(const CService& addr) return false; mapLocalHost[addr].nScore++; } - - AdvertizeLocal(); - return true; } + /** check whether a given address is potentially local */ bool IsLocal(const CService& addr) { @@ -322,114 +339,12 @@ bool IsReachable(const CNetAddr& addr) return IsReachable(net); } -bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet) -{ - SOCKET hSocket; - if (!ConnectSocket(addrConnect, hSocket)) - return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString()); - - send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL); - - string strLine; - while (RecvLine(hSocket, strLine)) - { - if (strLine.empty()) // HTTP response is separated from headers by blank line - { - while (true) - { - if (!RecvLine(hSocket, strLine)) - { - CloseSocket(hSocket); - return false; - } - if (pszKeyword == NULL) - break; - if (strLine.find(pszKeyword) != string::npos) - { - strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword)); - break; - } - } - CloseSocket(hSocket); - if (strLine.find("<") != string::npos) - strLine = strLine.substr(0, strLine.find("<")); - strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r")); - while (strLine.size() > 0 && isspace(strLine[strLine.size()-1])) - strLine.resize(strLine.size()-1); - CService addr(strLine,0,true); - LogPrintf("GetMyExternalIP() received [%s] %s\n", strLine, addr.ToString()); - if (!addr.IsValid() || !addr.IsRoutable()) - return false; - ipRet.SetIP(addr); - return true; - } - } - CloseSocket(hSocket); - return error("GetMyExternalIP() : connection closed"); -} - -bool GetMyExternalIP(CNetAddr& ipRet) -{ - CService addrConnect; - const char* pszGet; - const char* pszKeyword; - - for (int nLookup = 0; nLookup <= 1; nLookup++) - for (int nHost = 1; nHost <= 1; nHost++) - { - // We should be phasing out our use of sites like these. If we need - // replacements, we should ask for volunteers to put this simple - // php file on their web server that prints the client IP: - // <?php echo $_SERVER["REMOTE_ADDR"]; ?> - if (nHost == 1) - { - addrConnect = CService("91.198.22.70", 80); // checkip.dyndns.org - - if (nLookup == 1) - { - CService addrIP("checkip.dyndns.org", 80, true); - if (addrIP.IsValid()) - addrConnect = addrIP; - } - - pszGet = "GET / HTTP/1.1\r\n" - "Host: checkip.dyndns.org\r\n" - "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n" - "Connection: close\r\n" - "\r\n"; - - pszKeyword = "Address:"; - } - - if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet)) - return true; - } - - return false; -} - -void ThreadGetMyExternalIP() -{ - CNetAddr addrLocalHost; - if (GetMyExternalIP(addrLocalHost)) - { - LogPrintf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP()); - AddLocal(addrLocalHost, LOCAL_HTTP); - } -} - - - - - void AddressCurrentlyConnected(const CService& addr) { addrman.Connected(addr); } - - uint64_t CNode::nTotalBytesRecv = 0; uint64_t CNode::nTotalBytesSent = 0; CCriticalSection CNode::cs_totalBytesRecv; @@ -484,7 +399,9 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) // Connect SOCKET hSocket; - if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort()) : ConnectSocket(addrConnect, hSocket)) + bool proxyConnectionFailed = false; + if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) : + ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed)) { addrman.Attempt(addrConnect); @@ -500,6 +417,10 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) pnode->nTimeConnected = GetTime(); return pnode; + } else if (!proxyConnectionFailed) { + // If connecting to the node failed, and failure is not caused by a problem connecting to + // the proxy, mark this as an attempt. + addrman.Attempt(addrConnect); } return NULL; @@ -518,17 +439,12 @@ void CNode::CloseSocketDisconnect() TRY_LOCK(cs_vRecvMsg, lockRecv); if (lockRecv) vRecvMsg.clear(); - - // if this was the sync node, we'll need a new one - if (this == pnodeSync) - pnodeSync = NULL; } void CNode::PushVersion() { int nBestHeight = g_signals.GetHeight().get_value_or(0); - /// when NTP implemented, change to just nTime = GetAdjustedTime() int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime()); CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0))); CAddress addrMe = GetLocalAddress(&addr); @@ -614,7 +530,6 @@ void CNode::copyStats(CNodeStats &stats) X(nSendBytes); X(nRecvBytes); X(fWhitelisted); - stats.fSyncNode = (this == pnodeSync); // It is common for nodes with good ping times to suddenly become lagged, // due to a new block arriving or other large transfer. @@ -685,7 +600,7 @@ int CNetMessage::readHeader(const char *pch, unsigned int nBytes) try { hdrbuf >> hdr; } - catch (const std::exception &) { + catch (const std::exception&) { return -1; } @@ -1152,7 +1067,7 @@ void ThreadMapPort() MilliSleep(20*60*1000); // Refresh every 20 minutes } } - catch (boost::thread_interrupted) + catch (const boost::thread_interrupted&) { r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); LogPrintf("UPNP_DeletePortMapping() returned : %d\n", r); @@ -1486,61 +1401,20 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu } -// for now, use a very simple selection metric: the node from which we received -// most recently -static int64_t NodeSyncScore(const CNode *pnode) { - return pnode->nLastRecv; -} - -void static StartSync(const vector<CNode*> &vNodes) { - CNode *pnodeNewSync = NULL; - int64_t nBestScore = 0; - - int nBestHeight = g_signals.GetHeight().get_value_or(0); - - // Iterate over all nodes - BOOST_FOREACH(CNode* pnode, vNodes) { - // check preconditions for allowing a sync - if (!pnode->fClient && !pnode->fOneShot && - !pnode->fDisconnect && pnode->fSuccessfullyConnected && - (pnode->nStartingHeight > (nBestHeight - 144)) && - (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) { - // if ok, compare node's score with the best so far - int64_t nScore = NodeSyncScore(pnode); - if (pnodeNewSync == NULL || nScore > nBestScore) { - pnodeNewSync = pnode; - nBestScore = nScore; - } - } - } - // if a new sync candidate was found, start sync! - if (pnodeNewSync) { - pnodeNewSync->fStartSync = true; - pnodeSync = pnodeNewSync; - } -} - void ThreadMessageHandler() { SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL); while (true) { - bool fHaveSyncNode = false; - vector<CNode*> vNodesCopy; { LOCK(cs_vNodes); vNodesCopy = vNodes; BOOST_FOREACH(CNode* pnode, vNodesCopy) { pnode->AddRef(); - if (pnode == pnodeSync) - fHaveSyncNode = true; } } - if (!fHaveSyncNode) - StartSync(vNodesCopy); - // Poll the connected nodes for messages CNode* pnodeTrickle = NULL; if (!vNodesCopy.empty()) @@ -1690,7 +1564,7 @@ void static Discover(boost::thread_group& threadGroup) #ifdef WIN32 // Get local host IP - char pszHostName[1000] = ""; + char pszHostName[256] = ""; if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) { vector<CNetAddr> vaddr; @@ -1698,7 +1572,8 @@ void static Discover(boost::thread_group& threadGroup) { BOOST_FOREACH (const CNetAddr &addr, vaddr) { - AddLocal(addr, LOCAL_IF); + if (AddLocal(addr, LOCAL_IF)) + LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString()); } } } @@ -1718,27 +1593,35 @@ void static Discover(boost::thread_group& threadGroup) struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr); CNetAddr addr(s4->sin_addr); if (AddLocal(addr, LOCAL_IF)) - LogPrintf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString()); + LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString()); } else if (ifa->ifa_addr->sa_family == AF_INET6) { struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr); CNetAddr addr(s6->sin6_addr); if (AddLocal(addr, LOCAL_IF)) - LogPrintf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString()); + LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString()); } } freeifaddrs(myaddrs); } #endif - - // Don't use external IPv4 discovery, when -onlynet="IPv6" - if (!IsLimited(NET_IPV4)) - threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "ext-ip", &ThreadGetMyExternalIP)); } void StartNode(boost::thread_group& threadGroup) { + uiInterface.InitMessage(_("Loading addresses...")); + // Load addresses for peers.dat + int64_t nStart = GetTimeMillis(); + { + CAddrDB adb; + if (!adb.Read(addrman)) + LogPrintf("Invalid or missing peers.dat; recreating\n"); + } + LogPrintf("Loaded %i addresses from peers.dat %dms\n", + addrman.size(), GetTimeMillis() - nStart); + fAddressesInitialized = true; + if (semOutbound == NULL) { // initialize semaphore int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections); @@ -1785,7 +1668,12 @@ bool StopNode() if (semOutbound) for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++) semOutbound->post(); - DumpAddresses(); + + if (fAddressesInitialized) + { + DumpAddresses(); + fAddressesInitialized = false; + } return true; } @@ -1957,18 +1845,18 @@ bool CAddrDB::Write(const CAddrMan& addr) // open temp output file, and associate with CAutoFile boost::filesystem::path pathTmp = GetDataDir() / tmpfn; FILE *file = fopen(pathTmp.string().c_str(), "wb"); - CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION); - if (!fileout) + 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 << ssPeers; } - catch (std::exception &e) { + catch (const std::exception& e) { return error("%s : Serialize or I/O error - %s", __func__, e.what()); } - FileCommit(fileout); + FileCommit(fileout.Get()); fileout.fclose(); // replace existing peers.dat, if any, with new peers.dat.XXXX @@ -1982,8 +1870,8 @@ bool CAddrDB::Read(CAddrMan& addr) { // open input file, and associate with CAutoFile FILE *file = fopen(pathAddr.string().c_str(), "rb"); - CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION); - if (!filein) + CAutoFile filein(file, SER_DISK, CLIENT_VERSION); + if (filein.IsNull()) return error("%s : Failed to open file %s", __func__, pathAddr.string()); // use file size to size memory buffer @@ -2001,7 +1889,7 @@ bool CAddrDB::Read(CAddrMan& addr) filein.read((char *)&vchData[0], dataSize); filein >> hashIn; } - catch (std::exception &e) { + catch (const std::exception& e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); } filein.fclose(); @@ -2025,7 +1913,7 @@ bool CAddrDB::Read(CAddrMan& addr) // de-serialize address data into one CAddrMan object ssPeers >> addr; } - catch (std::exception &e) { + catch (const std::exception& e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); } @@ -2060,10 +1948,7 @@ CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fIn nSendSize = 0; nSendOffset = 0; hashContinue = 0; - pindexLastGetBlocksBegin = 0; - hashLastGetBlocksEnd = 0; nStartingHeight = -1; - fStartSync = false; fGetAddr = false; fRelayTxes = false; setInventoryKnown.max_size(SendBufferSize() / 1000); @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_NET_H @@ -14,6 +14,7 @@ #include "netbase.h" #include "protocol.h" #include "random.h" +#include "streams.h" #include "sync.h" #include "uint256.h" #include "utilstrencodings.h" @@ -43,6 +44,8 @@ static const int PING_INTERVAL = 2 * 60; static const int TIMEOUT_INTERVAL = 20 * 60; /** The maximum number of entries in an 'inv' protocol message */ static const unsigned int MAX_INV_SZ = 50000; +/** The maximum number of new addresses to accumulate before announcing. */ +static const unsigned int MAX_ADDR_TO_SEND = 1000; /** -listen default */ static const bool DEFAULT_LISTEN = true; /** -upnp default */ @@ -59,7 +62,6 @@ unsigned int SendBufferSize(); void AddOneShot(std::string strDest); bool RecvLine(SOCKET hSocket, std::string& strLine); -bool GetMyExternalIP(CNetAddr& ipRet); void AddressCurrentlyConnected(const CService& addr); CNode* FindNode(const CNetAddr& ip); CNode* FindNode(const std::string& addrName); @@ -95,12 +97,13 @@ enum LOCAL_IF, // address a local interface listens on LOCAL_BIND, // address explicit bound to LOCAL_UPNP, // address reported by UPnP - LOCAL_HTTP, // address reported by whatismyip.com and similar LOCAL_MANUAL, // address explicitly specified (-externalip=) LOCAL_MAX }; +bool IsPeerAddrLocalGood(CNode *pnode); +void AdvertizeLocal(CNode *pnode); void SetLimited(enum Network net, bool fLimited = true); bool IsLimited(enum Network net); bool IsLimited(const CNetAddr& addr); @@ -158,7 +161,6 @@ public: int nStartingHeight; uint64_t nSendBytes; uint64_t nRecvBytes; - bool fSyncNode; bool fWhitelisted; double dPingTime; double dPingWait; @@ -276,10 +278,7 @@ protected: public: uint256 hashContinue; - CBlockIndex* pindexLastGetBlocksBegin; - uint256 hashLastGetBlocksEnd; int nStartingHeight; - bool fStartSync; // flood relay std::vector<CAddress> vAddrToSend; @@ -371,8 +370,13 @@ public: // Known checking here is only to save space from duplicates. // SendMessages will filter it again for knowns that were added // after addresses were pushed. - if (addr.IsValid() && !setAddrKnown.count(addr)) - vAddrToSend.push_back(addr); + if (addr.IsValid() && !setAddrKnown.count(addr)) { + if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) { + vAddrToSend[insecure_rand() % vAddrToSend.size()] = addr; + } else { + vAddrToSend.push_back(addr); + } + } } diff --git a/src/netbase.cpp b/src/netbase.cpp index 5819c152a3..a2ac6575bc 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1,10 +1,10 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #ifdef HAVE_CONFIG_H -#include "bitcoin-config.h" +#include "config/bitcoin-config.h" #endif #include "netbase.h" @@ -40,7 +40,7 @@ using namespace std; static proxyType proxyInfo[NET_MAX]; static CService nameProxy; static CCriticalSection cs_proxyInfos; -int nConnectTimeout = 5000; +int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; bool fNameLookup = false; static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; @@ -519,9 +519,11 @@ bool IsProxy(const CNetAddr &addr) { return false; } -bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout) +bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed) { proxyType proxy; + if (outProxyConnectionFailed) + *outProxyConnectionFailed = false; // no proxy needed (none set for target network) if (!GetProxy(addrDest.GetNetwork(), proxy)) return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout); @@ -529,8 +531,11 @@ bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout) SOCKET hSocket = INVALID_SOCKET; // first connect to proxy server - if (!ConnectSocketDirectly(proxy, hSocket, nTimeout)) + if (!ConnectSocketDirectly(proxy, hSocket, nTimeout)) { + if (outProxyConnectionFailed) + *outProxyConnectionFailed = true; return false; + } // do socks negotiation if (!Socks5(addrDest.ToStringIP(), addrDest.GetPort(), hSocket)) return false; @@ -539,10 +544,14 @@ bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout) return true; } -bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout) +bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed) { string strDest; int port = portDefault; + + if (outProxyConnectionFailed) + *outProxyConnectionFailed = false; + SplitHostPort(string(pszDest), port, strDest); SOCKET hSocket = INVALID_SOCKET; @@ -561,8 +570,11 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest if (!HaveNameProxy()) return false; // first connect to name proxy server - if (!ConnectSocketDirectly(nameProxy, hSocket, nTimeout)) + if (!ConnectSocketDirectly(nameProxy, hSocket, nTimeout)) { + if (outProxyConnectionFailed) + *outProxyConnectionFailed = true; return false; + } // do socks negotiation if (!Socks5(strDest, (unsigned short)port, hSocket)) return false; @@ -667,11 +679,28 @@ bool CNetAddr::IsRFC1918() const (GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31))); } +bool CNetAddr::IsRFC2544() const +{ + return IsIPv4() && GetByte(3) == 198 && (GetByte(2) == 18 || GetByte(2) == 19); +} + bool CNetAddr::IsRFC3927() const { return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254); } +bool CNetAddr::IsRFC6598() const +{ + return IsIPv4() && GetByte(3) == 100 && GetByte(2) >= 64 && GetByte(2) <= 127; +} + +bool CNetAddr::IsRFC5737() const +{ + return IsIPv4() && ((GetByte(3) == 192 && GetByte(2) == 0 && GetByte(1) == 2) || + (GetByte(3) == 198 && GetByte(2) == 51 && GetByte(1) == 100) || + (GetByte(3) == 203 && GetByte(2) == 0 && GetByte(1) == 113)); +} + bool CNetAddr::IsRFC3849() const { return GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x0D && GetByte(12) == 0xB8; @@ -778,7 +807,7 @@ bool CNetAddr::IsValid() const bool CNetAddr::IsRoutable() const { - return IsValid() && !(IsRFC1918() || IsRFC3927() || IsRFC4862() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal()); + return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal()); } enum Network CNetAddr::GetNetwork() const diff --git a/src/netbase.h b/src/netbase.h index 9fc5c72eb8..5bf13a673f 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -1,5 +1,5 @@ -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-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_NETBASE_H @@ -19,6 +19,9 @@ extern int nConnectTimeout; extern bool fNameLookup; +/** -timeout default */ +static const int DEFAULT_CONNECT_TIMEOUT = 5000; + #ifdef WIN32 // In MSVC, this is defined as a macro, undefine it to prevent a compile and link error #undef SetPort @@ -58,6 +61,9 @@ class CNetAddr bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor) bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12) + bool IsRFC2544() const; // IPv4 inter-network communcations (192.18.0.0/15) + bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10) + bool IsRFC5737() const; // IPv4 documentation addresses (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24) bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32) bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16) bool IsRFC3964() const; // IPv6 6to4 tunnelling (2002::/16) @@ -176,8 +182,8 @@ bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nM bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true); bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault = 0, bool fAllowLookup = true, unsigned int nMaxSolutions = 0); bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0); -bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout); -bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault = 0, int nTimeout = nConnectTimeout); +bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed = 0); +bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed = 0); /** Return readable error string for a network error code */ std::string NetworkErrorString(int err); /** Close socket and set hSocket to INVALID_SOCKET */ diff --git a/src/noui.cpp b/src/noui.cpp index f786a20db5..3a77361919 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "noui.h" @@ -14,6 +14,9 @@ static bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style) { + bool fSecure = style & CClientUIInterface::SECURE; + style &= ~CClientUIInterface::SECURE; + std::string strCaption; // Check for usage of predefined caption switch (style) { @@ -30,7 +33,8 @@ static bool noui_ThreadSafeMessageBox(const std::string& message, const std::str strCaption += caption; // Use supplied caption (can be empty) } - LogPrintf("%s: %s\n", strCaption, message); + if (!fSecure) + LogPrintf("%s: %s\n", strCaption, message); fprintf(stderr, "%s: %s\n", strCaption.c_str(), message.c_str()); return false; } diff --git a/src/noui.h b/src/noui.h index dbd4320fa7..15cd30a639 100644 --- a/src/noui.h +++ b/src/noui.h @@ -1,5 +1,5 @@ -// Copyright (c) 2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_NOUI_H diff --git a/src/pow.cpp b/src/pow.cpp index 893f6c18be..e91e3d893c 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -1,14 +1,13 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "pow.h" +#include "chain.h" #include "chainparams.h" -#include "core.h" -#include "main.h" -#include "timedata.h" +#include "primitives/block.h" #include "uint256.h" #include "util.h" @@ -81,6 +80,10 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) bool fNegative; bool fOverflow; uint256 bnTarget; + + if (Params().SkipProofOfWorkCheck()) + return true; + bnTarget.SetCompact(nBits, &fNegative, &fOverflow); // Check range @@ -94,54 +97,12 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) return true; } -// -// true if nBits is greater than the minimum amount of work that could -// possibly be required deltaTime after minimum work required was nBase -// -bool CheckMinWork(unsigned int nBits, unsigned int nBase, int64_t deltaTime) -{ - bool fOverflow = false; - uint256 bnNewBlock; - bnNewBlock.SetCompact(nBits, NULL, &fOverflow); - if (fOverflow) - return false; - - const uint256 &bnLimit = Params().ProofOfWorkLimit(); - // Testnet has min-difficulty blocks - // after Params().TargetSpacing()*2 time between blocks: - if (Params().AllowMinDifficultyBlocks() && deltaTime > Params().TargetSpacing()*2) - return bnNewBlock <= bnLimit; - - uint256 bnResult; - bnResult.SetCompact(nBase); - while (deltaTime > 0 && bnResult < bnLimit) - { - // Maximum 400% adjustment... - bnResult *= 4; - // ... in best-case exactly 4-times-normal target time - deltaTime -= Params().TargetTimespan()*4; - } - if (bnResult > bnLimit) - bnResult = bnLimit; - - return bnNewBlock <= bnResult; -} - -void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev) -{ - pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); - - // Updating time can change work required on testnet: - if (Params().AllowMinDifficultyBlocks()) - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock); -} - -uint256 GetProofIncrement(unsigned int nBits) +uint256 GetBlockProof(const CBlockIndex& block) { uint256 bnTarget; bool fNegative; bool fOverflow; - bnTarget.SetCompact(nBits, &fNegative, &fOverflow); + bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); if (fNegative || fOverflow || bnTarget == 0) return 0; // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_POW_H @@ -16,11 +16,6 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ bool CheckProofOfWork(uint256 hash, unsigned int nBits); -/** Check the work is more than the minimum a received block needs, without knowing its direct parent */ -bool CheckMinWork(unsigned int nBits, unsigned int nBase, int64_t deltaTime); - -void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); - -uint256 GetProofIncrement(unsigned int nBits); +uint256 GetBlockProof(const CBlockIndex& block); #endif // BITCOIN_POW_H diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp new file mode 100644 index 0000000000..2b6a302ee9 --- /dev/null +++ b/src/primitives/block.cpp @@ -0,0 +1,130 @@ +// 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. + +#include "primitives/block.h" + +#include "hash.h" +#include "tinyformat.h" +#include "utilstrencodings.h" + +uint256 CBlockHeader::GetHash() const +{ + return Hash(BEGIN(nVersion), END(nNonce)); +} + +uint256 CBlock::BuildMerkleTree(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 + that the following merkle tree algorithm has a serious flaw related to + duplicate txids, resulting in a vulnerability (CVE-2012-2459). + + The reason is that if the number of hashes in the list at a given time + is odd, the last one is duplicated before computing the next level (which + is unusual in Merkle trees). This results in certain sequences of + transactions leading to the same merkle root. For example, these two + trees: + + A A + / \ / \ + B C B C + / \ | / \ / \ + D E F D E F F + / \ / \ / \ / \ / \ / \ / \ + 1 2 3 4 5 6 1 2 3 4 5 6 5 6 + + for transaction lists [1,2,3,4,5,6] and [1,2,3,4,5,6,5,6] (where 5 and + 6 are repeated) result in the same root hash A (because the hash of both + of (F) and (F,F) is C). + + The vulnerability results from being able to send a block with such a + transaction list, with the same merkle root, and the same block hash as + the original without duplication, resulting in failed validation. If the + receiving node proceeds to mark that block as permanently invalid + however, it will fail to accept further unmodified (and thus potentially + valid) versions of the same block. We defend against this by detecting + the case where we would hash two identical hashes at the end of the list + together, and treating that identically to the block having an invalid + merkle root. Assuming no double-SHA256 collisions, this will detect all + known ways of changing the transactions without affecting the merkle + root. + */ + vMerkleTree.clear(); + 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()); + int j = 0; + bool mutated = false; + for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + { + for (int i = 0; i < nSize; i += 2) + { + int i2 = std::min(i+1, nSize-1); + if (i2 == i + 1 && i2 + 1 == nSize && vMerkleTree[j+i] == vMerkleTree[j+i2]) { + // Two identical hashes at the end of the list at a particular level. + mutated = true; + } + vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), + BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); + } + j += nSize; + } + if (fMutated) { + *fMutated = mutated; + } + return (vMerkleTree.empty() ? 0 : 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 0; + 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; + s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n", + GetHash().ToString(), + nVersion, + hashPrevBlock.ToString(), + hashMerkleRoot.ToString(), + nTime, nBits, nNonce, + vtx.size()); + for (unsigned int i = 0; i < vtx.size(); i++) + { + 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 new file mode 100644 index 0000000000..1449882bd0 --- /dev/null +++ b/src/primitives/block.h @@ -0,0 +1,171 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-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_PRIMITIVES_BLOCK_H +#define BITCOIN_PRIMITIVES_BLOCK_H + +#include "primitives/transaction.h" +#include "serialize.h" +#include "uint256.h" + +/** The maximum allowed size for a serialized block, in bytes (network rule) */ +static const unsigned int MAX_BLOCK_SIZE = 1000000; + +/** Nodes collect new transactions into a block, hash them into a hash tree, + * and scan through nonce values to make the block's hash satisfy proof-of-work + * requirements. When they solve the proof-of-work, they broadcast the block + * to everyone and the block is added to the block chain. The first transaction + * in the block is a special one that creates a new coin owned by the creator + * of the block. + */ +class CBlockHeader +{ +public: + // header + static const int32_t CURRENT_VERSION=2; + int32_t nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + uint32_t nTime; + uint32_t nBits; + uint32_t nNonce; + + CBlockHeader() + { + SetNull(); + } + + 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(hashPrevBlock); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + } + + void SetNull() + { + nVersion = CBlockHeader::CURRENT_VERSION; + hashPrevBlock = 0; + hashMerkleRoot = 0; + nTime = 0; + nBits = 0; + nNonce = 0; + } + + bool IsNull() const + { + return (nBits == 0); + } + + uint256 GetHash() const; + + int64_t GetBlockTime() const + { + return (int64_t)nTime; + } +}; + + +class CBlock : public CBlockHeader +{ +public: + // network and disk + std::vector<CTransaction> vtx; + + // memory only + mutable std::vector<uint256> vMerkleTree; + + CBlock() + { + SetNull(); + } + + CBlock(const CBlockHeader &header) + { + SetNull(); + *((CBlockHeader*)this) = header; + } + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(*(CBlockHeader*)this); + READWRITE(vtx); + } + + void SetNull() + { + CBlockHeader::SetNull(); + vtx.clear(); + vMerkleTree.clear(); + } + + CBlockHeader GetBlockHeader() const + { + CBlockHeader block; + block.nVersion = nVersion; + block.hashPrevBlock = hashPrevBlock; + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + return block; + } + + // Build the in-memory 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; + + std::vector<uint256> GetMerkleBranch(int nIndex) const; + static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex); + std::string ToString() const; +}; + + +/** Describes a place in the block chain to another node such that if the + * other node doesn't have the same branch, it can find a recent common trunk. + * The further back it is, the further before the fork it may be. + */ +struct CBlockLocator +{ + std::vector<uint256> vHave; + + CBlockLocator() {} + + CBlockLocator(const std::vector<uint256>& vHaveIn) + { + vHave = vHaveIn; + } + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vHave); + } + + void SetNull() + { + vHave.clear(); + } + + bool IsNull() + { + return vHave.empty(); + } +}; + +#endif // BITCOIN_PRIMITIVES_BLOCK_H diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp new file mode 100644 index 0000000000..230aedd896 --- /dev/null +++ b/src/primitives/transaction.cpp @@ -0,0 +1,142 @@ +// 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. + +#include "primitives/transaction.h" + +#include "hash.h" +#include "tinyformat.h" +#include "utilstrencodings.h" + +std::string COutPoint::ToString() const +{ + return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n); +} + +CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn) +{ + prevout = prevoutIn; + scriptSig = scriptSigIn; + nSequence = nSequenceIn; +} + +CTxIn::CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn) +{ + prevout = COutPoint(hashPrevTx, nOut); + scriptSig = scriptSigIn; + nSequence = nSequenceIn; +} + +std::string CTxIn::ToString() const +{ + std::string str; + str += "CTxIn("; + str += prevout.ToString(); + if (prevout.IsNull()) + str += strprintf(", coinbase %s", HexStr(scriptSig)); + else + str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24)); + if (nSequence != std::numeric_limits<unsigned int>::max()) + str += strprintf(", nSequence=%u", nSequence); + str += ")"; + return str; +} + +CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn) +{ + nValue = nValueIn; + scriptPubKey = scriptPubKeyIn; +} + +uint256 CTxOut::GetHash() const +{ + return SerializeHash(*this); +} + +std::string CTxOut::ToString() const +{ + return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30)); +} + +CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {} +CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {} + +uint256 CMutableTransaction::GetHash() const +{ + return SerializeHash(*this); +} + +void CTransaction::UpdateHash() const +{ + *const_cast<uint256*>(&hash) = SerializeHash(*this); +} + +CTransaction::CTransaction() : hash(0), nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { } + +CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) { + UpdateHash(); +} + +CTransaction& CTransaction::operator=(const CTransaction &tx) { + *const_cast<int*>(&nVersion) = tx.nVersion; + *const_cast<std::vector<CTxIn>*>(&vin) = tx.vin; + *const_cast<std::vector<CTxOut>*>(&vout) = tx.vout; + *const_cast<unsigned int*>(&nLockTime) = tx.nLockTime; + *const_cast<uint256*>(&hash) = tx.hash; + return *this; +} + +CAmount CTransaction::GetValueOut() const +{ + CAmount nValueOut = 0; + for (std::vector<CTxOut>::const_iterator it(vout.begin()); it != vout.end(); ++it) + { + nValueOut += it->nValue; + if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut)) + throw std::runtime_error("CTransaction::GetValueOut() : value out of range"); + } + return nValueOut; +} + +double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const +{ + nTxSize = CalculateModifiedSize(nTxSize); + if (nTxSize == 0) return 0.0; + + return dPriorityInputs / nTxSize; +} + +unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const +{ + // In order to avoid disincentivizing cleaning up the UTXO set we don't count + // the constant overhead for each txin and up to 110 bytes of scriptSig (which + // is enough to cover a compressed pubkey p2sh redemption) for priority. + // Providing any more cleanup incentive than making additional inputs free would + // risk encouraging people to create junk outputs to redeem later. + if (nTxSize == 0) + nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); + for (std::vector<CTxIn>::const_iterator it(vin.begin()); it != vin.end(); ++it) + { + unsigned int offset = 41U + std::min(110U, (unsigned int)it->scriptSig.size()); + if (nTxSize > offset) + nTxSize -= offset; + } + return nTxSize; +} + +std::string CTransaction::ToString() const +{ + std::string str; + str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n", + GetHash().ToString().substr(0,10), + nVersion, + vin.size(), + vout.size(), + nLockTime); + for (unsigned int i = 0; i < vin.size(); i++) + str += " " + vin[i].ToString() + "\n"; + for (unsigned int i = 0; i < vout.size(); i++) + str += " " + vout[i].ToString() + "\n"; + return str; +} diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h new file mode 100644 index 0000000000..da35012300 --- /dev/null +++ b/src/primitives/transaction.h @@ -0,0 +1,276 @@ +// 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_PRIMITIVES_TRANSACTION_H +#define BITCOIN_PRIMITIVES_TRANSACTION_H + +#include "amount.h" +#include "script/script.h" +#include "serialize.h" +#include "uint256.h" + +/** An outpoint - a combination of a transaction hash and an index n into its vout */ +class COutPoint +{ +public: + uint256 hash; + uint32_t n; + + COutPoint() { SetNull(); } + COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; } + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(FLATDATA(*this)); + } + + void SetNull() { hash = 0; n = (uint32_t) -1; } + bool IsNull() const { return (hash == 0 && n == (uint32_t) -1); } + + friend bool operator<(const COutPoint& a, const COutPoint& b) + { + return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n)); + } + + friend bool operator==(const COutPoint& a, const COutPoint& b) + { + return (a.hash == b.hash && a.n == b.n); + } + + friend bool operator!=(const COutPoint& a, const COutPoint& b) + { + return !(a == b); + } + + std::string ToString() const; +}; + +/** An input of a transaction. It contains the location of the previous + * transaction's output that it claims and a signature that matches the + * output's public key. + */ +class CTxIn +{ +public: + COutPoint prevout; + CScript scriptSig; + uint32_t nSequence; + + CTxIn() + { + nSequence = std::numeric_limits<unsigned int>::max(); + } + + explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max()); + CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<uint32_t>::max()); + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(prevout); + READWRITE(scriptSig); + READWRITE(nSequence); + } + + bool IsFinal() const + { + return (nSequence == std::numeric_limits<uint32_t>::max()); + } + + friend bool operator==(const CTxIn& a, const CTxIn& b) + { + return (a.prevout == b.prevout && + a.scriptSig == b.scriptSig && + a.nSequence == b.nSequence); + } + + friend bool operator!=(const CTxIn& a, const CTxIn& b) + { + return !(a == b); + } + + std::string ToString() const; +}; + +/** An output of a transaction. It contains the public key that the next input + * must be able to sign with to claim it. + */ +class CTxOut +{ +public: + CAmount nValue; + CScript scriptPubKey; + + CTxOut() + { + SetNull(); + } + + CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn); + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(nValue); + READWRITE(scriptPubKey); + } + + void SetNull() + { + nValue = -1; + scriptPubKey.clear(); + } + + bool IsNull() const + { + return (nValue == -1); + } + + uint256 GetHash() const; + + bool IsDust(CFeeRate minRelayTxFee) const + { + // "Dust" is defined in terms of CTransaction::minRelayTxFee, + // 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 + // need a CTxIn of at least 148 bytes to spend: + // so dust is a txout less than 546 satoshis + // with default minRelayTxFee. + size_t nSize = GetSerializeSize(SER_DISK,0)+148u; + return (nValue < 3*minRelayTxFee.GetFee(nSize)); + } + + friend bool operator==(const CTxOut& a, const CTxOut& b) + { + return (a.nValue == b.nValue && + a.scriptPubKey == b.scriptPubKey); + } + + friend bool operator!=(const CTxOut& a, const CTxOut& b) + { + return !(a == b); + } + + std::string ToString() const; +}; + +struct CMutableTransaction; + +/** The basic transaction that is broadcasted on the network and contained in + * blocks. A transaction can contain multiple inputs and outputs. + */ +class CTransaction +{ +private: + /** Memory only. */ + const uint256 hash; + void UpdateHash() const; + +public: + static const int32_t CURRENT_VERSION=1; + + // The local variables are made const to prevent unintended modification + // without updating the cached hash value. However, CTransaction is not + // actually immutable; deserialization and assignment are implemented, + // and bypass the constness. This is safe, as they update the entire + // structure, including the hash. + const int32_t nVersion; + const std::vector<CTxIn> vin; + const std::vector<CTxOut> vout; + const uint32_t nLockTime; + + /** Construct a CTransaction that qualifies as IsNull() */ + CTransaction(); + + /** Convert a CMutableTransaction into a CTransaction. */ + CTransaction(const CMutableTransaction &tx); + + CTransaction& operator=(const CTransaction& tx); + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(*const_cast<int32_t*>(&this->nVersion)); + nVersion = this->nVersion; + READWRITE(*const_cast<std::vector<CTxIn>*>(&vin)); + READWRITE(*const_cast<std::vector<CTxOut>*>(&vout)); + READWRITE(*const_cast<uint32_t*>(&nLockTime)); + if (ser_action.ForRead()) + UpdateHash(); + } + + bool IsNull() const { + return vin.empty() && vout.empty(); + } + + const uint256& GetHash() const { + return hash; + } + + // Return sum of txouts. + CAmount GetValueOut() const; + // GetValueIn() is a method on CCoinsViewCache, because + // inputs must be known to compute value in. + + // Compute priority, given priority of inputs and (optionally) tx size + double ComputePriority(double dPriorityInputs, unsigned int nTxSize=0) const; + + // Compute modified tx size for priority calculation (optionally given tx size) + unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const; + + bool IsCoinBase() const + { + return (vin.size() == 1 && vin[0].prevout.IsNull()); + } + + friend bool operator==(const CTransaction& a, const CTransaction& b) + { + return a.hash == b.hash; + } + + friend bool operator!=(const CTransaction& a, const CTransaction& b) + { + return a.hash != b.hash; + } + + std::string ToString() const; +}; + +/** A mutable version of CTransaction. */ +struct CMutableTransaction +{ + int32_t nVersion; + std::vector<CTxIn> vin; + std::vector<CTxOut> vout; + uint32_t nLockTime; + + CMutableTransaction(); + CMutableTransaction(const CTransaction& tx); + + 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(vin); + READWRITE(vout); + READWRITE(nLockTime); + } + + /** Compute the hash of this CMutableTransaction. This is computed on the + * fly, as opposed to GetHash() in CTransaction, which uses a cached result. + */ + uint256 GetHash() const; +}; + +#endif // BITCOIN_PRIMITIVES_TRANSACTION_H diff --git a/src/protocol.cpp b/src/protocol.cpp index 341de0602a..71c6bd152b 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -1,12 +1,13 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "protocol.h" #include "chainparams.h" #include "util.h" +#include "utilstrencodings.h" #ifndef WIN32 # include <arpa/inet.h> @@ -24,7 +25,6 @@ CMessageHeader::CMessageHeader() { memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE); memset(pchCommand, 0, sizeof(pchCommand)); - pchCommand[1] = 1; nMessageSize = -1; nChecksum = 0; } @@ -32,6 +32,7 @@ CMessageHeader::CMessageHeader() CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) { memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE); + memset(pchCommand, 0, sizeof(pchCommand)); strncpy(pchCommand, pszCommand, COMMAND_SIZE); nMessageSize = nMessageSizeIn; nChecksum = 0; @@ -39,10 +40,7 @@ CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSize std::string CMessageHeader::GetCommand() const { - if (pchCommand[COMMAND_SIZE-1] == 0) - return std::string(pchCommand, pchCommand + strlen(pchCommand)); - else - return std::string(pchCommand, pchCommand + COMMAND_SIZE); + return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE)); } bool CMessageHeader::IsValid() const diff --git a/src/protocol.h b/src/protocol.h index b73041a9fd..f8394ce52f 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,14 +1,14 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-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 __cplusplus #error This header can only be compiled as C++. #endif -#ifndef __INCLUDED_PROTOCOL_H__ -#define __INCLUDED_PROTOCOL_H__ +#ifndef BITCOIN_PROTOCOL_H +#define BITCOIN_PROTOCOL_H #include "netbase.h" #include "serialize.h" @@ -149,4 +149,4 @@ enum { MSG_FILTERED_BLOCK, }; -#endif // __INCLUDED_PROTOCOL_H__ +#endif // BITCOIN_PROTOCOL_H diff --git a/src/pubkey.cpp b/src/pubkey.cpp new file mode 100644 index 0000000000..3ae67ca5fe --- /dev/null +++ b/src/pubkey.cpp @@ -0,0 +1,130 @@ +// 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. + +#include "pubkey.h" + +#include "eccryptoverify.h" + +#ifdef USE_SECP256K1 +#include <secp256k1.h> +#else +#include "ecwrapper.h" +#endif + +bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const { + if (!IsValid()) + return false; +#ifdef USE_SECP256K1 + if (secp256k1_ecdsa_verify((const unsigned char*)&hash, &vchSig[0], vchSig.size(), begin(), size()) != 1) + return false; +#else + CECKey key; + if (!key.SetPubKey(begin(), size())) + return false; + if (!key.Verify(hash, vchSig)) + return false; +#endif + return true; +} + +bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) { + if (vchSig.size() != 65) + return false; + int recid = (vchSig[0] - 27) & 3; + bool fComp = ((vchSig[0] - 27) & 4) != 0; +#ifdef USE_SECP256K1 + int pubkeylen = 65; + if (!secp256k1_ecdsa_recover_compact((const unsigned char*)&hash, &vchSig[1], (unsigned char*)begin(), &pubkeylen, fComp, recid)) + return false; + assert((int)size() == pubkeylen); +#else + CECKey key; + if (!key.Recover(hash, &vchSig[1], recid)) + return false; + std::vector<unsigned char> pubkey; + key.GetPubKey(pubkey, fComp); + Set(pubkey.begin(), pubkey.end()); +#endif + return true; +} + +bool CPubKey::IsFullyValid() const { + if (!IsValid()) + return false; +#ifdef USE_SECP256K1 + if (!secp256k1_ecdsa_pubkey_verify(begin(), size())) + return false; +#else + CECKey key; + if (!key.SetPubKey(begin(), size())) + return false; +#endif + return true; +} + +bool CPubKey::Decompress() { + if (!IsValid()) + return false; +#ifdef USE_SECP256K1 + int clen = size(); + int ret = secp256k1_ecdsa_pubkey_decompress((unsigned char*)begin(), &clen); + assert(ret); + assert(clen == (int)size()); +#else + CECKey key; + if (!key.SetPubKey(begin(), size())) + return false; + std::vector<unsigned char> pubkey; + key.GetPubKey(pubkey, false); + Set(pubkey.begin(), pubkey.end()); +#endif + return true; +} + +bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) 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); +#ifdef USE_SECP256K1 + pubkeyChild = *this; + bool ret = secp256k1_ecdsa_pubkey_tweak_add((unsigned char*)pubkeyChild.begin(), pubkeyChild.size(), out); +#else + CECKey key; + bool ret = key.SetPubKey(begin(), size()); + ret &= key.TweakPublic(out); + std::vector<unsigned char> pubkey; + key.GetPubKey(pubkey, true); + pubkeyChild.Set(pubkey.begin(), pubkey.end()); +#endif + return ret; +} + +void CExtPubKey::Encode(unsigned char code[74]) const { + code[0] = nDepth; + 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); + assert(pubkey.size() == 33); + memcpy(code+41, pubkey.begin(), 33); +} + +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); + pubkey.Set(code+41, code+74); +} + +bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const { + out.nDepth = nDepth + 1; + CKeyID id = pubkey.GetID(); + memcpy(&out.vchFingerprint[0], &id, 4); + out.nChild = nChild; + return pubkey.Derive(out.pubkey, out.vchChainCode, nChild, vchChainCode); +} diff --git a/src/pubkey.h b/src/pubkey.h new file mode 100644 index 0000000000..69b73a4e1c --- /dev/null +++ b/src/pubkey.h @@ -0,0 +1,206 @@ +// 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_PUBKEY_H +#define BITCOIN_PUBKEY_H + +#include "hash.h" +#include "serialize.h" +#include "uint256.h" + +#include <stdexcept> +#include <vector> + +/** + * secp256k1: + * const unsigned int PRIVATE_KEY_SIZE = 279; + * const unsigned int PUBLIC_KEY_SIZE = 65; + * const unsigned int SIGNATURE_SIZE = 72; + * + * see www.keylength.com + * script supports up to 75 for single byte push + */ + +/** A reference to a CKey: the Hash160 of its serialized public key */ +class CKeyID : public uint160 +{ +public: + CKeyID() : uint160(0) {} + CKeyID(const uint160& in) : uint160(in) {} +}; + +/** An encapsulated public key. */ +class CPubKey +{ +private: + + /** + * Just store the serialized data. + * Its length can very cheaply be computed from the first byte. + */ + unsigned char vch[65]; + + //! Compute the length of a pubkey with a given first byte. + unsigned int static GetLen(unsigned char chHeader) + { + if (chHeader == 2 || chHeader == 3) + return 33; + if (chHeader == 4 || chHeader == 6 || chHeader == 7) + return 65; + return 0; + } + + //! Set this key data to be invalid + void Invalidate() + { + vch[0] = 0xFF; + } + +public: + //! Construct an invalid public key. + CPubKey() + { + Invalidate(); + } + + //! Initialize a public key using begin/end iterators to byte data. + template <typename T> + void Set(const T pbegin, const T pend) + { + int len = pend == pbegin ? 0 : GetLen(pbegin[0]); + if (len && len == (pend - pbegin)) + memcpy(vch, (unsigned char*)&pbegin[0], len); + else + Invalidate(); + } + + //! Construct a public key using begin/end iterators to byte data. + template <typename T> + CPubKey(const T pbegin, const T pend) + { + Set(pbegin, pend); + } + + //! Construct a public key from a byte vector. + CPubKey(const std::vector<unsigned char>& vch) + { + Set(vch.begin(), vch.end()); + } + + //! Simple read-only vector-like interface to the pubkey data. + unsigned int size() const { return GetLen(vch[0]); } + const unsigned char* begin() const { return vch; } + const unsigned char* end() const { return vch + size(); } + const unsigned char& operator[](unsigned int pos) const { return vch[pos]; } + + //! Comparator implementation. + friend bool operator==(const CPubKey& a, const CPubKey& b) + { + return a.vch[0] == b.vch[0] && + memcmp(a.vch, b.vch, a.size()) == 0; + } + friend bool operator!=(const CPubKey& a, const CPubKey& b) + { + return !(a == b); + } + friend bool operator<(const CPubKey& a, const CPubKey& b) + { + return a.vch[0] < b.vch[0] || + (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0); + } + + //! Implement serialization, as if this was a byte vector. + unsigned int GetSerializeSize(int nType, int nVersion) const + { + return size() + 1; + } + template <typename Stream> + void Serialize(Stream& s, int nType, int nVersion) const + { + unsigned int len = size(); + ::WriteCompactSize(s, len); + s.write((char*)vch, len); + } + template <typename Stream> + void Unserialize(Stream& s, int nType, int nVersion) + { + unsigned int len = ::ReadCompactSize(s); + if (len <= 65) { + s.read((char*)vch, len); + } else { + // invalid pubkey, skip available data + char dummy; + while (len--) + s.read(&dummy, 1); + Invalidate(); + } + } + + //! Get the KeyID of this public key (hash of its serialization) + CKeyID GetID() const + { + return CKeyID(Hash160(vch, vch + size())); + } + + //! Get the 256-bit hash of this public key. + uint256 GetHash() const + { + return Hash(vch, vch + size()); + } + + /* + * Check syntactic correctness. + * + * Note that this is consensus critical as CheckSig() calls it! + */ + bool IsValid() const + { + return size() > 0; + } + + //! fully validate whether this is a valid public key (more expensive than IsValid()) + bool IsFullyValid() const; + + //! Check whether this is a compressed public key. + bool IsCompressed() const + { + return size() == 33; + } + + /** + * Verify a DER signature (~72 bytes). + * If this public key is not fully valid, the return value will be false. + */ + bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const; + + //! Recover a public key from a compact signature. + bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig); + + //! Turn this public key into an uncompressed public key. + bool Decompress(); + + //! Derive BIP32 child pubkey. + bool Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const; +}; + +struct CExtPubKey { + unsigned char nDepth; + unsigned char vchFingerprint[4]; + unsigned int nChild; + unsigned char vchChainCode[32]; + CPubKey pubkey; + + 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; + } + + void Encode(unsigned char code[74]) const; + void Decode(const unsigned char code[74]); + bool Derive(CExtPubKey& out, unsigned int nChild) const; +}; + +#endif // BITCOIN_PUBKEY_H diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index f336d47e83..5485d89f3e 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #if defined(HAVE_CONFIG_H) @@ -14,6 +14,7 @@ #include "csvmodelwriter.h" #include "editaddressdialog.h" #include "guiutil.h" +#include "scicon.h" #include <QIcon> #include <QMenu> @@ -34,6 +35,11 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : 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 switch(mode) diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index 20beb51ec4..5105f09ced 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 ADDRESSBOOKPAGE_H -#define ADDRESSBOOKPAGE_H +#ifndef BITCOIN_QT_ADDRESSBOOKPAGE_H +#define BITCOIN_QT_ADDRESSBOOKPAGE_H #include <QDialog> @@ -84,4 +84,4 @@ signals: void sendCoins(QString addr); }; -#endif // ADDRESSBOOKPAGE_H +#endif // BITCOIN_QT_ADDRESSBOOKPAGE_H diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 8d5284d5e9..bfb5bf3fec 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "addresstablemodel.h" diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 71691f5a26..6b34b2eac2 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 ADDRESSTABLEMODEL_H -#define ADDRESSTABLEMODEL_H +#ifndef BITCOIN_QT_ADDRESSTABLEMODEL_H +#define BITCOIN_QT_ADDRESSTABLEMODEL_H #include <QAbstractTableModel> #include <QStringList> @@ -92,4 +92,4 @@ public slots: friend class AddressTablePriv; }; -#endif // ADDRESSTABLEMODEL_H +#endif // BITCOIN_QT_ADDRESSTABLEMODEL_H diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index a448d5a9a0..9b7b59c0db 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "askpassphrasedialog.h" @@ -23,6 +23,10 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : { ui->setupUi(this); + ui->passEdit1->setMinimumSize(ui->passEdit1->sizeHint()); + ui->passEdit2->setMinimumSize(ui->passEdit2->sizeHint()); + ui->passEdit3->setMinimumSize(ui->passEdit3->sizeHint()); + ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE); ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE); ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE); @@ -35,9 +39,9 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : switch(mode) { case Encrypt: // Ask passphrase x2 + ui->warningLabel->setText(tr("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>.")); ui->passLabel1->hide(); ui->passEdit1->hide(); - ui->warningLabel->setText(tr("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>.")); setWindowTitle(tr("Encrypt wallet")); break; case Unlock: // Ask passphrase @@ -61,7 +65,6 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : ui->warningLabel->setText(tr("Enter the old and new passphrase to the wallet.")); break; } - textChanged(); connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); @@ -116,7 +119,7 @@ void AskPassphraseDialog::accept() { QMessageBox::warning(this, tr("Wallet encrypted"), "<qt>" + - tr("Bitcoin will close now to finish the encryption process. " + tr("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.") + "<br><br><b>" + diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index 1119e0861f..74d54d18f7 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 ASKPASSPHRASEDIALOG_H -#define ASKPASSPHRASEDIALOG_H +#ifndef BITCOIN_QT_ASKPASSPHRASEDIALOG_H +#define BITCOIN_QT_ASKPASSPHRASEDIALOG_H #include <QDialog> @@ -48,4 +48,4 @@ protected: bool eventFilter(QObject *object, QEvent *event); }; -#endif // ASKPASSPHRASEDIALOG_H +#endif // BITCOIN_QT_ASKPASSPHRASEDIALOG_H diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index bd686041c1..1adf4e00cb 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #if defined(HAVE_CONFIG_H) @@ -12,6 +12,7 @@ #include "guiconstants.h" #include "guiutil.h" #include "intro.h" +#include "networkstyle.h" #include "optionsmodel.h" #include "splashscreen.h" #include "utilitydialog.h" @@ -73,6 +74,7 @@ Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin); // Declare meta types used for QMetaObject::invokeMethod Q_DECLARE_METATYPE(bool*) +Q_DECLARE_METATYPE(CAmount) static void InitMessage(const std::string &message) { @@ -171,7 +173,7 @@ private: boost::thread_group threadGroup; /// Pass fatal exception message to UI thread - void handleRunawayException(std::exception *e); + void handleRunawayException(const std::exception *e); }; /** Main Bitcoin application object */ @@ -189,9 +191,9 @@ public: /// Create options model void createOptionsModel(); /// Create main window - void createWindow(bool isaTestNet); + void createWindow(const NetworkStyle *networkStyle); /// Create splash screen - void createSplashScreen(bool isaTestNet); + void createSplashScreen(const NetworkStyle *networkStyle); /// Request core initialization void requestInitialize(); @@ -238,7 +240,7 @@ BitcoinCore::BitcoinCore(): { } -void BitcoinCore::handleRunawayException(std::exception *e) +void BitcoinCore::handleRunawayException(const std::exception *e) { PrintExceptionContinue(e, "Runaway exception"); emit runawayException(QString::fromStdString(strMiscWarning)); @@ -258,7 +260,7 @@ void BitcoinCore::initialize() StartDummyRPCThread(); } emit initializeResult(rv); - } catch (std::exception& e) { + } catch (const std::exception& e) { handleRunawayException(&e); } catch (...) { handleRunawayException(NULL); @@ -275,7 +277,7 @@ void BitcoinCore::shutdown() Shutdown(); qDebug() << __func__ << ": Shutdown finished"; emit shutdownResult(1); - } catch (std::exception& e) { + } catch (const std::exception& e) { handleRunawayException(&e); } catch (...) { handleRunawayException(NULL); @@ -330,18 +332,18 @@ void BitcoinApplication::createOptionsModel() optionsModel = new OptionsModel(); } -void BitcoinApplication::createWindow(bool isaTestNet) +void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) { - window = new BitcoinGUI(isaTestNet, 0); + window = new BitcoinGUI(networkStyle, 0); pollShutdownTimer = new QTimer(window); connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown())); pollShutdownTimer->start(200); } -void BitcoinApplication::createSplashScreen(bool isaTestNet) +void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) { - SplashScreen *splash = new SplashScreen(0, isaTestNet); + SplashScreen *splash = new SplashScreen(0, networkStyle); // We don't hold a direct pointer to the splash screen after creation, so use // Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually. splash->setAttribute(Qt::WA_DeleteOnClose); @@ -509,6 +511,9 @@ int main(int argc, char *argv[]) // Register meta types used for QMetaObject::invokeMethod qRegisterMetaType< bool* >(); + // Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType) + // IMPORTANT if it is no longer a typedef use the normal variant above + qRegisterMetaType< CAmount >("CAmount"); /// 3. Application identification // must be set before OptionsModel is initialized or translations are loaded, @@ -546,7 +551,7 @@ int main(int argc, char *argv[]) } try { ReadConfigFile(mapArgs, mapMultiArgs); - } catch(std::exception &e) { + } catch (const std::exception& e) { QMessageBox::critical(0, QObject::tr("Bitcoin Core"), QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what())); return false; @@ -565,15 +570,13 @@ int main(int argc, char *argv[]) } #ifdef ENABLE_WALLET // Parse URIs on command line -- this can affect Params() - if (!PaymentServer::ipcParseCommandLine(argc, argv)) - exit(0); + PaymentServer::ipcParseCommandLine(argc, argv); #endif - bool isaTestNet = Params().NetworkID() != CBaseChainParams::MAIN; + + QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(QString::fromStdString(Params().NetworkIDString()))); + assert(!networkStyle.isNull()); // Allow for separate UI settings for testnets - if (isaTestNet) - QApplication::setApplicationName(QAPP_APP_NAME_TESTNET); - else - QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT); + QApplication::setApplicationName(networkStyle->getAppName()); // Re-initialize translations after changing application name (language in network-specific settings can be different) initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator); @@ -613,11 +616,11 @@ int main(int argc, char *argv[]) uiInterface.InitMessage.connect(InitMessage); if (GetBoolArg("-splash", true) && !GetBoolArg("-min", false)) - app.createSplashScreen(isaTestNet); + app.createSplashScreen(networkStyle.data()); try { - app.createWindow(isaTestNet); + app.createWindow(networkStyle.data()); app.requestInitialize(); #if defined(Q_OS_WIN) && QT_VERSION >= 0x050000 WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("Bitcoin Core didn't yet exit safely..."), (HWND)app.getMainWinId()); @@ -625,7 +628,7 @@ int main(int argc, char *argv[]) app.exec(); app.requestShutdown(); app.exec(); - } catch (std::exception& e) { + } catch (const std::exception& e) { PrintExceptionContinue(&e, "Runaway exception"); app.handleRunawayException(QString::fromStdString(strMiscWarning)); } catch (...) { diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index 42bb091e25..b54f2e2ed6 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -4,11 +4,11 @@ <file alias="address-book">res/icons/address-book.png</file> <file alias="quit">res/icons/quit.png</file> <file alias="send">res/icons/send.png</file> - <file alias="connect_0">res/icons/connect0_16.png</file> - <file alias="connect_1">res/icons/connect1_16.png</file> - <file alias="connect_2">res/icons/connect2_16.png</file> - <file alias="connect_3">res/icons/connect3_16.png</file> - <file alias="connect_4">res/icons/connect4_16.png</file> + <file alias="connect_0">res/icons/connect0.png</file> + <file alias="connect_1">res/icons/connect1.png</file> + <file alias="connect_2">res/icons/connect2.png</file> + <file alias="connect_3">res/icons/connect3.png</file> + <file alias="connect_4">res/icons/connect4.png</file> <file alias="transaction_0">res/icons/transaction0.png</file> <file alias="transaction_confirmed">res/icons/transaction2.png</file> <file alias="transaction_conflicted">res/icons/transaction_conflicted.png</file> @@ -25,7 +25,6 @@ <file alias="editpaste">res/icons/editpaste.png</file> <file alias="editcopy">res/icons/editcopy.png</file> <file alias="add">res/icons/add.png</file> - <file alias="bitcoin_testnet">res/icons/bitcoin_testnet.png</file> <file alias="edit">res/icons/edit.png</file> <file alias="history">res/icons/history.png</file> <file alias="overview">res/icons/overview.png</file> @@ -43,13 +42,15 @@ <file alias="lock_open">res/icons/lock_open.png</file> <file alias="key">res/icons/key.png</file> <file alias="filesave">res/icons/filesave.png</file> - <file alias="qrcode">res/icons/qrcode.png</file> <file alias="debugwindow">res/icons/debugwindow.png</file> + <file alias="open">res/icons/open.png</file> + <file alias="info">res/icons/info.png</file> + <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> </qresource> <qresource prefix="/images"> <file alias="about">res/images/about.png</file> - <file alias="splash">res/images/splash.png</file> - <file alias="splash_testnet">res/images/splash_testnet.png</file> </qresource> <qresource prefix="/movies"> <file alias="spinner-000">res/movies/spinner-000.png</file> @@ -87,5 +88,6 @@ <file alias="spinner-032">res/movies/spinner-032.png</file> <file alias="spinner-033">res/movies/spinner-033.png</file> <file alias="spinner-034">res/movies/spinner-034.png</file> + <file alias="spinner-035">res/movies/spinner-035.png</file> </qresource> </RCC> diff --git a/src/qt/bitcoinaddressvalidator.cpp b/src/qt/bitcoinaddressvalidator.cpp index 293cc168b9..d712705c43 100644 --- a/src/qt/bitcoinaddressvalidator.cpp +++ b/src/qt/bitcoinaddressvalidator.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "bitcoinaddressvalidator.h" diff --git a/src/qt/bitcoinaddressvalidator.h b/src/qt/bitcoinaddressvalidator.h index 0fb779f7d8..30d4a26d0e 100644 --- a/src/qt/bitcoinaddressvalidator.h +++ b/src/qt/bitcoinaddressvalidator.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. -#ifndef BITCOINADDRESSVALIDATOR_H -#define BITCOINADDRESSVALIDATOR_H +#ifndef BITCOIN_QT_BITCOINADDRESSVALIDATOR_H +#define BITCOIN_QT_BITCOINADDRESSVALIDATOR_H #include <QValidator> @@ -32,4 +32,4 @@ public: State validate(QString &input, int &pos) const; }; -#endif // BITCOINADDRESSVALIDATOR_H +#endif // BITCOIN_QT_BITCOINADDRESSVALIDATOR_H diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index 6466039013..fdb9bcd6d6 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "bitcoinamountfield.h" @@ -44,7 +44,7 @@ public: void fixup(QString &input) const { bool valid = false; - qint64 val = parse(input, &valid); + CAmount val = parse(input, &valid); if(valid) { input = BitcoinUnits::format(currentUnit, val, false, BitcoinUnits::separatorAlways); @@ -52,12 +52,12 @@ public: } } - qint64 value(bool *valid_out=0) const + CAmount value(bool *valid_out=0) const { return parse(text(), valid_out); } - void setValue(qint64 value) + void setValue(const CAmount& value) { lineEdit()->setText(BitcoinUnits::format(currentUnit, value, false, BitcoinUnits::separatorAlways)); emit valueChanged(); @@ -66,9 +66,9 @@ public: void stepBy(int steps) { bool valid = false; - qint64 val = value(&valid); + CAmount val = value(&valid); val = val + steps * singleStep; - val = qMin(qMax(val, Q_INT64_C(0)), BitcoinUnits::maxMoney()); + val = qMin(qMax(val, CAmount(0)), BitcoinUnits::maxMoney()); setValue(val); } @@ -78,7 +78,7 @@ public: if(text().isEmpty()) // Allow step-up with empty field return StepUpEnabled; bool valid = false; - qint64 val = value(&valid); + CAmount val = value(&valid); if(valid) { if(val > 0) @@ -92,7 +92,7 @@ public: void setDisplayUnit(int unit) { bool valid = false; - qint64 val = value(&valid); + CAmount val = value(&valid); currentUnit = unit; @@ -102,7 +102,7 @@ public: clear(); } - void setSingleStep(qint64 step) + void setSingleStep(const CAmount& step) { singleStep = step; } @@ -130,6 +130,7 @@ public: extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt, QStyle::SC_SpinBoxEditField, this).size(); hint += extra; + hint.setHeight(h); opt.rect = rect(); @@ -140,7 +141,7 @@ public: } private: int currentUnit; - qint64 singleStep; + CAmount singleStep; mutable QSize cachedMinimumSizeHint; /** @@ -148,9 +149,9 @@ private: * return validity. * @note Must return 0 if !valid. */ - qint64 parse(const QString &text, bool *valid_out=0) const + CAmount parse(const QString &text, bool *valid_out=0) const { - qint64 val = 0; + CAmount val = 0; bool valid = BitcoinUnits::parse(currentUnit, text, &val); if(valid) { @@ -220,6 +221,12 @@ void BitcoinAmountField::clear() unit->setCurrentIndex(0); } +void BitcoinAmountField::setEnabled(bool fEnabled) +{ + amount->setEnabled(fEnabled); + unit->setEnabled(fEnabled); +} + bool BitcoinAmountField::validate() { bool valid = false; @@ -253,12 +260,12 @@ QWidget *BitcoinAmountField::setupTabChain(QWidget *prev) return unit; } -qint64 BitcoinAmountField::value(bool *valid_out) const +CAmount BitcoinAmountField::value(bool *valid_out) const { return amount->value(valid_out); } -void BitcoinAmountField::setValue(qint64 value) +void BitcoinAmountField::setValue(const CAmount& value) { amount->setValue(value); } @@ -285,7 +292,7 @@ void BitcoinAmountField::setDisplayUnit(int newUnit) unit->setValue(newUnit); } -void BitcoinAmountField::setSingleStep(qint64 step) +void BitcoinAmountField::setSingleStep(const CAmount& step) { amount->setSingleStep(step); } diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h index 84795a7e7a..b047e6c51a 100644 --- a/src/qt/bitcoinamountfield.h +++ b/src/qt/bitcoinamountfield.h @@ -1,9 +1,11 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 BITCOINAMOUNTFIELD_H -#define BITCOINAMOUNTFIELD_H +#ifndef BITCOIN_QT_BITCOINAMOUNTFIELD_H +#define BITCOIN_QT_BITCOINAMOUNTFIELD_H + +#include "amount.h" #include <QWidget> @@ -19,16 +21,18 @@ class BitcoinAmountField: public QWidget { Q_OBJECT + // ugly hack: for some unknown reason CAmount (instead of qint64) does not work here as expected + // discussion: https://github.com/bitcoin/bitcoin/pull/5117 Q_PROPERTY(qint64 value READ value WRITE setValue NOTIFY valueChanged USER true) public: explicit BitcoinAmountField(QWidget *parent = 0); - qint64 value(bool *valid=0) const; - void setValue(qint64 value); + CAmount value(bool *value=0) const; + void setValue(const CAmount& value); /** Set single step in satoshis **/ - void setSingleStep(qint64 step); + void setSingleStep(const CAmount& step); /** Make read-only **/ void setReadOnly(bool fReadOnly); @@ -44,6 +48,9 @@ public: /** Make field empty and ready for new input. */ void clear(); + /** Enable/Disable. */ + void setEnabled(bool fEnabled); + /** Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907), in these cases we have to set it up manually. */ @@ -65,4 +72,4 @@ private slots: }; -#endif // BITCOINAMOUNTFIELD_H +#endif // BITCOIN_QT_BITCOINAMOUNTFIELD_H diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index dd5192982e..3b8fd985a0 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "bitcoingui.h" @@ -8,17 +8,19 @@ #include "clientmodel.h" #include "guiconstants.h" #include "guiutil.h" +#include "networkstyle.h" #include "notificator.h" #include "openuridialog.h" #include "optionsdialog.h" #include "optionsmodel.h" #include "rpcconsole.h" +#include "scicon.h" #include "utilitydialog.h" #ifdef ENABLE_WALLET #include "walletframe.h" #include "walletmodel.h" -#endif +#endif // ENABLE_WALLET #ifdef Q_OS_MAC #include "macdockiconhandler.h" @@ -35,7 +37,6 @@ #include <QDateTime> #include <QDesktopWidget> #include <QDragEnterEvent> -#include <QIcon> #include <QListWidget> #include <QMenuBar> #include <QMessageBox> @@ -59,7 +60,7 @@ const QString BitcoinGUI::DEFAULT_WALLET = "~Default"; -BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) : +BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : QMainWindow(parent), clientModel(0), walletFrame(0), @@ -102,36 +103,23 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) : QString windowTitle = tr("Bitcoin Core") + " - "; #ifdef ENABLE_WALLET /* if compiled with wallet support, -disablewallet can still disable the wallet */ - bool enableWallet = !GetBoolArg("-disablewallet", false); + enableWallet = !GetBoolArg("-disablewallet", false); #else - bool enableWallet = false; -#endif + enableWallet = false; +#endif // ENABLE_WALLET if(enableWallet) { windowTitle += tr("Wallet"); } else { windowTitle += tr("Node"); } - - if (!fIsTestnet) - { -#ifndef Q_OS_MAC - QApplication::setWindowIcon(QIcon(":icons/bitcoin")); - setWindowIcon(QIcon(":icons/bitcoin")); -#else - MacDockIconHandler::instance()->setIcon(QIcon(":icons/bitcoin")); -#endif - } - else - { - windowTitle += " " + tr("[testnet]"); + windowTitle += " " + networkStyle->getTitleAddText(); #ifndef Q_OS_MAC - QApplication::setWindowIcon(QIcon(":icons/bitcoin_testnet")); - setWindowIcon(QIcon(":icons/bitcoin_testnet")); + QApplication::setWindowIcon(networkStyle->getTrayAndWindowIcon()); + setWindowIcon(networkStyle->getTrayAndWindowIcon()); #else - MacDockIconHandler::instance()->setIcon(QIcon(":icons/bitcoin_testnet")); + MacDockIconHandler::instance()->setIcon(networkStyle->getAppIcon()); #endif - } setWindowTitle(windowTitle); #if defined(Q_OS_MAC) && QT_VERSION < 0x050000 @@ -140,7 +128,7 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) : setUnifiedTitleAndToolBarOnMac(true); #endif - rpcConsole = new RPCConsole(enableWallet ? this : 0); + rpcConsole = new RPCConsole(0); #ifdef ENABLE_WALLET if(enableWallet) { @@ -148,7 +136,7 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) : walletFrame = new WalletFrame(this); setCentralWidget(walletFrame); } else -#endif +#endif // ENABLE_WALLET { /* When compiled without wallet or -disablewallet is provided, * the central widget is the rpc console. @@ -161,7 +149,7 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) : // Create actions for the toolbar, menu bar and tray/dock icon // Needs walletFrame to be initialized - createActions(fIsTestnet); + createActions(networkStyle); // Create application menu bar createMenuBar(); @@ -170,7 +158,7 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) : createToolBars(); // Create system tray icon and notification - createTrayIcon(fIsTestnet); + createTrayIcon(networkStyle); // Create status bar statusBar(); @@ -202,7 +190,7 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) : // Progress bar and label for blocks download progressBarLabel = new QLabel(); progressBarLabel->setVisible(false); - progressBar = new QProgressBar(); + progressBar = new GUIUtil::ProgressBar(); progressBar->setAlignment(Qt::AlignCenter); progressBar->setVisible(false); @@ -246,40 +234,43 @@ BitcoinGUI::~BitcoinGUI() delete appMenuBar; MacDockIconHandler::instance()->setMainWindow(NULL); #endif + + delete rpcConsole; } -void BitcoinGUI::createActions(bool fIsTestnet) +void BitcoinGUI::createActions(const NetworkStyle *networkStyle) { QActionGroup *tabGroup = new QActionGroup(this); - overviewAction = new QAction(QIcon(":/icons/overview"), tr("&Overview"), this); + overviewAction = new QAction(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(QIcon(":/icons/send"), tr("&Send"), this); + sendCoinsAction = new QAction(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); - receiveCoinsAction = new QAction(QIcon(":/icons/receiving_addresses"), tr("&Receive"), this); + receiveCoinsAction = new QAction(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); - historyAction = new QAction(QIcon(":/icons/history"), tr("&Transactions"), this); + historyAction = new QAction(SingleColorIcon(":/icons/history"), tr("&Transactions"), this); historyAction->setStatusTip(tr("Browse transaction history")); historyAction->setToolTip(historyAction->statusTip()); historyAction->setCheckable(true); historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4)); tabGroup->addAction(historyAction); +#ifdef ENABLE_WALLET // These showNormalIfMinimized are needed because Send Coins and Receive Coins // can be triggered from the tray menu, and need to show the GUI to be useful. connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); @@ -290,57 +281,48 @@ void BitcoinGUI::createActions(bool fIsTestnet) connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage())); connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage())); +#endif // ENABLE_WALLET - quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this); + quitAction = new QAction(TextColorIcon(":/icons/quit"), tr("E&xit"), this); quitAction->setStatusTip(tr("Quit application")); quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); quitAction->setMenuRole(QAction::QuitRole); - if (!fIsTestnet) - aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About Bitcoin Core"), this); - else - aboutAction = new QAction(QIcon(":/icons/bitcoin_testnet"), tr("&About Bitcoin Core"), this); + aboutAction = new QAction(TextColorIcon(":/icons/about"), tr("&About Bitcoin Core"), this); aboutAction->setStatusTip(tr("Show information about Bitcoin Core")); aboutAction->setMenuRole(QAction::AboutRole); -#if QT_VERSION < 0x050000 - aboutQtAction = new QAction(QIcon(":/trolltech/qmessagebox/images/qtlogo-64.png"), tr("About &Qt"), this); -#else - aboutQtAction = new QAction(QIcon(":/qt-project.org/qmessagebox/images/qtlogo-64.png"), tr("About &Qt"), this); -#endif + aboutQtAction = new QAction(TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this); aboutQtAction->setStatusTip(tr("Show information about Qt")); aboutQtAction->setMenuRole(QAction::AboutQtRole); - optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this); - optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin")); + optionsAction = new QAction(TextColorIcon(":/icons/options"), tr("&Options..."), this); + optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin Core")); optionsAction->setMenuRole(QAction::PreferencesRole); - if (!fIsTestnet) - toggleHideAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Show / Hide"), this); - else - toggleHideAction = new QAction(QIcon(":/icons/bitcoin_testnet"), tr("&Show / Hide"), this); + toggleHideAction = new QAction(TextColorIcon(":/icons/about"), tr("&Show / Hide"), this); toggleHideAction->setStatusTip(tr("Show or hide the main Window")); - encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this); + encryptWalletAction = new QAction(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(QIcon(":/icons/filesave"), tr("&Backup Wallet..."), this); + backupWalletAction = new QAction(TextColorIcon(":/icons/filesave"), tr("&Backup Wallet..."), this); backupWalletAction->setStatusTip(tr("Backup wallet to another location")); - changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this); + changePassphraseAction = new QAction(TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this); changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption")); - signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this); + signMessageAction = new QAction(TextColorIcon(":/icons/edit"), tr("Sign &message..."), this); signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them")); - verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this); + verifyMessageAction = new QAction(TextColorIcon(":/icons/verify"), tr("&Verify message..."), this); verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses")); - openRPCConsoleAction = new QAction(QIcon(":/icons/debugwindow"), tr("&Debug window"), this); + openRPCConsoleAction = new QAction(TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this); openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console")); - usedSendingAddressesAction = new QAction(QIcon(":/icons/address-book"), tr("&Sending addresses..."), this); + usedSendingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this); usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels")); - usedReceivingAddressesAction = new QAction(QIcon(":/icons/address-book"), tr("&Receiving addresses..."), this); + usedReceivingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Receiving addresses..."), this); usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels")); - openAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_FileIcon), tr("Open &URI..."), this); + openAction = new QAction(TextColorIcon(":/icons/open"), tr("Open &URI..."), this); openAction->setStatusTip(tr("Open a bitcoin: URI or payment request")); - showHelpMessageAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation), tr("&Command-line options"), this); + showHelpMessageAction = new QAction(TextColorIcon(":/icons/info"), tr("&Command-line options"), this); showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options")); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); @@ -361,7 +343,7 @@ void BitcoinGUI::createActions(bool fIsTestnet) connect(usedReceivingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedReceivingAddresses())); connect(openAction, SIGNAL(triggered()), this, SLOT(openClicked())); } -#endif +#endif // ENABLE_WALLET } void BitcoinGUI::createMenuBar() @@ -451,7 +433,7 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) { walletFrame->setClientModel(clientModel); } -#endif +#endif // ENABLE_WALLET unitDisplayControl->setOptionsModel(clientModel->getOptionsModel()); } else { // Disable possibility to show main window via action @@ -487,7 +469,7 @@ void BitcoinGUI::removeAllWallets() setWalletActionsEnabled(false); walletFrame->removeAllWallets(); } -#endif +#endif // ENABLE_WALLET void BitcoinGUI::setWalletActionsEnabled(bool enabled) { @@ -505,22 +487,13 @@ void BitcoinGUI::setWalletActionsEnabled(bool enabled) openAction->setEnabled(enabled); } -void BitcoinGUI::createTrayIcon(bool fIsTestnet) +void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle) { #ifndef Q_OS_MAC trayIcon = new QSystemTrayIcon(this); - - if (!fIsTestnet) - { - trayIcon->setToolTip(tr("Bitcoin Core client")); - trayIcon->setIcon(QIcon(":/icons/bitcoin")); - } - else - { - trayIcon->setToolTip(tr("Bitcoin Core client") + " " + tr("[testnet]")); - trayIcon->setIcon(QIcon(":/icons/bitcoin_testnet")); - } - + QString toolTip = tr("Bitcoin Core client") + " " + networkStyle->getTitleAddText(); + trayIcon->setToolTip(toolTip); + trayIcon->setIcon(networkStyle->getTrayAndWindowIcon()); trayIcon->show(); #endif @@ -579,7 +552,7 @@ void BitcoinGUI::optionsClicked() if(!clientModel || !clientModel->getOptionsModel()) return; - OptionsDialog dlg(this); + OptionsDialog dlg(this, enableWallet); dlg.setModel(clientModel->getOptionsModel()); dlg.exec(); } @@ -643,7 +616,7 @@ void BitcoinGUI::gotoVerifyMessageTab(QString addr) { if (walletFrame) walletFrame->gotoVerifyMessageTab(addr); } -#endif +#endif // ENABLE_WALLET void BitcoinGUI::setNumConnections(int count) { @@ -656,12 +629,15 @@ void BitcoinGUI::setNumConnections(int count) case 7: case 8: case 9: icon = ":/icons/connect_3"; break; default: icon = ":/icons/connect_4"; break; } - labelConnectionsIcon->setPixmap(QIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelConnectionsIcon->setPixmap(SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count)); } void BitcoinGUI::setNumBlocks(int count) { + if(!clientModel) + return; + // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbelled text) statusBar()->clearMessage(); @@ -689,18 +665,18 @@ void BitcoinGUI::setNumBlocks(int count) QDateTime currentDate = QDateTime::currentDateTime(); int secs = lastBlockDate.secsTo(currentDate); - tooltip = tr("Processed %1 blocks of transaction history.").arg(count); + tooltip = tr("Processed %n blocks 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(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); + labelBlocksIcon->setPixmap(SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); #ifdef ENABLE_WALLET if(walletFrame) walletFrame->showOutOfSyncWarning(false); -#endif +#endif // ENABLE_WALLET progressBarLabel->setVisible(false); progressBar->setVisible(false); @@ -741,7 +717,7 @@ void BitcoinGUI::setNumBlocks(int count) tooltip = tr("Catching up...") + QString("<br>") + tooltip; if(count != prevBlocks) { - labelBlocksIcon->setPixmap(QIcon(QString( + labelBlocksIcon->setPixmap(SingleColorIcon(QString( ":/movies/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0'))) .pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE)); spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES; @@ -751,7 +727,7 @@ void BitcoinGUI::setNumBlocks(int count) #ifdef ENABLE_WALLET if(walletFrame) walletFrame->showOutOfSyncWarning(true); -#endif +#endif // ENABLE_WALLET tooltip += QString("<br>"); tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText); @@ -832,7 +808,7 @@ void BitcoinGUI::changeEvent(QEvent *e) #ifndef Q_OS_MAC // Ignored on Mac if(e->type() == QEvent::WindowStateChange) { - if(clientModel && clientModel->getOptionsModel()->getMinimizeToTray()) + if(clientModel && clientModel->getOptionsModel() && clientModel->getOptionsModel()->getMinimizeToTray()) { QWindowStateChangeEvent *wsevt = static_cast<QWindowStateChangeEvent*>(e); if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized()) @@ -847,21 +823,24 @@ void BitcoinGUI::changeEvent(QEvent *e) void BitcoinGUI::closeEvent(QCloseEvent *event) { - if(clientModel) - { #ifndef Q_OS_MAC // Ignored on Mac + if(clientModel && clientModel->getOptionsModel()) + { if(!clientModel->getOptionsModel()->getMinimizeToTray() && !clientModel->getOptionsModel()->getMinimizeOnClose()) { + // close rpcConsole in case it was open to make some space for the shutdown window + rpcConsole->close(); + QApplication::quit(); } -#endif } +#endif QMainWindow::closeEvent(event); } #ifdef ENABLE_WALLET -void BitcoinGUI::incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address) +void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address) { // On new transaction, make an info balloon message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"), @@ -874,7 +853,7 @@ void BitcoinGUI::incomingTransaction(const QString& date, int unit, qint64 amoun .arg(type) .arg(address), CClientUIInterface::MSG_INFORMATION); } -#endif +#endif // ENABLE_WALLET void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event) { @@ -917,8 +896,7 @@ bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient) gotoSendCoinsPage(); return true; } - else - return false; + return false; } void BitcoinGUI::setEncryptionStatus(int status) @@ -933,7 +911,7 @@ void BitcoinGUI::setEncryptionStatus(int status) break; case WalletModel::Unlocked: labelEncryptionIcon->show(); - labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setPixmap(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); @@ -941,7 +919,7 @@ void BitcoinGUI::setEncryptionStatus(int status) break; case WalletModel::Locked: labelEncryptionIcon->show(); - labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setPixmap(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); @@ -949,7 +927,7 @@ void BitcoinGUI::setEncryptionStatus(int status) break; } } -#endif +#endif // ENABLE_WALLET void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden) { @@ -1017,6 +995,9 @@ void BitcoinGUI::showProgress(const QString &title, int nProgress) static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style) { bool modal = (style & CClientUIInterface::MODAL); + // The SECURE flag has no effect in the Qt GUI. + // bool secure = (style & CClientUIInterface::SECURE); + style &= ~CClientUIInterface::SECURE; bool ret = false; // In case of modal message, use blocking connection to wait for user to click a button QMetaObject::invokeMethod(gui, "message", @@ -1085,7 +1066,7 @@ void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *optionsModel) /** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */ void UnitDisplayStatusBarControl::updateDisplayUnit(int newUnits) { - setPixmap(QIcon(":/icons/unit_" + BitcoinUnits::id(newUnits)).pixmap(31,STATUSBAR_ICONSIZE)); + setPixmap(SingleColorIcon(":/icons/unit_" + BitcoinUnits::id(newUnits)).pixmap(31,STATUSBAR_ICONSIZE)); } /** Shows context menu with Display Unit options by the mouse coordinates */ diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 30b05cb7d9..7509a00734 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -1,14 +1,16 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. -#ifndef BITCOINGUI_H -#define BITCOINGUI_H +#ifndef BITCOIN_QT_BITCOINGUI_H +#define BITCOIN_QT_BITCOINGUI_H #if defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" #endif +#include "amount.h" + #include <QLabel> #include <QMainWindow> #include <QMap> @@ -17,6 +19,7 @@ #include <QSystemTrayIcon> class ClientModel; +class NetworkStyle; class Notificator; class OptionsModel; class RPCConsole; @@ -44,7 +47,7 @@ class BitcoinGUI : public QMainWindow public: static const QString DEFAULT_WALLET; - explicit BitcoinGUI(bool fIsTestnet = false, QWidget *parent = 0); + explicit BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent = 0); ~BitcoinGUI(); /** Set the client model. @@ -60,7 +63,8 @@ public: bool addWallet(const QString& name, WalletModel *walletModel); bool setCurrentWallet(const QString& name); void removeAllWallets(); -#endif +#endif // ENABLE_WALLET + bool enableWallet; protected: void changeEvent(QEvent *e); @@ -112,13 +116,13 @@ private: int spinnerFrame; /** Create the main UI actions. */ - void createActions(bool fIsTestnet); + void createActions(const NetworkStyle *networkStyle); /** Create the menu bar and sub-menus. */ void createMenuBar(); /** Create the toolbars */ void createToolBars(); /** Create system tray icon and notification */ - void createTrayIcon(bool fIsTestnet); + void createTrayIcon(const NetworkStyle *networkStyle); /** Create system tray menu (or setup the dock menu) */ void createTrayIconMenu(); @@ -159,8 +163,8 @@ public slots: bool handlePaymentRequest(const SendCoinsRecipient& recipient); /** Show incoming transaction notification for new transactions. */ - void incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address); -#endif + void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address); +#endif // ENABLE_WALLET private slots: #ifdef ENABLE_WALLET @@ -180,7 +184,7 @@ private slots: /** Show open dialog */ void openClicked(); -#endif +#endif // ENABLE_WALLET /** Show configuration dialog */ void optionsClicked(); /** Show about dialog */ @@ -233,4 +237,4 @@ private slots: void onMenuSelection(QAction* action); }; -#endif // BITCOINGUI_H +#endif // BITCOIN_QT_BITCOINGUI_H diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 3b4b40aae3..548529865a 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -22,11 +22,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "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", "" -"(default: 1, 1 = keep tx meta data e.g. account owner and payment request " -"information, 2 = drop tx meta data)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" -"Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!" -"3DES:@STRENGTH)"), +"(1 = keep tx meta data e.g. account owner and payment request information, 2 " +"= drop tx meta data)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "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 " @@ -49,7 +46,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "running."), QT_TRANSLATE_NOOP("bitcoin-core", "" "Continuously rate-limit free transactions to <n>*1000 bytes per minute " -"(default:15)"), +"(default:%u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Create new files with system default permissions, instead of umask 077 (only " "effective with disabled wallet functionality)"), @@ -57,7 +54,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Delete all wallet transactions and only recover those parts of the " "blockchain through -rescan on startup"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Distributed under the MIT/X11 software license, see the accompanying file " +"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 " @@ -75,9 +72,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Error: Unsupported argument -socks found. Setting SOCKS version isn't " "possible anymore, only SOCKS5 proxies are supported."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Execute command when a network tx respends wallet tx input (%s=respend TxID, " -"%t=wallet TxID)"), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Execute command when a relevant alert is received or we see a really long " "fork (%s in cmd is replaced by message)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -94,22 +88,27 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "creation (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Flush database activity from memory pool to disk log every <n> megabytes " -"(default: 100)"), +"(default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"How thorough the block verification of -checkblocks is (0-4, default: 3)"), +"How thorough the block verification of -checkblocks is (0-4, default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "If paytxfee is not set, include enough fee so transactions are confirmed on " -"average within n blocks (default: 1)"), +"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", "" -"Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)"), +"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", "" -"Number of seconds to keep misbehaving peers from reconnecting (default: " -"86400)"), +"Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Output debugging information (default: 0, supplying <category> is optional)"), +"Output debugging information (default: %u, supplying <category> is optional)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Query for peer addresses via DNS lookup, if low on addresses (default: 1 " "unless -connect)"), @@ -119,8 +118,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Set the number of script verification threads (%u to %d, 0 = auto, <0 = " "leave that many cores free, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Set the processor limit for when generation is on (-1 = unlimited, default: " -"-1)"), +"Set the number of threads for coin generation if enabled (-1 = all cores, " +"default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "This is a pre-release test build - use at your own risk - do not use for " "mining or merchant applications"), @@ -132,8 +131,8 @@ 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 separate SOCKS5 proxy to reach peers via Tor hidden services (default: -" -"proxy)"), +"Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: " +"%s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Warning: -paytxfee is set very high! This is the transaction fee you will " "pay if you send a transaction."), @@ -154,19 +153,20 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect " "you should restore from a backup."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Whitelist peers connecting from the given netmask or ip. Can be specified " -"multiple times."), +"Whitelist peers connecting from the given netmask or IP address. Can be " +"specified multiple times."), QT_TRANSLATE_NOOP("bitcoin-core", "" "Whitelisted peers cannot be DoS banned and their transactions are always " "relayed, even if they are already in the mempool, useful e.g. for a gateway"), +QT_TRANSLATE_NOOP("bitcoin-core", "(default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "(default: 1)"), -QT_TRANSLATE_NOOP("bitcoin-core", "(default: wallet.dat)"), QT_TRANSLATE_NOOP("bitcoin-core", "<category> can be:"), QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"), QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1 if no -proxy or -connect)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Acceptable ciphers (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"), QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"), -QT_TRANSLATE_NOOP("bitcoin-core", "Always query for peer addresses via DNS lookup (default: 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", "Cannot downgrade wallet"), @@ -182,7 +182,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Copyright (C) 2009-%i The Bitcoin Core Develo 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: 0)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Disable safemode, override a real safe mode event (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Discover own IP address (default: 1 when listening and no -externalip)"), 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?"), @@ -195,29 +195,19 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"), QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin Core"), QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"), QT_TRANSLATE_NOOP("bitcoin-core", "Error"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occured, 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", "Error: Wallet locked, unable to create transaction!"), -QT_TRANSLATE_NOOP("bitcoin-core", "Error: system error: "), QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to read block info"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to read block"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to sync block index"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write block index"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write block info"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write block"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write file info"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write to coin database"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write transaction index"), -QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write undo data"), 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: 0)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins (default: 0)"), -QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: 288, 0 = all)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Force safe mode (default: %u)"), +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: 0)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Include IP addresses in debug output (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Incorrect or no genesis block found. Wrong datadir for network?"), QT_TRANSLATE_NOOP("bitcoin-core", "Information"), QT_TRANSLATE_NOOP("bitcoin-core", "Initialization sanity check failed. Bitcoin Core is shutting down."), @@ -231,62 +221,62 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'") QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount"), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable blocks in memory (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Limit size of signature cache to <n> entries (default: 50000)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: 8333 or testnet: 18333)"), +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..."), QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."), QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."), -QT_TRANSLATE_NOOP("bitcoin-core", "Log transaction priority and fee per kB when mining blocks (default: 0)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Maintain a full transaction index (default: 0)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: 125)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Need to specify a port with -whitebind: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Node relay options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Not enough file descriptors available."), -QT_TRANSLATE_NOOP("bitcoin-core", "Only accept block chain matching built-in checkpoints (default: 1)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (IPv4, IPv6 or Tor)"), +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: 1)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Print block on startup, if found in block index"), -QT_TRANSLATE_NOOP("bitcoin-core", "Print block tree on startup (default: 0)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Print block tree on startup (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"), QT_TRANSLATE_NOOP("bitcoin-core", "RPC server options:"), 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", "Relay and mine data carrier transactions (default: 1)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Relay non-P2SH multisig (default: 1)"), +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: 1)"), +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", "Server certificate file (default: server.cert)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: server.pem)"), +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 database cache size in megabytes (%d to %d, default: %d)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: 100)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: %u)"), 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: 0)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: 4)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Sets the DB_PRIVATE flag in the wallet db environment (default: 1)"), +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", "Shrink debug.log file on client startup (default: 1 when no -debug)"), QT_TRANSLATE_NOOP("bitcoin-core", "Signing transaction failed"), -QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: bitcoin.conf)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout in milliseconds (default: 5000)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: %s)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout in milliseconds (minimum: 1, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory"), -QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: bitcoind.pid)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)"), QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"), -QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: 1)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Stop running after importing blocks from disk (default: 0)"), -QT_TRANSLATE_NOOP("bitcoin-core", "System error: "), +QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Stop running after importing blocks from disk (default: %u)"), 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: 100)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "To use the %s option"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amount too small"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"), @@ -295,7 +285,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind r 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: 0)"), +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"), diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp index 3215363fa0..758fba7058 100644 --- a/src/qt/bitcoinunits.cpp +++ b/src/qt/bitcoinunits.cpp @@ -1,10 +1,10 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "bitcoinunits.h" -#include "core.h" +#include "primitives/transaction.h" #include <QStringList> @@ -91,12 +91,13 @@ int BitcoinUnits::decimals(int unit) } } -QString BitcoinUnits::format(int unit, qint64 n, bool fPlus, SeparatorStyle separators) +QString BitcoinUnits::format(int unit, const CAmount& nIn, bool fPlus, SeparatorStyle separators) { // Note: not using straight sprintf here because we do NOT want // localized number formatting. if(!valid(unit)) return QString(); // Refuse to format invalid unit + qint64 n = (qint64)nIn; qint64 coin = factor(unit); int num_decimals = decimals(unit); qint64 n_abs = (n > 0 ? n : -n); @@ -105,10 +106,8 @@ QString BitcoinUnits::format(int unit, qint64 n, bool fPlus, SeparatorStyle sepa QString quotient_str = QString::number(quotient); QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0'); - // Use SI-stule separators as these are locale indendent and can't be - // confused with the decimal marker. Rule is to use a thin space every - // three digits on *both* sides of the decimal point - but only if there - // are five or more digits + // Use SI-style thin space separators as these are locale independent and can't be + // confused with the decimal marker. QChar thin_sp(THIN_SP_CP); int q_size = quotient_str.size(); if (separators == separatorAlways || (separators == separatorStandard && q_size > 4)) @@ -138,12 +137,12 @@ QString BitcoinUnits::format(int unit, qint64 n, bool fPlus, SeparatorStyle sepa // Please take care to use formatHtmlWithUnit instead, when // appropriate. -QString BitcoinUnits::formatWithUnit(int unit, qint64 amount, bool plussign, SeparatorStyle separators) +QString BitcoinUnits::formatWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators) { return format(unit, amount, plussign, separators) + QString(" ") + name(unit); } -QString BitcoinUnits::formatHtmlWithUnit(int unit, qint64 amount, bool plussign, SeparatorStyle separators) +QString BitcoinUnits::formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators) { QString str(formatWithUnit(unit, amount, plussign, separators)); str.replace(QChar(THIN_SP_CP), QString(THIN_SP_HTML)); @@ -151,7 +150,7 @@ QString BitcoinUnits::formatHtmlWithUnit(int unit, qint64 amount, bool plussign, } -bool BitcoinUnits::parse(int unit, const QString &value, qint64 *val_out) +bool BitcoinUnits::parse(int unit, const QString &value, CAmount *val_out) { if(!valid(unit) || value.isEmpty()) return false; // Refuse to parse invalid unit or empty string @@ -182,7 +181,7 @@ bool BitcoinUnits::parse(int unit, const QString &value, qint64 *val_out) { return false; // Longer numbers will exceed 63 bits } - qint64 retvalue = str.toLongLong(&ok); + CAmount retvalue(str.toLongLong(&ok)); if(val_out) { *val_out = retvalue; @@ -226,7 +225,7 @@ QVariant BitcoinUnits::data(const QModelIndex &index, int role) const return QVariant(); } -qint64 BitcoinUnits::maxMoney() +CAmount BitcoinUnits::maxMoney() { return MAX_MONEY; } diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h index be9dca6012..a01fcc8cf9 100644 --- a/src/qt/bitcoinunits.h +++ b/src/qt/bitcoinunits.h @@ -1,9 +1,11 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 BITCOINUNITS_H -#define BITCOINUNITS_H +#ifndef BITCOIN_QT_BITCOINUNITS_H +#define BITCOIN_QT_BITCOINUNITS_H + +#include "amount.h" #include <QAbstractListModel> #include <QString> @@ -85,12 +87,12 @@ public: //! Number of decimals left static int decimals(int unit); //! Format as string - static QString format(int unit, qint64 amount, bool plussign=false, SeparatorStyle separators=separatorStandard); + static QString format(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); //! Format as string (with unit) - static QString formatWithUnit(int unit, qint64 amount, bool plussign=false, SeparatorStyle separators=separatorStandard); - static QString formatHtmlWithUnit(int unit, qint64 amount, bool plussign=false, SeparatorStyle separators=separatorStandard); + static QString formatWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); + static QString formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); //! Parse string to coin amount - static bool parse(int unit, const QString &value, qint64 *val_out); + static bool parse(int unit, const QString &value, CAmount *val_out); //! Gets title for amount column including current display unit if optionsModel reference available */ static QString getAmountColumnTitle(int unit); ///@} @@ -117,11 +119,11 @@ public: } //! Return maximum number of base units (Satoshis) - static qint64 maxMoney(); + static CAmount maxMoney(); private: QList<BitcoinUnits::Unit> unitlist; }; typedef BitcoinUnits::Unit BitcoinUnit; -#endif // BITCOINUNITS_H +#endif // BITCOIN_QT_BITCOINUNITS_H diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 738fb48ef8..493cdd6dd2 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "clientmodel.h" @@ -10,6 +10,7 @@ #include "alert.h" #include "chainparams.h" #include "checkpoints.h" +#include "clientversion.h" #include "main.h" #include "net.h" #include "ui_interface.h" diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index c7bd60bd41..4856a72d7d 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 CLIENTMODEL_H -#define CLIENTMODEL_H +#ifndef BITCOIN_QT_CLIENTMODEL_H +#define BITCOIN_QT_CLIENTMODEL_H #include <QObject> @@ -102,4 +102,4 @@ public slots: void updateAlert(const QString &hash, int status); }; -#endif // CLIENTMODEL_H +#endif // BITCOIN_QT_CLIENTMODEL_H diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index d10463fd8f..60e7d62a7a 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "coincontroldialog.h" @@ -10,6 +10,7 @@ #include "guiutil.h" #include "init.h" #include "optionsmodel.h" +#include "scicon.h" #include "walletmodel.h" #include "coincontrol.h" @@ -24,12 +25,13 @@ #include <QDialogButtonBox> #include <QFlags> #include <QIcon> +#include <QSettings> #include <QString> #include <QTreeWidget> #include <QTreeWidgetItem> using namespace std; -QList<qint64> CoinControlDialog::payAmounts; +QList<CAmount> CoinControlDialog::payAmounts; CCoinControl* CoinControlDialog::coinControl = new CCoinControl(); CoinControlDialog::CoinControlDialog(QWidget *parent) : @@ -130,10 +132,22 @@ CoinControlDialog::CoinControlDialog(QWidget *parent) : // default view is sorted by amount desc sortView(COLUMN_AMOUNT_INT64, Qt::DescendingOrder); + + // restore list mode and sortorder as a convenience feature + QSettings settings; + if (settings.contains("nCoinControlMode") && !settings.value("nCoinControlMode").toBool()) + ui->radioTreeMode->click(); + if (settings.contains("nCoinControlSortColumn") && settings.contains("nCoinControlSortOrder")) + sortView(settings.value("nCoinControlSortColumn").toInt(), ((Qt::SortOrder)settings.value("nCoinControlSortOrder").toInt())); } CoinControlDialog::~CoinControlDialog() { + QSettings settings; + settings.setValue("nCoinControlMode", ui->radioListMode->isChecked()); + settings.setValue("nCoinControlSortColumn", sortColumn); + settings.setValue("nCoinControlSortOrder", (int)sortOrder); + delete ui; } @@ -261,7 +275,7 @@ void CoinControlDialog::lockCoin() COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); model->lockCoin(outpt); contextMenuItem->setDisabled(true); - contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon(":/icons/lock_closed")); + contextMenuItem->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed")); updateLabelLocked(); } @@ -290,19 +304,19 @@ void CoinControlDialog::clipboardAmount() // copy label "Fee" to clipboard void CoinControlDialog::clipboardFee() { - GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" "))); + GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace("~", "")); } // copy label "After fee" to clipboard void CoinControlDialog::clipboardAfterFee() { - GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" "))); + GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace("~", "")); } // copy label "Bytes" to clipboard void CoinControlDialog::clipboardBytes() { - GUIUtil::setClipboard(ui->labelCoinControlBytes->text()); + GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace("~", "")); } // copy label "Priority" to clipboard @@ -320,7 +334,7 @@ void CoinControlDialog::clipboardLowOutput() // copy label "Change" to clipboard void CoinControlDialog::clipboardChange() { - GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" "))); + GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace("~", "")); } // treeview: sort @@ -402,26 +416,22 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) } // return human readable label for priority number -QString CoinControlDialog::getPriorityLabel(const CTxMemPool& pool, double dPriority) +QString CoinControlDialog::getPriorityLabel(double dPriority, double mempoolEstimatePriority) { - // confirmations -> textual description - typedef std::map<unsigned int, QString> PriorityDescription; - const static PriorityDescription priorityDescriptions = boost::assign::map_list_of - (1, tr("highest"))(2, tr("higher"))(3, tr("high")) - (5, tr("medium-high"))(6, tr("medium")) - (10, tr("low-medium"))(15, tr("low")) - (20, tr("lower")); - - BOOST_FOREACH(const PriorityDescription::value_type& i, priorityDescriptions) - { - double p = mempool.estimatePriority(i.first); - if (p > 0 && dPriority >= p) return i.second; - } - // Note: if mempool hasn't accumulated enough history (estimatePriority - // returns -1) we're conservative and classify as "lowest" - if (mempool.estimatePriority(nTxConfirmTarget) <= 0 && AllowFree(dPriority)) - return ">=" + tr("medium"); - return tr("lowest"); + double dPriorityMedium = mempoolEstimatePriority; + + if (dPriorityMedium <= 0) + dPriorityMedium = AllowFreeThreshold(); // not enough data, back to hard-coded + + if (dPriority / 1000000 > dPriorityMedium) return tr("highest"); + else if (dPriority / 100000 > dPriorityMedium) return tr("higher"); + else if (dPriority / 10000 > dPriorityMedium) return tr("high"); + else if (dPriority / 1000 > dPriorityMedium) return tr("medium-high"); + else if (dPriority > dPriorityMedium) return tr("medium"); + else if (dPriority * 10 > dPriorityMedium) return tr("low-medium"); + else if (dPriority * 100 > dPriorityMedium) return tr("low"); + else if (dPriority * 1000 > dPriorityMedium) return tr("lower"); + else return tr("lowest"); } // shows count of locked unspent outputs @@ -443,10 +453,10 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) return; // nPayAmount - qint64 nPayAmount = 0; + CAmount nPayAmount = 0; bool fDust = false; CMutableTransaction txDummy; - foreach(const qint64 &amount, CoinControlDialog::payAmounts) + foreach(const CAmount &amount, CoinControlDialog::payAmounts) { nPayAmount += amount; @@ -460,16 +470,17 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) } QString sPriorityLabel = tr("none"); - int64_t nAmount = 0; - int64_t nPayFee = 0; - int64_t nAfterFee = 0; - int64_t nChange = 0; + CAmount nAmount = 0; + CAmount nPayFee = 0; + CAmount nAfterFee = 0; + CAmount nChange = 0; unsigned int nBytes = 0; unsigned int nBytesInputs = 0; double dPriority = 0; double dPriorityInputs = 0; unsigned int nQuantity = 0; int nQuantityUncompressed = 0; + bool fAllowFree = false; vector<COutPoint> vCoinControl; vector<COutput> vOutputs; @@ -522,24 +533,22 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) nBytes = nBytesInputs + ((CoinControlDialog::payAmounts.size() > 0 ? CoinControlDialog::payAmounts.size() + 1 : 2) * 34) + 10; // always assume +1 output for change here // Priority + double mempoolEstimatePriority = mempool.estimatePriority(nTxConfirmTarget); dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29)); // 29 = 180 - 151 (uncompressed public keys are over the limit. max 151 bytes of the input are ignored for priority) - sPriorityLabel = CoinControlDialog::getPriorityLabel(mempool, dPriority); + sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority); - // Voluntary Fee - nPayFee = payTxFee.GetFee(max((unsigned int)1000, nBytes)); + // Fee + nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool); - // Min Fee - if (nPayFee == 0) - { - nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool); - - double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget); - if (dPriorityNeeded <= 0 && !AllowFree(dPriority)) // not enough mempool history: never send free - dPriorityNeeded = std::numeric_limits<double>::max(); + // Allow free? + double dPriorityNeeded = mempoolEstimatePriority; + if (dPriorityNeeded <= 0) + dPriorityNeeded = AllowFreeThreshold(); // not enough data, back to hard-coded + fAllowFree = (dPriority >= dPriorityNeeded); - if (nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE && dPriority >= dPriorityNeeded) + if (fSendFreeTransactions) + if (fAllowFree && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE) nPayFee = 0; - } if (nPayAmount > 0) { @@ -595,7 +604,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) l6->setText(sPriorityLabel); // Priority l7->setText(fDust ? tr("yes") : tr("no")); // Dust l8->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nChange)); // Change - if (nPayFee > 0) + if (nPayFee > 0 && !(payTxFee.GetFeePerK() > 0 && fPayAtLeastCustomFee && nBytes < 1000)) { l3->setText("~" + l3->text()); l4->setText("~" + l4->text()); @@ -605,7 +614,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // turn labels "red" l5->setStyleSheet((nBytes >= MAX_FREE_TRANSACTION_CREATE_SIZE) ? "color:red;" : "");// Bytes >= 1000 - l6->setStyleSheet((dPriority > 0 && !AllowFree(dPriority)) ? "color:red;" : ""); // Priority < "medium" + l6->setStyleSheet((dPriority > 0 && !fAllowFree) ? "color:red;" : ""); // Priority < "medium" l7->setStyleSheet((fDust) ? "color:red;" : ""); // Dust = "yes" // tool tips @@ -620,7 +629,11 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) 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 = (double)std::max(CWallet::minTxFee.GetFeePerK(), std::max(payTxFee.GetFeePerK(), mempool.estimateFee(nTxConfirmTarget).GetFeePerK())) / 1000; + double dFeeVary; + if (payTxFee.GetFeePerK() > 0) + dFeeVary = (double)std::max(CWallet::minTxFee.GetFeePerK(), payTxFee.GetFeePerK()) / 1000; + else + dFeeVary = (double)std::max(CWallet::minTxFee.GetFeePerK(), mempool.estimateFee(nTxConfirmTarget).GetFeePerK()) / 1000; QString toolTip4 = tr("Can vary +/- %1 satoshi(s) per input.").arg(dFeeVary); l3->setToolTip(toolTip4); @@ -656,6 +669,7 @@ void CoinControlDialog::updateView() QFlags<Qt::ItemFlag> flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate; int nDisplayUnit = model->getOptionsModel()->getDisplayUnit(); + double mempoolEstimatePriority = mempool.estimatePriority(nTxConfirmTarget); map<QString, vector<COutput> > mapCoins; model->listCoins(mapCoins); @@ -684,7 +698,7 @@ void CoinControlDialog::updateView() itemWalletAddress->setText(COLUMN_ADDRESS, sWalletAddress); } - int64_t nSum = 0; + CAmount nSum = 0; double dPrioritySum = 0; int nChildren = 0; int nInputSum = 0; @@ -745,7 +759,7 @@ void CoinControlDialog::updateView() // priority double dPriority = ((double)out.tx->vout[out.i].nValue / (nInputSize + 78)) * (out.nDepth+1); // 78 = 2 * 34 + 10 - itemOutput->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(mempool, dPriority)); + itemOutput->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority)); itemOutput->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPriority), 20, " ")); dPrioritySum += (double)out.tx->vout[out.i].nValue * (out.nDepth+1); nInputSum += nInputSize; @@ -763,7 +777,7 @@ void CoinControlDialog::updateView() COutPoint outpt(txhash, out.i); coinControl->UnSelect(outpt); // just to be sure itemOutput->setDisabled(true); - itemOutput->setIcon(COLUMN_CHECKBOX, QIcon(":/icons/lock_closed")); + itemOutput->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed")); } // set checkbox @@ -778,7 +792,7 @@ void CoinControlDialog::updateView() itemWalletAddress->setText(COLUMN_CHECKBOX, "(" + QString::number(nChildren) + ")"); itemWalletAddress->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, nSum)); itemWalletAddress->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(nSum), 15, " ")); - itemWalletAddress->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(mempool, dPrioritySum)); + itemWalletAddress->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPrioritySum, mempoolEstimatePriority)); itemWalletAddress->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPrioritySum), 20, " ")); } } diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index a6f239a898..0974443066 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -1,9 +1,11 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 COINCONTROLDIALOG_H -#define COINCONTROLDIALOG_H +#ifndef BITCOIN_QT_COINCONTROLDIALOG_H +#define BITCOIN_QT_COINCONTROLDIALOG_H + +#include "amount.h" #include <QAbstractButton> #include <QAction> @@ -35,9 +37,9 @@ public: // static because also called from sendcoinsdialog static void updateLabels(WalletModel*, QDialog*); - static QString getPriorityLabel(const CTxMemPool& pool, double); + static QString getPriorityLabel(double dPriority, double mempoolEstimatePriority); - static QList<qint64> payAmounts; + static QList<CAmount> payAmounts; static CCoinControl *coinControl; private: @@ -122,4 +124,4 @@ private slots: void updateLabelLocked(); }; -#endif // COINCONTROLDIALOG_H +#endif // BITCOIN_QT_COINCONTROLDIALOG_H diff --git a/src/qt/coincontroltreewidget.cpp b/src/qt/coincontroltreewidget.cpp index 907b5caa05..6cbcf7128d 100644 --- a/src/qt/coincontroltreewidget.cpp +++ b/src/qt/coincontroltreewidget.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "coincontroltreewidget.h" diff --git a/src/qt/coincontroltreewidget.h b/src/qt/coincontroltreewidget.h index a2cd34eb88..98a7d32f05 100644 --- a/src/qt/coincontroltreewidget.h +++ b/src/qt/coincontroltreewidget.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 COINCONTROLTREEWIDGET_H -#define COINCONTROLTREEWIDGET_H +#ifndef BITCOIN_QT_COINCONTROLTREEWIDGET_H +#define BITCOIN_QT_COINCONTROLTREEWIDGET_H #include <QKeyEvent> #include <QTreeWidget> @@ -19,4 +19,4 @@ protected: virtual void keyPressEvent(QKeyEvent *event); }; -#endif // COINCONTROLTREEWIDGET_H
\ No newline at end of file +#endif // BITCOIN_QT_COINCONTROLTREEWIDGET_H diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp index ac8c6b41d4..55c5957088 100644 --- a/src/qt/csvmodelwriter.cpp +++ b/src/qt/csvmodelwriter.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "csvmodelwriter.h" diff --git a/src/qt/csvmodelwriter.h b/src/qt/csvmodelwriter.h index 29de251efe..a2bf379f4e 100644 --- a/src/qt/csvmodelwriter.h +++ b/src/qt/csvmodelwriter.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 CSVMODELWRITER_H -#define CSVMODELWRITER_H +#ifndef BITCOIN_QT_CSVMODELWRITER_H +#define BITCOIN_QT_CSVMODELWRITER_H #include <QList> #include <QObject> @@ -43,4 +43,4 @@ private: QList<Column> columns; }; -#endif // CSVMODELWRITER_H +#endif // BITCOIN_QT_CSVMODELWRITER_H diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp index 46982cc339..1c22594cd7 100644 --- a/src/qt/editaddressdialog.cpp +++ b/src/qt/editaddressdialog.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "editaddressdialog.h" diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h index 6910c667cd..13c6da8eda 100644 --- a/src/qt/editaddressdialog.h +++ b/src/qt/editaddressdialog.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 EDITADDRESSDIALOG_H -#define EDITADDRESSDIALOG_H +#ifndef BITCOIN_QT_EDITADDRESSDIALOG_H +#define BITCOIN_QT_EDITADDRESSDIALOG_H #include <QDialog> @@ -54,4 +54,4 @@ private: QString address; }; -#endif // EDITADDRESSDIALOG_H +#endif // BITCOIN_QT_EDITADDRESSDIALOG_H diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui index 52fdc6ef06..264edeb720 100644 --- a/src/qt/forms/addressbookpage.ui +++ b/src/qt/forms/addressbookpage.ui @@ -27,7 +27,7 @@ <enum>Qt::CustomContextMenu</enum> </property> <property name="toolTip"> - <string>Double-click to edit address or label</string> + <string>Right-click to edit address or label</string> </property> <property name="tabKeyNavigation"> <bool>false</bool> diff --git a/src/qt/forms/askpassphrasedialog.ui b/src/qt/forms/askpassphrasedialog.ui index bc4921455f..a2105ecd0a 100644 --- a/src/qt/forms/askpassphrasedialog.ui +++ b/src/qt/forms/askpassphrasedialog.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>598</width> - <height>198</height> + <height>222</height> </rect> </property> <property name="sizePolicy"> @@ -26,8 +26,14 @@ <string>Passphrase Dialog</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> + <property name="sizeConstraint"> + <enum>QLayout::SetMinimumSize</enum> + </property> <item> <widget class="QLabel" name="warningLabel"> + <property name="text"> + <string notr="true">Placeholder text</string> + </property> <property name="textFormat"> <enum>Qt::RichText</enum> </property> @@ -38,6 +44,9 @@ </item> <item> <layout class="QFormLayout" name="formLayout"> + <property name="sizeConstraint"> + <enum>QLayout::SetMinimumSize</enum> + </property> <property name="fieldGrowthPolicy"> <enum>QFormLayout::AllNonFixedFieldsGrow</enum> </property> diff --git a/src/qt/forms/coincontroldialog.ui b/src/qt/forms/coincontroldialog.ui index cbe58fec65..c1fef6b9b1 100644 --- a/src/qt/forms/coincontroldialog.ui +++ b/src/qt/forms/coincontroldialog.ui @@ -11,7 +11,7 @@ </rect> </property> <property name="windowTitle"> - <string>Coin Control Address Selection</string> + <string>Coin Selection</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> @@ -379,9 +379,6 @@ <property name="text"> <string>Tree mode</string> </property> - <property name="checked"> - <bool>true</bool> - </property> </widget> </item> <item> @@ -395,6 +392,9 @@ <property name="text"> <string>List mode</string> </property> + <property name="checked"> + <bool>true</bool> + </property> </widget> </item> <item> @@ -451,12 +451,12 @@ </column> <column> <property name="text"> - <string notr="true">Label</string> + <string>Received with label</string> </property> </column> <column> <property name="text"> - <string>Address</string> + <string>Received with address</string> </property> </column> <column> diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 9d094c1a73..55c4f5ac58 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -30,10 +30,10 @@ <item> <widget class="QCheckBox" name="bitcoinAtStartup"> <property name="toolTip"> - <string>Automatically start Bitcoin after logging in to the system.</string> + <string>Automatically start Bitcoin Core after logging in to the system.</string> </property> <property name="text"> - <string>&Start Bitcoin on system login</string> + <string>&Start Bitcoin Core on system login</string> </property> </widget> </item> @@ -138,65 +138,6 @@ </attribute> <layout class="QVBoxLayout" name="verticalLayout_Wallet"> <item> - <widget class="QLabel" name="transactionFeeInfoLabel"> - <property name="text"> - <string>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</string> - </property> - <property name="textFormat"> - <enum>Qt::PlainText</enum> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_1_Wallet"> - <item> - <widget class="QLabel" name="transactionFeeLabel"> - <property name="text"> - <string>Pay transaction &fee</string> - </property> - <property name="textFormat"> - <enum>Qt::PlainText</enum> - </property> - <property name="buddy"> - <cstring>transactionFee</cstring> - </property> - </widget> - </item> - <item> - <widget class="BitcoinAmountField" name="transactionFee"/> - </item> - <item> - <spacer name="horizontalSpacer_1_Wallet"> - <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_Wallet"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item> <widget class="QGroupBox" name="groupBox"> <property name="title"> <string>Expert</string> @@ -225,6 +166,19 @@ </layout> </widget> </item> + <item> + <spacer name="verticalSpacer_Wallet"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> </layout> </widget> <widget class="QWidget" name="tabNetwork"> @@ -255,10 +209,10 @@ <item> <widget class="QCheckBox" name="connectSocks"> <property name="toolTip"> - <string>Connect to the Bitcoin network through a SOCKS proxy.</string> + <string>Connect to the Bitcoin network through a SOCKS5 proxy.</string> </property> <property name="text"> - <string>&Connect through SOCKS proxy (default proxy):</string> + <string>&Connect through SOCKS5 proxy (default proxy):</string> </property> </widget> </item> @@ -376,7 +330,7 @@ <item> <widget class="QCheckBox" name="minimizeOnClose"> <property name="toolTip"> - <string>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.</string> + <string>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.</string> </property> <property name="text"> <string>M&inimize on close</string> @@ -421,7 +375,7 @@ <item> <widget class="QValueComboBox" name="lang"> <property name="toolTip"> - <string>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</string> + <string>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</string> </property> </widget> </item> @@ -633,12 +587,6 @@ </widget> <customwidgets> <customwidget> - <class>BitcoinAmountField</class> - <extends>QLineEdit</extends> - <header>bitcoinamountfield.h</header> - <container>1</container> - </customwidget> - <customwidget> <class>QValidatedLineEdit</class> <extends>QLineEdit</extends> <header>qvalidatedlineedit.h</header> diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui index 7f28209c9a..eb7c92cfec 100644 --- a/src/qt/forms/rpcconsole.ui +++ b/src/qt/forms/rpcconsole.ui @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>RPCConsole</class> - <widget class="QDialog" name="RPCConsole"> + <widget class="QWidget" name="RPCConsole"> <property name="geometry"> <rect> <x>0</x> @@ -331,7 +331,7 @@ <item row="15" column="0"> <widget class="QPushButton" name="openDebugLogfileButton"> <property name="toolTip"> - <string>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</string> + <string>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</string> </property> <property name="text"> <string>&Open</string> @@ -689,7 +689,7 @@ <item row="0" column="0" rowspan="2"> <widget class="QTableView" name="peerWidget"> <property name="horizontalScrollBarPolicy"> - <enum>Qt::ScrollBarAlwaysOff</enum> + <enum>Qt::ScrollBarAsNeeded</enum> </property> <property name="sortingEnabled"> <bool>true</bool> @@ -836,29 +836,6 @@ </property> </widget> </item> - <item row="4" column="0"> - <widget class="QLabel" name="label_25"> - <property name="text"> - <string>Sync Node</string> - </property> - </widget> - </item> - <item row="4" column="2"> - <widget class="QLabel" name="peerSyncNode"> - <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="5" column="0"> <widget class="QLabel" name="label_29"> <property name="text"> diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index dce7f4ce4c..eebb459327 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -7,13 +7,13 @@ <x>0</x> <y>0</y> <width>850</width> - <height>400</height> + <height>526</height> </rect> </property> <property name="windowTitle"> <string>Send Coins</string> </property> - <layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0"> + <layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0,0"> <property name="bottomMargin"> <number>8</number> </property> @@ -617,7 +617,7 @@ <x>0</x> <y>0</y> <width>830</width> - <height>178</height> + <height>68</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1"> @@ -658,6 +658,590 @@ </widget> </item> <item> + <widget class="QFrame" name="frameFee"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>16777215</height> + </size> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <layout class="QVBoxLayout" name="verticalLayoutFee1"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QVBoxLayout" name="verticalLayoutFee2" stretch="0,0,0"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>10</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayoutFee1"> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QVBoxLayout" name="verticalLayoutFee7"> + <property name="spacing"> + <number>0</number> + </property> + <item> + <spacer name="verticalSpacerSmartFee"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>1</width> + <height>4</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayoutSmartFee"> + <property name="spacing"> + <number>10</number> + </property> + <item> + <widget class="QLabel" name="labelFeeHeadline"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="styleSheet"> + <string notr="true">font-weight:bold;</string> + </property> + <property name="text"> + <string>Transaction Fee:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="labelFeeMinimized"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="buttonChooseFee"> + <property name="text"> + <string>Choose...</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="buttonMinimizeFee"> + <property name="toolTip"> + <string>collapse fee-settings</string> + </property> + <property name="text"> + <string>Minimize</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_5"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>1</width> + <height>1</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <spacer name="horizontalSpacer_4"> + <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="QFrame" name="frameFeeSelection"> + <layout class="QVBoxLayout" name="verticalLayoutFee12"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QGridLayout" name="gridLayoutFee"> + <property name="topMargin"> + <number>10</number> + </property> + <property name="bottomMargin"> + <number>4</number> + </property> + <property name="horizontalSpacing"> + <number>10</number> + </property> + <property name="verticalSpacing"> + <number>4</number> + </property> + <item row="1" column="1"> + <layout class="QVBoxLayout" name="verticalLayoutFee8"> + <property name="spacing"> + <number>6</number> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayoutFee13"> + <item> + <widget class="QRadioButton" name="radioCustomPerKilobyte"> + <property name="toolTip"> + <string>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.</string> + </property> + <property name="text"> + <string>per kilobyte</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <attribute name="buttonGroup"> + <string notr="true">groupCustomFee</string> + </attribute> + </widget> + </item> + <item> + <widget class="QRadioButton" name="radioCustomAtLeast"> + <property name="toolTip"> + <string>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.</string> + </property> + <property name="text"> + <string>total at least</string> + </property> + <attribute name="buttonGroup"> + <string notr="true">groupCustomFee</string> + </attribute> + </widget> + </item> + <item> + <widget class="BitcoinAmountField" name="customFee"/> + </item> + <item> + <spacer name="horizontalSpacer_6"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>1</width> + <height>1</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayoutFee8"> + <item> + <widget class="QCheckBox" name="checkBoxMinimumFee"> + <property name="toolTip"> + <string>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.</string> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="labelMinFeeWarning"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="toolTip"> + <string>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.</string> + </property> + <property name="text"> + <string>(read the tooltip)</string> + </property> + <property name="margin"> + <number>5</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>1</width> + <height>1</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </item> + <item row="0" column="0"> + <layout class="QVBoxLayout" name="verticalLayoutFee4" stretch="0,1"> + <item> + <widget class="QRadioButton" name="radioSmartFee"> + <property name="text"> + <string>Recommended:</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <attribute name="buttonGroup"> + <string notr="true">groupFee</string> + </attribute> + </widget> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>1</width> + <height>1</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="1" column="0"> + <layout class="QVBoxLayout" name="verticalLayoutFee9" stretch="0,1"> + <item> + <widget class="QRadioButton" name="radioCustomFee"> + <property name="text"> + <string>Custom:</string> + </property> + <attribute name="buttonGroup"> + <string notr="true">groupFee</string> + </attribute> + </widget> + </item> + <item> + <spacer name="verticalSpacer_6"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>1</width> + <height>1</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="0" column="1"> + <layout class="QVBoxLayout" name="verticalLayoutFee3" stretch="0,0,1"> + <property name="spacing"> + <number>6</number> + </property> + <property name="topMargin"> + <number>2</number> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayoutFee12"> + <item> + <widget class="QLabel" name="labelSmartFee"> + <property name="text"> + <string/> + </property> + <property name="margin"> + <number>2</number> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="labelFeeEstimation"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="labelSmartFee2"> + <property name="text"> + <string>(Smart fee not initialized yet. This usually takes a few blocks...)</string> + </property> + <property name="margin"> + <number>2</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>1</width> + <height>1</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayoutFee9"> + <item> + <layout class="QVBoxLayout" name="verticalLayoutFee6"> + <item> + <widget class="QLabel" name="labelSmartFee3"> + <property name="text"> + <string>Confirmation time:</string> + </property> + <property name="margin"> + <number>2</number> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>1</width> + <height>1</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayoutFee5"> + <property name="rightMargin"> + <number>30</number> + </property> + <item> + <widget class="QSlider" name="sliderSmartFee"> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>24</number> + </property> + <property name="pageStep"> + <number>1</number> + </property> + <property name="value"> + <number>0</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="invertedAppearance"> + <bool>false</bool> + </property> + <property name="invertedControls"> + <bool>false</bool> + </property> + <property name="tickPosition"> + <enum>QSlider::NoTicks</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayoutFee10"> + <item> + <widget class="QLabel" name="labelSmartFeeNormal"> + <property name="text"> + <string>normal</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="labelSmartFeeFast"> + <property name="text"> + <string>fast</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>1</width> + <height>1</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayoutFee5" stretch="0,0,0"> + <property name="spacing"> + <number>8</number> + </property> + <property name="bottomMargin"> + <number>4</number> + </property> + <item> + <widget class="QCheckBox" name="checkBoxFreeTx"> + <property name="text"> + <string>Send as zero-fee transaction if possible</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="labelFreeTx"> + <property name="text"> + <string>(confirmation may take longer)</string> + </property> + <property name="margin"> + <number>5</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacerFee5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>1</width> + <height>1</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacerFee2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>1</width> + <height>1</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacerFee"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>800</width> + <height>1</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <widget class="QPushButton" name="sendButton"> @@ -787,9 +1371,19 @@ <extends>QLineEdit</extends> <header>qvalidatedlineedit.h</header> </customwidget> + <customwidget> + <class>BitcoinAmountField</class> + <extends>QLineEdit</extends> + <header>bitcoinamountfield.h</header> + <container>1</container> + </customwidget> </customwidgets> <resources> <include location="../bitcoin.qrc"/> </resources> <connections/> + <buttongroups> + <buttongroup name="groupFee"/> + <buttongroup name="groupCustomFee"/> + </buttongroups> </ui> diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui index 9d829970f0..9f8c0a4844 100644 --- a/src/qt/forms/sendcoinsentry.ui +++ b/src/qt/forms/sendcoinsentry.ui @@ -67,6 +67,12 @@ <iconset resource="../bitcoin.qrc"> <normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset> </property> + <property name="iconSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> <property name="shortcut"> <string>Alt+A</string> </property> @@ -84,6 +90,12 @@ <iconset resource="../bitcoin.qrc"> <normaloff>:/icons/editpaste</normaloff>:/icons/editpaste</iconset> </property> + <property name="iconSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> <property name="shortcut"> <string>Alt+P</string> </property> @@ -101,6 +113,12 @@ <iconset resource="../bitcoin.qrc"> <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset> </property> + <property name="iconSize"> + <size> + <width>22</width> + <height>22</height> + </size> + </property> </widget> </item> </layout> diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 4c8a67b663..a0a2993ea3 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. -#ifndef GUICONSTANTS_H -#define GUICONSTANTS_H +#ifndef BITCOIN_QT_GUICONSTANTS_H +#define BITCOIN_QT_GUICONSTANTS_H /* Milliseconds between model updates */ static const int MODEL_UPDATE_DELAY = 250; @@ -38,9 +38,6 @@ static const int TOOLTIP_WRAP_THRESHOLD = 80; /* Maximum allowed URI length */ static const int MAX_URI_LENGTH = 255; -/* Maximum somewhat-sane size of a payment request file */ -static const int MAX_PAYMENT_REQUEST_SIZE = 50000; // bytes - /* QRCodeDialog -- size of exported QR Code image */ #define EXPORT_IMAGE_SIZE 256 @@ -52,4 +49,4 @@ static const int MAX_PAYMENT_REQUEST_SIZE = 50000; // bytes #define QAPP_APP_NAME_DEFAULT "Bitcoin-Qt" #define QAPP_APP_NAME_TESTNET "Bitcoin-Qt-testnet" -#endif // GUICONSTANTS_H +#endif // BITCOIN_QT_GUICONSTANTS_H diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index fc22871a6b..a3ede9fd62 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "guiutil.h" @@ -9,7 +9,7 @@ #include "qvalidatedlineedit.h" #include "walletmodel.h" -#include "core.h" +#include "primitives/transaction.h" #include "init.h" #include "main.h" #include "protocol.h" @@ -221,7 +221,7 @@ QString formatBitcoinURI(const SendCoinsRecipient &info) return ret; } -bool isDust(const QString& address, qint64 amount) +bool isDust(const QString& address, const CAmount& amount) { CTxDestination dest = CBitcoinAddress(address.toStdString()).Get(); CScript script = GetScriptForDestination(dest); diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 67e11e59a0..4f8c683147 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -1,13 +1,17 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 GUIUTIL_H -#define GUIUTIL_H +#ifndef BITCOIN_QT_GUIUTIL_H +#define BITCOIN_QT_GUIUTIL_H +#include "amount.h" + +#include <QEvent> #include <QHeaderView> #include <QMessageBox> #include <QObject> +#include <QProgressBar> #include <QString> #include <QTableView> @@ -46,7 +50,7 @@ namespace GUIUtil QString formatBitcoinURI(const SendCoinsRecipient &info); // Returns true if given address+amount meets "dust" definition - bool isDust(const QString& address, qint64 amount); + bool isDust(const QString& address, const CAmount& amount); // HTML escaping for rich text controls QString HtmlEscape(const QString& str, bool fMultiLine=false); @@ -184,6 +188,21 @@ namespace GUIUtil /* Format a CNodeCombinedStats.dPingTime into a user-readable string or display N/A, if 0*/ QString formatPingTime(double dPingTime); + +#if defined(Q_OS_MAC) && QT_VERSION >= 0x050000 + // workaround for Qt OSX Bug: + // https://bugreports.qt-project.org/browse/QTBUG-15631 + // QProgressBar uses around 10% CPU even when app is in background + class ProgressBar : public QProgressBar + { + bool event(QEvent *e) { + return (e->type() != QEvent::StyleAnimationUpdate) ? QProgressBar::event(e) : false; + } + }; +#else + typedef QProgressBar ProgressBar; +#endif + } // namespace GUIUtil -#endif // GUIUTIL_H +#endif // BITCOIN_QT_GUIUTIL_H diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index d469c9a0bd..9f72602b4d 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -1,11 +1,12 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "intro.h" #include "ui_intro.h" #include "guiutil.h" +#include "scicon.h" #include "util.h" @@ -95,7 +96,7 @@ void FreespaceChecker::check() replyMessage = tr("Path already exists, and is not a directory."); } } - } catch(fs::filesystem_error &e) + } catch (const fs::filesystem_error&) { /* Parent directory does not exist or is not accessible */ replyStatus = ST_ERROR; @@ -167,7 +168,7 @@ void Intro::pickDataDirectory() /* If current default data directory does not exist, let the user choose one */ Intro intro; intro.setDataDirectory(dataDir); - intro.setWindowIcon(QIcon(":icons/bitcoin")); + intro.setWindowIcon(SingleColorIcon(":icons/bitcoin")); while(true) { @@ -180,7 +181,7 @@ void Intro::pickDataDirectory() try { TryCreateDirectory(GUIUtil::qstringToBoostPath(dataDir)); break; - } catch(fs::filesystem_error &e) { + } catch (const fs::filesystem_error&) { QMessageBox::critical(0, tr("Bitcoin Core"), tr("Error: Specified data directory \"%1\" cannot be created.").arg(dataDir)); /* fall through, back to choosing screen */ @@ -215,10 +216,10 @@ void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable { ui->freeSpace->setText(""); } else { - QString freeString = QString::number(bytesAvailable/GB_BYTES) + tr("GB of free space available"); + QString freeString = tr("%n GB of free space available", "", bytesAvailable/GB_BYTES); if(bytesAvailable < BLOCK_CHAIN_SIZE) { - freeString += " " + tr("(of %1GB needed)").arg(BLOCK_CHAIN_SIZE/GB_BYTES); + freeString += " " + tr("(of %n GB needed)", "", BLOCK_CHAIN_SIZE/GB_BYTES); ui->freeSpace->setStyleSheet("QLabel { color: #800000 }"); } else { ui->freeSpace->setStyleSheet(""); diff --git a/src/qt/intro.h b/src/qt/intro.h index e3e396d369..c9735615b6 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 INTRO_H -#define INTRO_H +#ifndef BITCOIN_QT_INTRO_H +#define BITCOIN_QT_INTRO_H #include <QDialog> #include <QMutex> @@ -70,4 +70,4 @@ private: friend class FreespaceChecker; }; -#endif // INTRO_H +#endif // BITCOIN_QT_INTRO_H 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 474b6b3298..c369c3c68f 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> @@ -201,10 +201,6 @@ <translation>Bedrag</translation> </message> <message> - <source>Address</source> - <translation>Adres</translation> - </message> - <message> <source>Date</source> <translation>Datum</translation> </message> @@ -277,14 +273,6 @@ <source>Form</source> <translation>Vorm</translation> </message> - <message> - <source>Wallet</source> - <translation>Beursie</translation> - </message> - <message> - <source><b>Recent transactions</b></source> - <translation><b>Onlangse transaksies</b></translation> - </message> </context> <context> <name>PaymentServer</name> @@ -651,14 +639,6 @@ <translation>Opsies:</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Luister vir konneksies op <port> (standaard: 8333 of testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Onderhou op die meeste <n> konneksies na eweknieë (standaard: 125)</translation> - </message> - <message> <source>Use the test network</source> <translation>Gebruik die toets netwerk</translation> </message> @@ -671,10 +651,6 @@ <translation>Informasie</translation> </message> <message> - <source>System error: </source> - <translation>Sisteem fout:</translation> - </message> - <message> <source>This help message</source> <translation>Hierdie help boodskap</translation> </message> diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index ea1bc0ea4b..101f51f8dc 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> @@ -34,6 +34,10 @@ <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> @@ -62,6 +66,14 @@ <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>هذه هي عناوين Bitcion التابعة لك من أجل إرسال الدفعات. تحقق دائما من المبلغ و عنوان المرسل المستقبل قبل إرسال العملات</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>هذه هي عناوين Bitcion التابعة لك من أجل إستقبال الدفعات. ينصح استخدام عنوان جديد من أجل كل صفقة</translation> + </message> + <message> <source>Copy &Label</source> <translation>نسخ &الوصف</translation> </message> @@ -74,6 +86,10 @@ <translation>تصدير قائمة العناوين</translation> </message> <message> + <source>Comma separated file (*.csv)</source> + <translation>ملف مفصول بفواصل (*.csv)</translation> + </message> + <message> <source>Exporting Failed</source> <translation>فشل التصدير</translation> </message> @@ -96,6 +112,10 @@ <context> <name>AskPassphraseDialog</name> <message> + <source>Passphrase Dialog</source> + <translation>حوار جملة السر</translation> + </message> + <message> <source>Enter passphrase</source> <translation>ادخل كلمة المرور</translation> </message> @@ -140,6 +160,18 @@ <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>تحذير: إذا قمت بتشفير محفظتك وفقدت كلمة المرور الخاص بك, ستفقد كل عملات BITCOINS الخاصة بك.</translation> + </message> + <message> + <source>Are you sure you wish to encrypt your wallet?</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> + <message> <source>Warning: The Caps Lock key is on!</source> <translation>تحذير: مفتاح الحروف الكبيرة مفعل</translation> </message> @@ -148,6 +180,10 @@ <translation>محفظة مشفرة</translation> </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>أدخل عبارة مرور جديدة إلى المحفظة. الرجاء استخدام عبارة مرور تتكون من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> @@ -175,7 +211,11 @@ <source>Wallet decryption failed</source> <translation>فشل فك التشفير المحفظة</translation> </message> - </context> + <message> + <source>Wallet passphrase was successfully changed.</source> + <translation>لقد تم تغير عبارة مرور المحفظة بنجاح</translation> + </message> +</context> <context> <name>BitcoinGUI</name> <message> @@ -239,14 +279,30 @@ <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> <message> + <source>Bitcoin Core client</source> + <translation>عميل bitcion core</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> @@ -275,6 +331,10 @@ <translation>&استقبل</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation> اظهار معلومات حول bitcion core</translation> + </message> + <message> <source>&Show / Hide</source> <translation>&عرض / اخفاء</translation> </message> @@ -283,6 +343,10 @@ <translation>عرض او اخفاء النافذة الرئيسية</translation> </message> <message> + <source>Encrypt the private keys that belong to your wallet</source> + <translation>تشفير المفتاح الخاص لمحفظتك</translation> + </message> + <message> <source>&File</source> <translation>&ملف</translation> </message> @@ -299,13 +363,13 @@ <translation>شريط أدوات علامات التبويب</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>جوهر البيت كوين</translation> </message> + <message> + <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> @@ -393,10 +457,6 @@ <translation>المبلغ</translation> </message> <message> - <source>Address</source> - <translation>عنوان</translation> - </message> - <message> <source>Date</source> <translation>التاريخ</translation> </message> @@ -461,6 +521,10 @@ <translation>عالي</translation> </message> <message> + <source>medium-high</source> + <translation>متوسط-مرتفع</translation> + </message> + <message> <source>low</source> <translation>منخفض</translation> </message> @@ -596,10 +660,6 @@ <source>Error</source> <translation>خطأ</translation> </message> - <message> - <source>GB of free space available</source> - <translation>قيقا بايت مساحة متاحة</translation> - </message> </context> <context> <name>OpenURIDialog</name> @@ -623,10 +683,6 @@ <translation>&الرئيسي</translation> </message> <message> - <source>Pay transaction &fee</source> - <translation>ادفع &رسوم المعاملة</translation> - </message> - <message> <source>MB</source> <translation>م ب</translation> </message> @@ -710,10 +766,6 @@ <translation>نمودج</translation> </message> <message> - <source>Wallet</source> - <translation>محفظة</translation> - </message> - <message> <source>Available:</source> <translation>متوفر</translation> </message> @@ -734,10 +786,6 @@ <translation>رصيدك الكلي الحالي</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation>اخر المعملات </translation> - </message> - <message> <source>out of sync</source> <translation>خارج المزامنه</translation> </message> @@ -877,14 +925,6 @@ <translation>استخدم اسهم الاعلى و الاسفل للتنقل بين السجلات و <b>Ctrl-L</b> لمسح الشاشة</translation> </message> <message> - <source>Yes</source> - <translation>نعم</translation> - </message> - <message> - <source>No</source> - <translation>لا</translation> - </message> - <message> <source>Unknown</source> <translation>غير معرف</translation> </message> @@ -1540,6 +1580,10 @@ <translation>نجح التصدير</translation> </message> <message> + <source>Comma separated file (*.csv)</source> + <translation>ملف مفصول بفواصل (*.csv)</translation> + </message> + <message> <source>Confirmed</source> <translation>تأكيد</translation> </message> @@ -1592,6 +1636,10 @@ <translation>&تصدير</translation> </message> <message> + <source>Export the data in the current tab to a file</source> + <translation>تحميل البيانات في علامة التبويب الحالية إلى ملف.</translation> + </message> + <message> <source>Backup Wallet</source> <translation>نسخ احتياط للمحفظة</translation> </message> @@ -1631,10 +1679,6 @@ <translation>تحذير: المحفظة مغلقة , لا تستطيع تنفيذ المعاملة</translation> </message> <message> - <source>Error: system error: </source> - <translation>خطأ: خطأ في النظام:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>فشل في الاستماع على أي منفذ. استخدام الاستماع = 0 إذا كنت تريد هذا.</translation> </message> @@ -1659,10 +1703,6 @@ <translation>فشل توقيع المعاملة</translation> </message> <message> - <source>System error: </source> - <translation>خطأ في النظام :</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>قيمة العملية صغيره جدا</translation> </message> @@ -1687,10 +1727,6 @@ <translation>تحديث المحفظة للنسخة الاخيرة</translation> </message> <message> - <source>Server private key (default: server.pem)</source> - <translation>المفتاح الخاص بالسيرفر (default: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>رسالة المساعدة هذه</translation> </message> diff --git a/src/qt/locale/bitcoin_be_BY.ts b/src/qt/locale/bitcoin_be_BY.ts index 8fac417b73..e63628396c 100644 --- a/src/qt/locale/bitcoin_be_BY.ts +++ b/src/qt/locale/bitcoin_be_BY.ts @@ -1,4 +1,4 @@ -<TS language="be_BY" version="2.1"> +<TS language="be_BY" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -10,10 +10,34 @@ <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> @@ -22,9 +46,37 @@ <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>&Edit</source> + <translation>Рэдагаваць</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Коскамі падзелены файл (*.csv)</translation> </message> + <message> + <source>Exporting Failed</source> + <translation>Экспартаванне няўдалае</translation> + </message> </context> <context> <name>AddressTableModel</name> @@ -88,6 +140,18 @@ <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> + </message> + <message> + <source>Are you sure you wish to encrypt your wallet?</source> + <translation>Ці ўпэўненыя вы, што жадаеце зашыфраваць свой гаманец?</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> @@ -119,10 +183,18 @@ <source>Wallet decryption failed</source> <translation>Расшыфраванне гаманца няўдалае</translation> </message> - </context> + <message> + <source>Wallet passphrase was successfully changed.</source> + <translation>Парольная фраза гаманца паспяхова зменена.</translation> + </message> +</context> <context> <name>BitcoinGUI</name> <message> + <source>Sign &message...</source> + <translation>Падпісаць паведамленне...</translation> + </message> + <message> <source>Synchronizing with network...</source> <translation>Сінхранізацыя з сецівам...</translation> </message> @@ -131,6 +203,10 @@ <translation>Агляд</translation> </message> <message> + <source>Node</source> + <translation>Вузел</translation> + </message> + <message> <source>Show general overview of wallet</source> <translation>Паказвае агульныя звесткі аб гаманцы</translation> </message> @@ -163,6 +239,14 @@ <translation>Опцыі...</translation> </message> <message> + <source>&Encrypt Wallet...</source> + <translation>Зашыфраваць Гаманец...</translation> + </message> + <message> + <source>Open &URI...</source> + <translation>Адчыниць &URI...</translation> + </message> + <message> <source>Backup wallet to another location</source> <translation>Зрабіце копію гаманца ў іншае месца</translation> </message> @@ -171,6 +255,14 @@ <translation>Змяніць пароль шыфравання гаманца</translation> </message> <message> + <source>&Debug window</source> + <translation>Вакно адладкі</translation> + </message> + <message> + <source>Wallet</source> + <translation>Гаманец</translation> + </message> + <message> <source>&Send</source> <translation>Даслаць</translation> </message> @@ -179,6 +271,18 @@ <translation>Атрымаць</translation> </message> <message> + <source>&Show / Hide</source> + <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>&File</source> <translation>Ф&айл</translation> </message> @@ -190,10 +294,6 @@ <source>&Help</source> <translation>Дапамога</translation> </message> - <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n актыўнае злучэнне з Bitcoin-сецівам</numerusform><numerusform>%n актыўных злучэнняў з Bitcoin-сецівам</numerusform></translation> @@ -245,12 +345,12 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> - <source>Amount</source> - <translation>Колькасць</translation> + <source>Amount:</source> + <translation>Колькасць:</translation> </message> <message> - <source>Address</source> - <translation>Адрас</translation> + <source>Amount</source> + <translation>Колькасць</translation> </message> <message> <source>Date</source> @@ -330,6 +430,14 @@ Address: %4 <context> <name>HelpMessageDialog</name> <message> + <source>(%1-bit)</source> + <translation>(%1-біт)</translation> + </message> + <message> + <source>About Bitcoin Core</source> + <translation>Аб Bitcoin Core</translation> + </message> + <message> <source>Usage:</source> <translation>Ужыванне:</translation> </message> @@ -357,10 +465,6 @@ Address: %4 <source>Form</source> <translation>Форма</translation> </message> - <message> - <source><b>Recent transactions</b></source> - <translation><b>Нядаўнія транзаццыі</b></translation> - </message> </context> <context> <name>PaymentServer</name> @@ -437,6 +541,10 @@ Address: %4 <translation>Даслаць Манеты</translation> </message> <message> + <source>Amount:</source> + <translation>Колькасць:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Даслаць адразу некалькім атрымальнікам</translation> </message> @@ -517,6 +625,10 @@ Address: %4 <context> <name>SplashScreen</name> <message> + <source>The Bitcoin Core developers</source> + <translation>Распрацоўнікі Bitcoin Core</translation> + </message> + <message> <source>[testnet]</source> <translation>[testnet]</translation> </message> @@ -716,6 +828,10 @@ Address: %4 <translation>Рэдагаваць пазнаку</translation> </message> <message> + <source>Exporting Failed</source> + <translation>Экспартаванне няўдалае</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Коскамі падзелены файл (*.csv)</translation> </message> @@ -771,6 +887,10 @@ Address: %4 <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> @@ -779,34 +899,10 @@ Address: %4 <translation>Опцыі:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Вызначыць канфігурацыйны файл (зыходна: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Вызначыць pid-файл (зыходна: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Вызначыць каталог даных</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Слухаць злучэнні на <port> (зыходна: 8333 ці testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Трымаць не больш за <n> злучэнняў на асобу (зыходна: 125)</translation> - </message> - <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Парог для адлучэння злаўмысных карыстальнікаў (тыпова: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Колькасць секунд для ўстрымання асобаў да перадалучэння (заходна: 86400)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Прымаць камандны радок і JSON-RPC каманды</translation> </message> @@ -839,10 +935,6 @@ Address: %4 <translation>Абнавіць гаманец на новы фармат</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Устанавіць памер фонда ключоў у <n> (тыпова: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Перасканаваць ланцуг блокаў дзеля пошуку адсутных транзакцый</translation> </message> @@ -851,14 +943,6 @@ Address: %4 <translation>Ужываць OpenSSL (https) для JSON-RPC злучэнняў</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Файл-сертыфікат сервера (зыходна: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Прыватны ключ сервера (зыходна: server.pem)</translation> - </message> - <message> <source>Loading addresses...</source> <translation>Загружаем адрасы...</translation> </message> diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index 11bf594a42..3095aa1172 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -1,4 +1,4 @@ -<TS language="bg" version="2.1"> +<TS language="bg" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -278,10 +278,6 @@ <source>Tabs toolbar</source> <translation>Раздели</translation> </message> - <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n връзка към Биткоин мрежата</numerusform><numerusform>%n връзки към Биткоин мрежата</numerusform></translation> @@ -369,10 +365,6 @@ <translation>Сума</translation> </message> <message> - <source>Address</source> - <translation>Адрес</translation> - </message> - <message> <source>Date</source> <translation>Дата</translation> </message> @@ -515,10 +507,6 @@ <translation>&Основни</translation> </message> <message> - <source>Pay transaction &fee</source> - <translation>&Такса за изходяща трансакция</translation> - </message> - <message> <source>&Start Bitcoin on system login</source> <translation>&Пускане на Биткоин при вход в системата</translation> </message> @@ -610,10 +598,6 @@ <translation>Форма</translation> </message> <message> - <source>Wallet</source> - <translation>Портфейл</translation> - </message> - <message> <source>Available:</source> <translation>Налично:</translation> </message> @@ -630,10 +614,6 @@ <translation>Текущият ви общ баланс</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Последни трансакции</b></translation> - </message> - <message> <source>out of sync</source> <translation>несинхронизиран</translation> </message> @@ -1427,22 +1407,10 @@ <translation>Опции:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Задаване на файл с настройки (по подразбиране bitcoin.conf)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Определете директория за данните</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Праг на прекъсване на връзката при непорядъчно държащи се пиъри (по подразбиране:100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Брой секунди до възтановяване на връзката за зле държащите се пиъри (по подразбиране:86400)</translation> - </message> - <message> <source>Use the test network</source> <translation>Използвайте тестовата мрежа</translation> </message> @@ -1455,10 +1423,6 @@ <translation>(по подразбиране 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(по подразбиране wallet.dat)</translation> - </message> - <message> <source>Connection options:</source> <translation>Настройки на връзката:</translation> </message> @@ -1467,30 +1431,10 @@ <translation>Грешка: мястото на диска е малко!</translation> </message> <message> - <source>Error: system error: </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>Failed to read block info</source> - <translation>Грешка при четене данни на блок</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Грешка при четене на блок</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Грешка при запис данни на блок</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Грешка при запис на блок</translation> - </message> - <message> <source>Importing...</source> <translation>Внасяне...</translation> </message> @@ -1515,18 +1459,6 @@ <translation>Изпрати локализиращата или дебъг информацията към конзолата, вместо файлът debug.log</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Задайте минимален размер на блок-а в байтове (подразбиране: 0)</translation> - </message> - <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Определете таймаут за свързване в милисекунди (подразбиране: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Системна грешка:</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Сумата на трансакцията е твърде малка</translation> </message> @@ -1567,14 +1499,6 @@ <translation>Използвайте OpenSSL (https) за JSON-RPC връзките</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Сертификатен файл на сървъра (По подразбиране:server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Поверителен ключ за сървъра (default: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Това помощно съобщение</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 0d45ab63b6..8f06ac3aa7 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> @@ -391,10 +391,6 @@ <translation>Barra d'eines de les pestanyes</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Nucli de Bitcoin</translation> </message> @@ -434,10 +430,6 @@ <source>No block source available...</source> <translation>No hi ha cap font de bloc disponible...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Proccessats %1 blocs del històric de transaccions.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation> @@ -525,10 +517,6 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Selecció de l'adreça de control de monedes</translation> - </message> - <message> <source>Quantity:</source> <translation>Quantitat:</translation> </message> @@ -577,10 +565,6 @@ Address: %4 <translation>Quantitat</translation> </message> <message> - <source>Address</source> - <translation>Adreça</translation> - </message> - <message> <source>Date</source> <translation>Data</translation> </message> @@ -912,15 +896,7 @@ Address: %4 <source>Error</source> <translation>Error</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB d'espai lliure disponible</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(d' %1GB necessari)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -955,14 +931,6 @@ Address: %4 <translation>&Principal</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Comissió opcional de transacció per kB que ajuda a assegurar que les transaccions es processen ràpidament. La majoria de transaccions són d'1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Paga &comissió de transacció</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> @@ -991,14 +959,6 @@ Address: %4 <translation>Permet connexions entrants</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Connecta a través d'un proxy SOCKS (proxy per defecte):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1162,8 +1122,8 @@ Address: %4 <translation>La informació mostrada pot no estar al día. El teu moneder es sincronitza automàticament amb la xarxa Bitcoin un cop s'ha establert connexió, però aquest proces no s'ha completat encara.</translation> </message> <message> - <source>Wallet</source> - <translation>Moneder</translation> + <source>Watch-only:</source> + <translation>Només lectura:</translation> </message> <message> <source>Available:</source> @@ -1198,8 +1158,20 @@ Address: %4 <translation>El balanç total actual</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Transaccions recents</b></translation> + <source>Your current balance in watch-only addresses</source> + <translation>El vostre balanç actual en adreces de només lectura</translation> + </message> + <message> + <source>Unconfirmed transactions to watch-only addresses</source> + <translation>Transaccions sense confirmar a adreces de només lectura</translation> + </message> + <message> + <source>Mined balance in watch-only addresses that has not yet matured</source> + <translation>Balanç minat en adreces de només lectura que encara no ha madurat</translation> + </message> + <message> + <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> @@ -1461,8 +1433,36 @@ Address: %4 <translation>Serveis</translation> </message> <message> - <source>Sync Node</source> - <translation>Node de sincronització</translation> + <source>Starting Height</source> + <translation>Alçada inicial</translation> + </message> + <message> + <source>Sync Height</source> + <translation>Sincronitza l'alçada</translation> + </message> + <message> + <source>Ban Score</source> + <translation>Puntuació de bandeig</translation> + </message> + <message> + <source>Connection Time</source> + <translation>Temps de connexió</translation> + </message> + <message> + <source>Last Send</source> + <translation>Darrer enviament</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Darrera recepció</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Bytes enviats</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Bytes rebuts</translation> </message> <message> <source>Ping Time</source> @@ -1544,7 +1544,31 @@ Address: %4 <source>%1 GB</source> <translation>%1 GB</translation> </message> - </context> + <message> + <source>via %1</source> + <translation>a través de %1</translation> + </message> + <message> + <source>never</source> + <translation>mai</translation> + </message> + <message> + <source>Inbound</source> + <translation>Entrant</translation> + </message> + <message> + <source>Outbound</source> + <translation>Sortint</translation> + </message> + <message> + <source>Unknown</source> + <translation>Desconegut</translation> + </message> + <message> + <source>Fetching...</source> + <translation>S'està obtenint...</translation> + </message> +</context> <context> <name>ReceiveCoinsDialog</name> <message> @@ -1928,6 +1952,10 @@ Address: %4 <translation>Això és un pagament normal.</translation> </message> <message> + <source>The Bitcoin address to send the payment to</source> + <translation>L'adreça Bitcoin on enviar el pagament</translation> + </message> + <message> <source>Alt+A</source> <translation>Alta+A</translation> </message> @@ -1998,6 +2026,10 @@ Address: %4 <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> </message> <message> + <source>The Bitcoin address to sign the message with</source> + <translation>L'adreça Bitcoin amb què signar el missatge</translation> + </message> + <message> <source>Choose previously used address</source> <translation>Tria les adreces fetes servir amb anterioritat</translation> </message> @@ -2050,6 +2082,10 @@ Address: %4 <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> </message> <message> + <source>The Bitcoin address the message was signed with</source> + <translation>L'adreça Bitcoin amb què va ser signat el missatge</translation> + </message> + <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>Verificar el missatge per assegurar-se que ha estat signat amb una adreça Bitcoin específica</translation> </message> @@ -2191,6 +2227,10 @@ Address: %4 <translation>Adreça pròpia</translation> </message> <message> + <source>watch-only</source> + <translation>només lectura</translation> + </message> + <message> <source>label</source> <translation>etiqueta</translation> </message> @@ -2211,6 +2251,14 @@ Address: %4 <translation>Dèbit</translation> </message> <message> + <source>Total debit</source> + <translation>Dèbit total</translation> + </message> + <message> + <source>Total credit</source> + <translation>Crèdit total</translation> + </message> + <message> <source>Transaction fee</source> <translation>Comissió de transacció</translation> </message> @@ -2361,6 +2409,10 @@ Address: %4 <translation>Minat</translation> </message> <message> + <source>watch-only</source> + <translation>només lectura</translation> + </message> + <message> <source>(n/a)</source> <translation>(n/a)</translation> </message> @@ -2526,7 +2578,11 @@ Address: %4 </context> <context> <name>UnitDisplayStatusBarControl</name> - </context> + <message> + <source>Unit to show amounts in. Click to select another unit.</source> + <translation>Unitat en què mostrar els imports. Feu clic per seleccionar una altra unitat.</translation> + </message> +</context> <context> <name>WalletFrame</name> <message> @@ -2583,26 +2639,10 @@ Address: %4 <translation>Opcions:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Especifica un fitxer de configuració (per defecte: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Especifica un fitxer pid (per defecte: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Especifica el directori de dades</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Escolta connexions a <port> (per defecte: 8333 o testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Manté com a molt <n> connexions a iguals (per defecte: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Connecta al node per obtenir les adreces de les connexions, i desconnecta</translation> </message> @@ -2611,18 +2651,6 @@ Address: %4 <translation>Especifiqueu la vostra adreça pública</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Límit per a desconectar connexions errònies (per defecte: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Nombre de segons abans de reconectar amb connexions errònies (per defecte: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Escolta connexions JSON-RPC al port <port> (per defecte: 8332 o testnet:18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Accepta la línia d'ordres i ordres JSON-RPC </translation> </message> @@ -2662,16 +2690,12 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Xifrats acceptables (per defecte: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Vincula a una adreça específica i sempre escolta-hi. Utilitza la notació [host]:port per IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Limita contínuament les transaccions gratuïtes a <n>*1000 bytes per minut (per defecte: 15)</translation> + <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> + <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> @@ -2690,14 +2714,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Buida l'activitat de la base de dades de la memòria disponible al registre del disc cada <n> megabytes (per defecte: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Com d'exhaustiva és la verificació de blocs de -checkblocks is (0-4, per defecte: 3)</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> </message> @@ -2706,10 +2722,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Defineix el nombre de fils de verificació d'scripts (%u a %d, 0 = auto, <0 = deixa tants nuclis lliures, per defecte: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Defineix el límit de processadors quan està activada la generació (-1 = sense límit, per defecte: -1)</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>Aquesta és una versió de pre-llançament - utilitza-la sota la teva responsabilitat - No usar per a minería o aplicacions de compra-venda</translation> </message> @@ -2718,10 +2730,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>No es pot enllaçar %s a aquest ordinador. El Bitcoin Core probablement ja estigui executant-s'hi.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Utilitza un proxy SOCKS5 apart per arribar a iguals a través de serveis de Tor ocults (per defecte: -proxy)</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> @@ -2746,10 +2754,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(per defecte: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(per defecte: wallet.dat)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> pot ser:</translation> </message> @@ -2778,10 +2782,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Opcions de depuració/proves:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Inhabilia el mode segur (safemode), invalida un esdeveniment de mode segur real (per defecte: 0)</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> @@ -2818,66 +2818,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Error: El moneder està bloquejat, no és possible crear la transacció!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Error: error de sistema: </translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Ha fallat escoltar a qualsevol port. Feu servir -listen=0 si voleu fer això.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Ha fallat la lectura de la informació del bloc</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Ha fallat la lectura del bloc</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Ha fallat la sincronització de l'índex de blocs</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Ha fallat la escriptura de l'índex de blocs</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Ha fallat la escriptura de la informació de bloc</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Ha fallat l'escriptura del bloc</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Ha fallat l'escriptura de la informació de fitxer</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Ha fallat l'escriptura de la basse de dades de monedes</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Ha fallat l'escriptura de l'índex de transaccions</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Ha fallat el desfer de dades</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Força el mode segur (per defecte: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Genera monedes (per defecte: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Quants blocs s'han de confirmar a l'inici (per defecte: 288, 0 = tots)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Si no se subministra <category>, mostra tota la informació de depuració.</translation> </message> @@ -2898,10 +2842,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>No hi ha suficient descriptors de fitxers disponibles.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Posa davant de la sortida de depuració una marca horària (per defecte: 1)</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> </message> @@ -2914,18 +2854,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Defineix la mida màxim del bloc en bytes (per defecte: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Estableix el nombre de fils per atendre trucades RPC (per defecte: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Especifica un fitxer de moneder (dins del directori de dades)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Gasta el canvi sense confirmar en enviar transaccions (per defecte: 1)</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> @@ -2954,26 +2886,102 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Importa blocs de un fitxer blk000??.dat extern</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>Permet les connexions JSON-RPC d'una font específica. Vàlid per a <ip> són una IP individual (p. ex., 1.2.3.4), una xarxa / màscara de xarxa (p. ex., 1.2.3.4/255.255.255.0) o una xarxa/CIDR (p. ex., 1.2.3.4/24). Es pot especificar aquesta opció moltes vegades</translation> + </message> + <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>Vincula l'adreça donada i posa a la llista blanca els iguals que s'hi connectin. Feu servir la notació [host]:port per a 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>Vincula a l'adreça donada per a escoltar les connexions JSON-RPC. Feu servir la notació [host]:port per a IPv6. Aquesta opció pot ser especificada moltes vegades (per defecte: vincula a totes les interfícies)</translation> + </message> + <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>No es pot obtenir un bloqueig del directori de dades %s. El Bitcoin Core probablement ja s'estigui executant.</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>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> + <message> + <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Error: s'ha trobat un argument no permès de -socks. Ja no es pot definir més la versió de SOCKS, només s'accepten els proxies de 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>Executa l'ordre quan es rebi un avís rellevant o veiem una forquilla molt llarga (%s en cmd és reemplaçat per un missatge)</translation> </message> <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Informació de la depuració de sortida (per defecte: 0, proporcionar <category> és opcional)</translation> + <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> + <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>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>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>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> + <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 siguin correctes! Si el vostre rellotge no és correcte, el Bitcoin Core no funcionarà correctament.</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>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>Cannot resolve -whitebind address: '%s'</source> + <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation> + </message> + <message> + <source>Connect through SOCKS5 proxy</source> + <translation>Connecta a través del proxy SOCKS5</translation> + </message> + <message> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Copyright (C) 2009-%i Els desenvolupadors del Bitcoin Core</translation> + </message> + <message> + <source>Could not parse -rpcbind value %s as network address</source> + <translation>No s'ha pogut analitzar el valor -rpcbind %s com una adreça de xarxa</translation> + </message> + <message> + <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> + <translation>Error en carregar wallet.dat: el moneder requereix una versió més nova del Bitcoin core</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> + <message> + <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> + <translation>Comissió en (BTC/kB) per afegir a les transaccions que envieu (per defecte: %s)</translation> + </message> + <message> <source>Information</source> <translation>&Informació</translation> </message> <message> + <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source> + <translation>Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està aturant.</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Import no vàlid per a -minrelaytxfee=<amount>: «%s»</translation> </message> @@ -2982,42 +2990,30 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Import no vàlid per a -mintxfee=<amount>: «%s»</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Mida límit de la memòria cau de signatura per a <n> entrades (per defecte: 50000)</translation> + <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> + <translation>Import no vàlid per a -paytxfee=<amount>: «%s» (ha de ser com a mínim %s)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Registra la prioritat de transacció i comissió per kB en minar blocs (per defecte: 0)</translation> + <source>Invalid netmask specified in -whitelist: '%s'</source> + <translation>S'ha especificat una màscara de xarxa no vàlida a -whitelist: «%s»</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Manté l'índex sencer de transaccions (per defecte: 0)</translation> + <source>Keep at most <n> unconnectable blocks in memory (default: %u)</source> + <translation>Manté com a màxim <n> blocs no connectables en memòria (per defecte: %u)</translation> </message> <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Mida màxima del buffer de recepció per a cada connexió, <n>*1000 bytes (default: 5000)</translation> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>Cal especificar un port amb -whitebind: «%s»</translation> </message> <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Mida màxima del buffer d'enviament per a cada connexió, <n>*1000 bytes (default: 5000)</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Només accepta cadenes de blocs que coincideixin amb els punts de prova (per defecte: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Només connecta als nodes de la xarxa <net> (IPv4, IPv6 o Tor)</translation> + <source>Node relay options:</source> + <translation>Opcions de transmissió del node:</translation> </message> <message> <source>Print block on startup, if found in block index</source> <translation>Imprimeix el block a l'inici, si es troba l'índex de blocs</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Imprimeix l'arbre de blocs a l'inici (per defecte: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Opcions RPC SSL: (veieu el wiki del Bitcoin per a instruccions de configuració de l'SSL)</translation> </message> @@ -3034,22 +3030,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Introdueix incertesa en 1 de cada <n> missatges de la xarxa</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Executa un fil per buidar el moneder periòdicament (per defecte: 1)</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>Set minimum block size in bytes (default: 0)</source> - <translation>Defineix una mida mínima de bloc en bytes (per defecte: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Defineix el senyal DB_PRIVATE en l'entorn db del moneder (per defecte: 1)</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> @@ -3062,12 +3046,8 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ha fallat la signatura de la transacció</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Especifica el temps limit per a un intent de connexió en mil·lisegons (per defecte: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Error de sistema: </translation> + <source>This is experimental software.</source> + <translation>Això és programari experimental.</translation> </message> <message> <source>Transaction amount too small</source> @@ -3082,8 +3062,8 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>La transacció és massa gran</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Utilitza UPnP per a mapejar els ports d'escolta (per defecte: 0)</translation> + <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> <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> @@ -3094,6 +3074,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Nom d'usuari per a connexions JSON-RPC</translation> </message> <message> + <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source> + <translation>Cal reescriure el moneder: reiniceu el Bitcoin Core per completar-ho.</translation> + </message> + <message> <source>Warning</source> <translation>Avís</translation> </message> @@ -3102,6 +3086,14 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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> + <message> + <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Avís: s'ha ignorat l'argument no acceptat de -debugnet. Feu servir -debug=net.</translation> + </message> + <message> <source>Zapping all transactions from wallet...</source> <translation>Se suprimeixen totes les transaccions del moneder...</translation> </message> @@ -3126,10 +3118,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Actualitza el moneder a l'últim format</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Defineix el límit de nombre de claus a <n> (per defecte: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Reescaneja la cadena de blocs en les transaccions de moneder perdudes</translation> </message> @@ -3138,14 +3126,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Utilitza OpenSSL (https) per a connexions JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Fitxer del certificat de servidor (per defecte: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Clau privada del servidor (per defecte: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Aquest misatge d'ajuda</translation> </message> diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index 0d43d95d2a..d3bf33ebfb 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -1,13 +1,13 @@ -<TS language="ca@valencia" version="2.1"> +<TS language="ca@valencia" version="2.0"> <context> <name>AddressBookPage</name> <message> <source>Double-click to edit address or label</source> - <translation>Doble click per editar la direccio o la etiqueta</translation> + <translation>Feu doble clic per editar l'adreça o l'etiqueta</translation> </message> <message> <source>Create a new address</source> - <translation>Crear nova direccio</translation> + <translation>Crea una nova adreça</translation> </message> <message> <source>&New</source> @@ -15,7 +15,7 @@ </message> <message> <source>Copy the currently selected address to the system clipboard</source> - <translation>Copieu l'adreça seleccionada al porta-retalls del sistema</translation> + <translation>Copia l'adreça seleccionada al porta-retalls del sistema</translation> </message> <message> <source>&Copy</source> @@ -43,7 +43,7 @@ </message> <message> <source>&Delete</source> - <translation>Eliminar</translation> + <translation>&Elimina</translation> </message> <message> <source>Choose the address to send coins to</source> @@ -93,7 +93,11 @@ <source>Exporting Failed</source> <translation>L'exportació ha fallat</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>S'ha produït un error en guardar la llista d'adreces a %1. Torneu-ho a provar.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -180,6 +184,10 @@ <translation>Moneder encriptat</translation> </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>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> </message> @@ -287,6 +295,10 @@ <translation>Obri un &URI...</translation> </message> <message> + <source>Bitcoin Core client</source> + <translation>Client del Bitcoin Core</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>S'estan important els blocs del disc...</translation> </message> @@ -339,6 +351,10 @@ <translation>&Rep</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>Mostra informació del Bitcoin Core</translation> + </message> + <message> <source>&Show / Hide</source> <translation>&Mostra / Amaga</translation> </message> @@ -375,12 +391,8 @@ <translation>Barra d'eines de les pestanyes</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> - <translation>Bitcoin Core</translation> + <translation>Nucli de Bitcoin</translation> </message> <message> <source>Request payments (generates QR codes and bitcoin: URIs)</source> @@ -415,10 +427,6 @@ <translation>No hi ha cap font de bloc disponible...</translation> </message> <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Proccessats %1 blocs del històric de transaccions.</translation> - </message> - <message> <source>%1 and %2</source> <translation>%1 i %2</translation> </message> @@ -489,10 +497,6 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Selecció de l'adreça de control de monedes</translation> - </message> - <message> <source>Quantity:</source> <translation>Quantitat:</translation> </message> @@ -513,8 +517,12 @@ Address: %4 <translation>Quota:</translation> </message> <message> + <source>Dust:</source> + <translation>Polsim:</translation> + </message> + <message> <source>After Fee:</source> - <translation>Comissió posterior:</translation> + <translation>Quota posterior:</translation> </message> <message> <source>Change:</source> @@ -534,11 +542,7 @@ Address: %4 </message> <message> <source>Amount</source> - <translation>Import</translation> - </message> - <message> - <source>Address</source> - <translation>Adreça</translation> + <translation>Quantitat</translation> </message> <message> <source>Date</source> @@ -601,6 +605,10 @@ Address: %4 <translation>Copia la prioritat</translation> </message> <message> + <source>Copy dust</source> + <translation>Copia el polsim</translation> + </message> + <message> <source>Copy change</source> <translation>Copia el canvi</translation> </message> @@ -649,6 +657,10 @@ Address: %4 <translation>cap</translation> </message> <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>Pot variar +/- %1 satoshi(s) per entrada.</translation> + </message> + <message> <source>yes</source> <translation>sí</translation> </message> @@ -775,7 +787,7 @@ Address: %4 <name>HelpMessageDialog</name> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Core</translation> + <translation>Nucli de Bitcoin</translation> </message> <message> <source>version</source> @@ -790,6 +802,10 @@ Address: %4 <translation>Quant al Bitcoin Core</translation> </message> <message> + <source>Command-line options</source> + <translation>Opcions de línia d'ordes</translation> + </message> + <message> <source>Usage:</source> <translation>Ús:</translation> </message> @@ -850,21 +866,17 @@ Address: %4 </message> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Core</translation> - </message> - <message> - <source>Error</source> - <translation>Error</translation> + <translation>Nucli de Bitcoin</translation> </message> <message> - <source>GB of free space available</source> - <translation>GB d'espai lliure disponible</translation> + <source>Error: Specified data directory "%1" cannot be created.</source> + <translation>Error: el directori de dades «%1» especificat no pot ser creat.</translation> </message> <message> - <source>(of %1GB needed)</source> - <translation>(d' %1GB necessari)</translation> + <source>Error</source> + <translation>Error</translation> </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -899,14 +911,6 @@ Address: %4 <translation>&Principal</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Comissió opcional de transacció per kB que ajuda a assegurar que les transaccions es processen ràpidament. La majoria de transaccions són d'1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Paga &comissió de transacció</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> @@ -927,12 +931,12 @@ Address: %4 <translation>Nombre de fils de &verificació d'scripts</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS.</translation> + <source>Accept connections from outside</source> + <translation>Accepta connexions de fora</translation> </message> <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Connecta a través d'un proxy SOCKS (proxy per defecte):</translation> + <source>Allow incoming connections</source> + <translation>Permet connexions entrants</translation> </message> <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> @@ -1098,8 +1102,8 @@ Address: %4 <translation>La informació mostrada pot no estar al día. El teu moneder es sincronitza automàticament amb la xarxa Bitcoin un cop s'ha establit connexió, però este proces no s'ha completat encara.</translation> </message> <message> - <source>Wallet</source> - <translation>Moneder</translation> + <source>Watch-only:</source> + <translation>Només lectura:</translation> </message> <message> <source>Available:</source> @@ -1134,8 +1138,20 @@ Address: %4 <translation>El balanç total actual</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Transaccions recents</b></translation> + <source>Your current balance in watch-only addresses</source> + <translation>El vostre balanç actual en adreces de només lectura</translation> + </message> + <message> + <source>Unconfirmed transactions to watch-only addresses</source> + <translation>Transaccions sense confirmar a adreces de només lectura</translation> + </message> + <message> + <source>Mined balance in watch-only addresses that has not yet matured</source> + <translation>Balanç minat en adreces de només lectura que encara no ha madurat</translation> + </message> + <message> + <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> @@ -1153,6 +1169,22 @@ Address: %4 <translation>Adreça de pagament no vàlida %1</translation> </message> <message> + <source>Payment request rejected</source> + <translation>La sol·licitud de pagament s'ha rebutjat</translation> + </message> + <message> + <source>Payment request network doesn't match client network.</source> + <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> + <message> <source>Requested payment amount of %1 is too small (considered dust).</source> <translation>L'import de pagament sol·licitat %1 és massa petit (es considera polsim).</translation> </message> @@ -1169,10 +1201,18 @@ Address: %4 <translation>L'URL de recuperació de la sol·licitud de pagament no és vàlida: %1</translation> </message> <message> + <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> + <translation>L'URI no pot ser analitzat! Això pot ser a causa d'una adreça de Bitcoin no vàlida o per paràmetres URI amb mal format.</translation> + </message> + <message> <source>Payment request file handling</source> <translation>Gestió de fitxers de les sol·licituds de pagament</translation> </message> <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <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>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> @@ -1185,6 +1225,10 @@ Address: %4 <translation>Error en comunicar amb %1: %2</translation> </message> <message> + <source>Payment request cannot be parsed!</source> + <translation>No es pot analitzar la sol·licitud de pagament!</translation> + </message> + <message> <source>Bad response from server %1</source> <translation>Mala resposta del servidor %1</translation> </message> @@ -1199,12 +1243,32 @@ Address: %4 </context> <context> <name>PeerTableModel</name> - </context> + <message> + <source>User Agent</source> + <translation>Agent d'usuari</translation> + </message> + <message> + <source>Address/Hostname</source> + <translation>Adreça / nom de l'ordinador</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Temps de ping</translation> + </message> +</context> <context> <name>QObject</name> <message> <source>Amount</source> - <translation>Import</translation> + <translation>Quantitat</translation> + </message> + <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>Introduïu una adreça de Bitcoin (p. ex. %1)</translation> + </message> + <message> + <source>%1 d</source> + <translation>%1 d</translation> </message> <message> <source>%1 h</source> @@ -1215,10 +1279,30 @@ Address: %4 <translation>%1 m</translation> </message> <message> + <source>%1 s</source> + <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> + <message> <source>N/A</source> - <translation>N/D</translation> + <translation>N/A</translation> </message> - </context> + <message> + <source>%1 ms</source> + <translation>%1 ms</translation> + </message> +</context> <context> <name>QRImageWidget</name> <message> @@ -1246,7 +1330,7 @@ Address: %4 </message> <message> <source>N/A</source> - <translation>N/D</translation> + <translation>N/A</translation> </message> <message> <source>Client version</source> @@ -1269,6 +1353,10 @@ Address: %4 <translation>Utilitzant OpenSSL versió</translation> </message> <message> + <source>Using BerkeleyDB version</source> + <translation>Utilitzant BerkeleyDB versió</translation> + </message> + <message> <source>Startup time</source> <translation>&Temps d'inici</translation> </message> @@ -1293,6 +1381,74 @@ Address: %4 <translation>Nombre de blocs actuals</translation> </message> <message> + <source>Received</source> + <translation>Rebut</translation> + </message> + <message> + <source>Sent</source> + <translation>Enviat</translation> + </message> + <message> + <source>&Peers</source> + <translation>&Iguals</translation> + </message> + <message> + <source>Select a peer to view detailed information.</source> + <translation>Seleccioneu un igual per mostrar informació detallada.</translation> + </message> + <message> + <source>Direction</source> + <translation>Direcció</translation> + </message> + <message> + <source>Version</source> + <translation>Versió</translation> + </message> + <message> + <source>User Agent</source> + <translation>Agent d'usuari</translation> + </message> + <message> + <source>Services</source> + <translation>Serveis</translation> + </message> + <message> + <source>Starting Height</source> + <translation>Alçada inicial</translation> + </message> + <message> + <source>Sync Height</source> + <translation>Sincronitza l'alçada</translation> + </message> + <message> + <source>Ban Score</source> + <translation>Puntuació de bandeig</translation> + </message> + <message> + <source>Connection Time</source> + <translation>Temps de connexió</translation> + </message> + <message> + <source>Last Send</source> + <translation>Darrer enviament</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Darrera recepció</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Bytes enviats</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Bytes rebuts</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Temps de ping</translation> + </message> + <message> <source>Last block time</source> <translation>Últim temps de bloc</translation> </message> @@ -1368,7 +1524,31 @@ Address: %4 <source>%1 GB</source> <translation>%1 GB</translation> </message> - </context> + <message> + <source>via %1</source> + <translation>a través de %1</translation> + </message> + <message> + <source>never</source> + <translation>mai</translation> + </message> + <message> + <source>Inbound</source> + <translation>Entrant</translation> + </message> + <message> + <source>Outbound</source> + <translation>Eixint</translation> + </message> + <message> + <source>Unknown</source> + <translation>Desconegut</translation> + </message> + <message> + <source>Fetching...</source> + <translation>S'està obtenint...</translation> + </message> +</context> <context> <name>ReceiveCoinsDialog</name> <message> @@ -1409,7 +1589,7 @@ Address: %4 </message> <message> <source>Clear all fields of the form.</source> - <translation>Neteja tots els camps del formulari.</translation> + <translation>Esborra tots els camps del formuari.</translation> </message> <message> <source>Clear</source> @@ -1441,7 +1621,7 @@ Address: %4 </message> <message> <source>Copy label</source> - <translation>Copiar etiqueta</translation> + <translation>Copia l'etiqueta</translation> </message> <message> <source>Copy message</source> @@ -1578,11 +1758,11 @@ Address: %4 </message> <message> <source>Fee:</source> - <translation>Quota:</translation> + <translation>Comissió:</translation> </message> <message> <source>After Fee:</source> - <translation>Comissió posterior:</translation> + <translation>Quota posterior:</translation> </message> <message> <source>Change:</source> @@ -1606,7 +1786,11 @@ Address: %4 </message> <message> <source>Clear all fields of the form.</source> - <translation>Neteja tots els camps del formulari.</translation> + <translation>Netejar tots els camps del formulari.</translation> + </message> + <message> + <source>Dust:</source> + <translation>Polsim:</translation> </message> <message> <source>Clear &All</source> @@ -1642,7 +1826,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> @@ -1709,6 +1893,10 @@ Address: %4 <translation>Avís: adreça de canvi desconeguda</translation> </message> <message> + <source>Copy dust</source> + <translation>Copia el polsim</translation> + </message> + <message> <source>Are you sure you want to send?</source> <translation>Esteu segur que ho voleu enviar?</translation> </message> @@ -1737,19 +1925,23 @@ Address: %4 </message> <message> <source>Choose previously used address</source> - <translation>Tria les adreces fetes servir amb anterioritat</translation> + <translation>Trieu una adreça feta servir anteriorment</translation> </message> <message> <source>This is a normal payment.</source> <translation>Això és un pagament normal.</translation> </message> <message> + <source>The Bitcoin address to send the payment to</source> + <translation>L'adreça Bitcoin on enviar el pagament</translation> + </message> + <message> <source>Alt+A</source> - <translation>Alt+A</translation> + <translation>Alta+A</translation> </message> <message> <source>Paste address from clipboard</source> - <translation>Apega l'adreça del porta-retalls</translation> + <translation>Apegar adreça del porta-retalls</translation> </message> <message> <source>Alt+P</source> @@ -1814,6 +2006,10 @@ Address: %4 <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> </message> <message> + <source>The Bitcoin address to sign the message with</source> + <translation>L'adreça Bitcoin amb què signar el missatge</translation> + </message> + <message> <source>Choose previously used address</source> <translation>Tria les adreces fetes servir amb anterioritat</translation> </message> @@ -1866,6 +2062,10 @@ Address: %4 <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> </message> <message> + <source>The Bitcoin address the message was signed with</source> + <translation>L'adreça Bitcoin amb què va ser signat el missatge</translation> + </message> + <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>Verificar el missatge per assegurar-se que ha estat signat amb una adreça Bitcoin específica</translation> </message> @@ -2003,6 +2203,10 @@ Address: %4 <translation>Adreça pròpia</translation> </message> <message> + <source>watch-only</source> + <translation>només lectura</translation> + </message> + <message> <source>label</source> <translation>etiqueta</translation> </message> @@ -2019,6 +2223,14 @@ Address: %4 <translation>Dèbit</translation> </message> <message> + <source>Total debit</source> + <translation>Dèbit total</translation> + </message> + <message> + <source>Total credit</source> + <translation>Crèdit total</translation> + </message> + <message> <source>Transaction fee</source> <translation>Comissió de transacció</translation> </message> @@ -2060,7 +2272,7 @@ Address: %4 </message> <message> <source>Amount</source> - <translation>Import</translation> + <translation>Quantitat</translation> </message> <message> <source>true</source> @@ -2161,6 +2373,10 @@ Address: %4 <translation>Minat</translation> </message> <message> + <source>watch-only</source> + <translation>només lectura</translation> + </message> + <message> <source>(n/a)</source> <translation>(n/a)</translation> </message> @@ -2245,7 +2461,7 @@ Address: %4 </message> <message> <source>Copy address</source> - <translation>Copiar adreça </translation> + <translation>Copia l'adreça</translation> </message> <message> <source>Copy label</source> @@ -2289,7 +2505,7 @@ Address: %4 </message> <message> <source>Comma separated file (*.csv)</source> - <translation>Fitxer de separació amb comes (*.csv)</translation> + <translation>Fitxer separat per comes (*.csv)</translation> </message> <message> <source>Confirmed</source> @@ -2326,7 +2542,11 @@ Address: %4 </context> <context> <name>UnitDisplayStatusBarControl</name> - </context> + <message> + <source>Unit to show amounts in. Click to select another unit.</source> + <translation>Unitat en què mostrar els imports. Feu clic per seleccionar una altra unitat.</translation> + </message> +</context> <context> <name>WalletFrame</name> <message> @@ -2383,26 +2603,10 @@ Address: %4 <translation>Opcions:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Especifica un fitxer de configuració (per defecte: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Especifica un fitxer pid (per defecte: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Especifica el directori de dades</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Escolta connexions a <port> (per defecte: 8333 o testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Manté com a molt <n> connexions a iguals (per defecte: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Connecta al node per obtindre les adreces de les connexions, i desconnecta</translation> </message> @@ -2411,18 +2615,6 @@ Address: %4 <translation>Especifiqueu la vostra adreça pública</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Límit per a desconectar connexions errònies (per defecte: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Nombre de segons abans de reconectar amb connexions errònies (per defecte: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Escolta connexions JSON-RPC al port <port> (per defecte: 8332 o testnet:18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Accepta la línia d'ordes i ordes JSON-RPC </translation> </message> @@ -2462,16 +2654,12 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Xifrats acceptables (per defecte: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Vincula a una adreça específica i sempre escolta-hi. Utilitza la notació [host]:port per IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Limita contínuament les transaccions gratuïtes a <n>*1000 bytes per minut (per defecte: 15)</translation> + <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> + <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> @@ -2490,14 +2678,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Executa una orde quan una transacció del moneder canvie (%s en cmd es canvia per TxID)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Buida l'activitat de la base de dades de la memòria disponible al registre del disc cada <n> megabytes (per defecte: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Com d'exhaustiva és la verificació de blocs de -checkblocks is (0-4, per defecte: 3)</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> </message> @@ -2506,10 +2686,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Defineix el nombre de fils de verificació d'scripts (%u a %d, 0 = auto, <0 = deixa tants nuclis lliures, per defecte: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Defineix el límit de processadors quan està activada la generació (-1 = sense límit, per defecte: -1)</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>Esta és una versió de pre-llançament - utilitza-la sota la teva responsabilitat - No usar per a minería o aplicacions de compra-venda</translation> </message> @@ -2518,10 +2694,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>No es pot enllaçar %s a este ordinador. El Bitcoin Core probablement ja estiga executant-s'hi.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Utilitza un proxy SOCKS5 apart per arribar a iguals a través de serveis de Tor ocults (per defecte: -proxy)</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> @@ -2546,10 +2718,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(per defecte: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(per defecte: wallet.dat)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> pot ser:</translation> </message> @@ -2578,10 +2746,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Opcions de depuració/proves:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Inhabilia el mode segur (safemode), invalida un esdeveniment de mode segur real (per defecte: 0)</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> @@ -2618,66 +2782,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Error: El moneder està bloquejat, no és possible crear la transacció!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Error: error de sistema: </translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Ha fallat escoltar a qualsevol port. Feu servir -listen=0 si voleu fer això.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Ha fallat la lectura de la informació del bloc</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Ha fallat la lectura del bloc</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Ha fallat la sincronització de l'índex de blocs</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Ha fallat la escriptura de l'índex de blocs</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Ha fallat la escriptura de la informació de bloc</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Ha fallat l'escriptura del bloc</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Ha fallat l'escriptura de la informació de fitxer</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Ha fallat l'escriptura de la basse de dades de monedes</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Ha fallat l'escriptura de l'índex de transaccions</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Ha fallat el desfer de dades</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Força el mode segur (per defecte: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Genera monedes (per defecte: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Quants blocs s'han de confirmar a l'inici (per defecte: 288, 0 = tots)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Si no se subministra <category>, mostra tota la informació de depuració.</translation> </message> @@ -2698,10 +2806,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>No hi ha suficient descriptors de fitxers disponibles.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Posa davant de l'eixida de depuració una marca horària (per defecte: 1)</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> </message> @@ -2714,18 +2818,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Defineix la mida màxim del bloc en bytes (per defecte: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Estableix el nombre de fils per atendre trucades RPC (per defecte: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Especifica un fitxer de moneder (dins del directori de dades)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Gasta el canvi sense confirmar en enviar transaccions (per defecte: 1)</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> </message> @@ -2754,24 +2850,100 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Importa blocs d'un fitxer blk000??.dat extern</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>Permet les connexions JSON-RPC d'una font específica. Vàlid per a <ip> són una IP individual (p. ex., 1.2.3.4), una xarxa / màscara de xarxa (p. ex., 1.2.3.4/255.255.255.0) o una xarxa/CIDR (p. ex., 1.2.3.4/24). Es pot especificar esta opció moltes vegades</translation> + </message> + <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>Vincula l'adreça donada i posa a la llista blanca els iguals que s'hi connecten. Feu servir la notació [host]:port per a 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>Vincula a l'adreça donada per a escoltar les connexions JSON-RPC. Feu servir la notació [host]:port per a IPv6. Esta opció pot ser especificada moltes vegades (per defecte: vincula a totes les interfícies)</translation> + </message> + <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>No es pot obtindre un bloqueig del directori de dades %s. El Bitcoin Core probablement ja s'estiga executant.</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>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> + <message> + <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Error: s'ha trobat un argument no permés de -socks. Ja no es pot definir més la versió de SOCKS, només s'accepten els proxies de 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>Executa l'orde quan es reba un avís rellevant o veiem una forquilla molt llarga (%s en cmd és reemplaçat per un missatge)</translation> </message> <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Informació de la depuració d'eixida (per defecte: 0, proporcionar <category> és opcional)</translation> + <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> + <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>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>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>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>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> + <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>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>Cannot resolve -whitebind address: '%s'</source> + <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation> + </message> + <message> + <source>Connect through SOCKS5 proxy</source> + <translation>Connecta a través del proxy SOCKS5</translation> + </message> + <message> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Copyright (C) 2009-%i Els desenvolupadors del Bitcoin Core</translation> + </message> + <message> + <source>Could not parse -rpcbind value %s as network address</source> + <translation>No s'ha pogut analitzar el valor -rpcbind %s com una adreça de xarxa</translation> + </message> + <message> + <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> + <translation>Error en carregar wallet.dat: el moneder requereix una versió més nova del Bitcoin core</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> + <message> + <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> + <translation>Comissió en (BTC/kB) per afegir a les transaccions que envieu (per defecte: %s)</translation> + </message> + <message> <source>Information</source> - <translation>Informació</translation> + <translation>&Informació</translation> + </message> + <message> + <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source> + <translation>Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està parant.</translation> </message> <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> @@ -2782,42 +2954,30 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Import no vàlid per a -mintxfee=<amount>: «%s»</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Mida límit de la memòria cau de signatura per a <n> entrades (per defecte: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Registra la prioritat de transacció i comissió per kB en minar blocs (per defecte: 0)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Manté l'índex sencer de transaccions (per defecte: 0)</translation> + <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> + <translation>Import no vàlid per a -paytxfee=<amount>: «%s» (ha de ser com a mínim %s)</translation> </message> <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Mida màxima del buffer de recepció per a cada connexió, <n>*1000 bytes (default: 5000)</translation> + <source>Invalid netmask specified in -whitelist: '%s'</source> + <translation>S'ha especificat una màscara de xarxa no vàlida a -whitelist: «%s»</translation> </message> <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Mida màxima del buffer d'enviament per a cada connexió, <n>*1000 bytes (default: 5000)</translation> + <source>Keep at most <n> unconnectable blocks in memory (default: %u)</source> + <translation>Manté com a màxim <n> blocs no connectables en memòria (per defecte: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Només accepta cadenes de blocs que coincidisquen amb els punts de prova (per defecte: 1)</translation> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>Cal especificar un port amb -whitebind: «%s»</translation> </message> <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Només connecta als nodes de la xarxa <net> (IPv4, IPv6 o Tor)</translation> + <source>Node relay options:</source> + <translation>Opcions de transmissió del node:</translation> </message> <message> <source>Print block on startup, if found in block index</source> <translation>Imprimeix el block a l'inici, si es troba l'índex de blocs</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Imprimeix l'arbre de blocs a l'inici (per defecte: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Opcions RPC SSL: (veieu el wiki del Bitcoin per a instruccions de configuració de l'SSL)</translation> </message> @@ -2834,22 +2994,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Introdueix incertesa en 1 de cada <n> missatges de la xarxa</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Executa un fil per buidar el moneder periòdicament (per defecte: 1)</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>Set minimum block size in bytes (default: 0)</source> - <translation>Defineix una mida mínima de bloc en bytes (per defecte: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Defineix el senyal DB_PRIVATE en l'entorn db del moneder (per defecte: 1)</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> @@ -2862,12 +3010,8 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ha fallat la signatura de la transacció</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Especifica el temps limit per a un intent de connexió en mil·lisegons (per defecte: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Error de sistema: </translation> + <source>This is experimental software.</source> + <translation>Això és programari experimental.</translation> </message> <message> <source>Transaction amount too small</source> @@ -2882,8 +3026,8 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>La transacció és massa gran</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Utilitza UPnP per a mapejar els ports d'escolta (per defecte: 0)</translation> + <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> <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> @@ -2894,6 +3038,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Nom d'usuari per a connexions JSON-RPC</translation> </message> <message> + <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source> + <translation>Cal reescriure el moneder: reiniceu el Bitcoin Core per completar-ho.</translation> + </message> + <message> <source>Warning</source> <translation>Avís</translation> </message> @@ -2902,6 +3050,14 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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> + <message> + <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Avís: s'ha ignorat l'argument no acceptat de -debugnet. Feu servir -debug=net.</translation> + </message> + <message> <source>Zapping all transactions from wallet...</source> <translation>Se suprimeixen totes les transaccions del moneder...</translation> </message> @@ -2926,10 +3082,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Actualitza el moneder a l'últim format</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Defineix el límit de nombre de claus a <n> (per defecte: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Reescaneja la cadena de blocs en les transaccions de moneder perdudes</translation> </message> @@ -2938,14 +3090,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Utilitza OpenSSL (https) per a connexions JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Fitxer del certificat de servidor (per defecte: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Clau privada del servidor (per defecte: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Este misatge d'ajuda</translation> </message> diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index f3b2b4a926..60c6fa30f4 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> @@ -391,10 +391,6 @@ <translation>Barra d'eines de les pestanyes</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Nucli de Bitcoin</translation> </message> @@ -434,10 +430,6 @@ <source>No block source available...</source> <translation>No hi ha cap font de bloc disponible...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Proccessats %1 blocs del històric de transaccions.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation> @@ -525,10 +517,6 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Selecció de l'adreça de control de monedes</translation> - </message> - <message> <source>Quantity:</source> <translation>Quantitat:</translation> </message> @@ -577,10 +565,6 @@ Address: %4 <translation>Quantitat</translation> </message> <message> - <source>Address</source> - <translation>Adreça</translation> - </message> - <message> <source>Date</source> <translation>Data</translation> </message> @@ -912,15 +896,7 @@ Address: %4 <source>Error</source> <translation>Error</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB d'espai lliure disponible</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(d' %1GB necessari)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -955,14 +931,6 @@ Address: %4 <translation>&Principal</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Comissió opcional de transacció per kB que ajuda a assegurar que les transaccions es processen ràpidament. La majoria de transaccions són d'1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Paga &comissió de transacció</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> @@ -991,14 +959,6 @@ Address: %4 <translation>Permet connexions entrants</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Connecta a través d'un proxy SOCKS (proxy per defecte):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1162,10 +1122,6 @@ Address: %4 <translation>La informació mostrada pot no estar al día. El teu moneder es sincronitza automàticament amb la xarxa Bitcoin un cop s'ha establert connexió, però aquest proces no s'ha completat encara.</translation> </message> <message> - <source>Wallet</source> - <translation>Moneder</translation> - </message> - <message> <source>Watch-only:</source> <translation>Només lectura:</translation> </message> @@ -1218,10 +1174,6 @@ Address: %4 <translation>Balanç total actual en adreces de només lectura</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Transaccions recents</b></translation> - </message> - <message> <source>out of sync</source> <translation>Fora de sincronia</translation> </message> @@ -1481,10 +1433,6 @@ Address: %4 <translation>Serveis</translation> </message> <message> - <source>Sync Node</source> - <translation>Node de sincronització</translation> - </message> - <message> <source>Starting Height</source> <translation>Alçada inicial</translation> </message> @@ -1613,14 +1561,6 @@ Address: %4 <translation>Sortint</translation> </message> <message> - <source>Yes</source> - <translation>Sí</translation> - </message> - <message> - <source>No</source> - <translation>No</translation> - </message> - <message> <source>Unknown</source> <translation>Desconegut</translation> </message> @@ -2469,6 +2409,10 @@ Address: %4 <translation>Minat</translation> </message> <message> + <source>watch-only</source> + <translation>només lectura</translation> + </message> + <message> <source>(n/a)</source> <translation>(n/a)</translation> </message> @@ -2695,26 +2639,10 @@ Address: %4 <translation>Opcions:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Especifica un fitxer de configuració (per defecte: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Especifica un fitxer pid (per defecte: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Especifica el directori de dades</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Escolta connexions a <port> (per defecte: 8333 o testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Manté com a molt <n> connexions a iguals (per defecte: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Connecta al node per obtenir les adreces de les connexions, i desconnecta</translation> </message> @@ -2723,18 +2651,6 @@ Address: %4 <translation>Especifiqueu la vostra adreça pública</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Límit per a desconectar connexions errònies (per defecte: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Nombre de segons abans de reconectar amb connexions errònies (per defecte: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Escolta connexions JSON-RPC al port <port> (per defecte: 8332 o testnet:18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Accepta la línia d'ordres i ordres JSON-RPC </translation> </message> @@ -2774,18 +2690,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Xifrats acceptables (per defecte: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Vincula a una adreça específica i sempre escolta-hi. Utilitza la notació [host]:port per IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Limita contínuament les transaccions gratuïtes a <n>*1000 bytes per minut (per defecte: 15)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <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> @@ -2806,14 +2714,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Buida l'activitat de la base de dades de la memòria disponible al registre del disc cada <n> megabytes (per defecte: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Com d'exhaustiva és la verificació de blocs de -checkblocks is (0-4, per defecte: 3)</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> </message> @@ -2822,10 +2722,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Defineix el nombre de fils de verificació d'scripts (%u a %d, 0 = auto, <0 = deixa tants nuclis lliures, per defecte: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Defineix el límit de processadors quan està activada la generació (-1 = sense límit, per defecte: -1)</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>Aquesta és una versió de pre-llançament - utilitza-la sota la teva responsabilitat - No usar per a minería o aplicacions de compra-venda</translation> </message> @@ -2834,10 +2730,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>No es pot enllaçar %s a aquest ordinador. El Bitcoin Core probablement ja estigui executant-s'hi.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Utilitza un proxy SOCKS5 apart per arribar a iguals a través de serveis de Tor ocults (per defecte: -proxy)</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> @@ -2862,10 +2754,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(per defecte: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(per defecte: wallet.dat)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> pot ser:</translation> </message> @@ -2894,10 +2782,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Opcions de depuració/proves:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Inhabilia el mode segur (safemode), invalida un esdeveniment de mode segur real (per defecte: 0)</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> @@ -2934,66 +2818,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Error: El moneder està bloquejat, no és possible crear la transacció!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Error: error de sistema: </translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Ha fallat escoltar a qualsevol port. Feu servir -listen=0 si voleu fer això.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Ha fallat la lectura de la informació del bloc</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Ha fallat la lectura del bloc</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Ha fallat la sincronització de l'índex de blocs</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Ha fallat la escriptura de l'índex de blocs</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Ha fallat la escriptura de la informació de bloc</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Ha fallat l'escriptura del bloc</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Ha fallat l'escriptura de la informació de fitxer</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Ha fallat l'escriptura de la basse de dades de monedes</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Ha fallat l'escriptura de l'índex de transaccions</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Ha fallat el desfer de dades</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Força el mode segur (per defecte: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Genera monedes (per defecte: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Quants blocs s'han de confirmar a l'inici (per defecte: 288, 0 = tots)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Si no se subministra <category>, mostra tota la informació de depuració.</translation> </message> @@ -3014,10 +2842,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>No hi ha suficient descriptors de fitxers disponibles.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Posa davant de la sortida de depuració una marca horària (per defecte: 1)</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> </message> @@ -3030,22 +2854,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Defineix la mida màxim del bloc en bytes (per defecte: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Estableix el nombre de fils per atendre trucades RPC (per defecte: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Especifica un fitxer de moneder (dins del directori de dades)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Gasta el canvi sense confirmar en enviar transaccions (per defecte: 1)</translation> - </message> - <message> - <source>Stop running after importing blocks from disk (default: 0)</source> - <translation>Atura l'execució després d'importar blocs del disc (per defecte: 0)</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> @@ -3074,10 +2886,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Importa blocs de un fitxer blk000??.dat extern</translation> </message> <message> - <source>(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> - <translation>(per defecte: 1, 1 = mantingues les metadades de les tx, p. ex., el propietari del compte i la informació de sol·licitud de pagament, 2 = descarta les metadades de tx) </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>Permet les connexions JSON-RPC d'una font específica. Vàlid per a <ip> són una IP individual (p. ex., 1.2.3.4), una xarxa / màscara de xarxa (p. ex., 1.2.3.4/255.255.255.0) o una xarxa/CIDR (p. ex., 1.2.3.4/24). Es pot especificar aquesta opció moltes vegades</translation> </message> @@ -3098,10 +2906,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> - <translation>Distribuït sota la llicència de programari MIT/X11. Vegeu el fitxer acompanyant COPYING o <http://www.opensource.org/licenses/mit-license.php>.</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> @@ -3110,10 +2914,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Error: s'ha trobat un argument no permès de -socks. Ja no es pot definir més la versió de SOCKS, només s'accepten els proxies de SOCKS5.ç</translation> </message> <message> - <source>Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)</source> - <translation>Executa l'ordre quan una tx de xarxa gasta de nou una tx d'entrada del moneder (%s=torna a gastar TxID, %t=TxID del moneder)</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 l'ordre quan es rebi un avís rellevant o veiem una forquilla molt llarga (%s en cmd és reemplaçat per un missatge)</translation> </message> @@ -3126,14 +2926,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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 are confirmed on average within n blocks (default: 1)</source> - <translation>Si no s'ha definit paytxfee, inclou comissió suficient per tal que les transaccions siguin confirmades dins d'una mitja de n blocs (per defecte: 1)</translation> - </message> - <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Informació de la depuració de sortida (per defecte: 0, proporcionar <category> és opcional)</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> @@ -3150,18 +2942,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Avís: comproveu que la data i hora del vostre ordinador siguin correctes! Si el vostre rellotge no és correcte, el Bitcoin Core no funcionarà correctament.</translation> </message> <message> - <source>Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.</source> - <translation>Posa en la llista blanca els iguals que es connectin de la màscara de xarxa o ip donada. Es pot especificar moltes vegades.</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>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>Always query for peer addresses via DNS lookup (default: 0)</source> - <translation>Consulta sempre adreces d'iguals a través de consultes DNS (per defecte: 0)</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation> </message> @@ -3190,14 +2974,14 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Comissió en (BTC/kB) per afegir a les transaccions que envieu (per defecte: %s)</translation> </message> <message> - <source>Include IP addresses in debug output (default: 0)</source> - <translation>Inclou adreces IP en la sortida de depuració (per defecte: 0)</translation> - </message> - <message> <source>Information</source> <translation>&Informació</translation> </message> <message> + <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source> + <translation>Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està aturant.</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Import no vàlid per a -minrelaytxfee=<amount>: «%s»</translation> </message> @@ -3206,42 +2990,30 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Import no vàlid per a -mintxfee=<amount>: «%s»</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Mida límit de la memòria cau de signatura per a <n> entrades (per defecte: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Registra la prioritat de transacció i comissió per kB en minar blocs (per defecte: 0)</translation> + <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> + <translation>Import no vàlid per a -paytxfee=<amount>: «%s» (ha de ser com a mínim %s)</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Manté l'índex sencer de transaccions (per defecte: 0)</translation> + <source>Invalid netmask specified in -whitelist: '%s'</source> + <translation>S'ha especificat una màscara de xarxa no vàlida a -whitelist: «%s»</translation> </message> <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Mida màxima del buffer de recepció per a cada connexió, <n>*1000 bytes (default: 5000)</translation> + <source>Keep at most <n> unconnectable blocks in memory (default: %u)</source> + <translation>Manté com a màxim <n> blocs no connectables en memòria (per defecte: %u)</translation> </message> <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Mida màxima del buffer d'enviament per a cada connexió, <n>*1000 bytes (default: 5000)</translation> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>Cal especificar un port amb -whitebind: «%s»</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Només accepta cadenes de blocs que coincideixin amb els punts de prova (per defecte: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Només connecta als nodes de la xarxa <net> (IPv4, IPv6 o Tor)</translation> + <source>Node relay options:</source> + <translation>Opcions de transmissió del node:</translation> </message> <message> <source>Print block on startup, if found in block index</source> <translation>Imprimeix el block a l'inici, si es troba l'índex de blocs</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Imprimeix l'arbre de blocs a l'inici (per defecte: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Opcions RPC SSL: (veieu el wiki del Bitcoin per a instruccions de configuració de l'SSL)</translation> </message> @@ -3258,22 +3030,10 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Introdueix incertesa en 1 de cada <n> missatges de la xarxa</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Executa un fil per buidar el moneder periòdicament (per defecte: 1)</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>Set minimum block size in bytes (default: 0)</source> - <translation>Defineix una mida mínima de bloc en bytes (per defecte: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Defineix el senyal DB_PRIVATE en l'entorn db del moneder (per defecte: 1)</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> @@ -3286,12 +3046,8 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ha fallat la signatura de la transacció</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Especifica el temps limit per a un intent de connexió en mil·lisegons (per defecte: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Error de sistema: </translation> + <source>This is experimental software.</source> + <translation>Això és programari experimental.</translation> </message> <message> <source>Transaction amount too small</source> @@ -3306,8 +3062,8 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>La transacció és massa gran</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Utilitza UPnP per a mapejar els ports d'escolta (per defecte: 0)</translation> + <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> <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> @@ -3362,10 +3118,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Actualitza el moneder a l'últim format</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Defineix el límit de nombre de claus a <n> (per defecte: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Reescaneja la cadena de blocs en les transaccions de moneder perdudes</translation> </message> @@ -3374,14 +3126,6 @@ per exemple: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Utilitza OpenSSL (https) per a connexions JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Fitxer del certificat de servidor (per defecte: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Clau privada del servidor (per defecte: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Aquest misatge d'ajuda</translation> </message> diff --git a/src/qt/locale/bitcoin_cmn.ts b/src/qt/locale/bitcoin_cmn.ts index 3286f12698..09ff0acf02 100644 --- a/src/qt/locale/bitcoin_cmn.ts +++ b/src/qt/locale/bitcoin_cmn.ts @@ -1,4 +1,4 @@ -<TS language="cmn" version="2.1"> +<TS language="cmn" version="2.0"> <context> <name>AddressBookPage</name> </context> diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index 2aa017fdf8..bc2a2ef7b5 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> @@ -391,10 +391,6 @@ <translation>Panel s listy</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -435,10 +431,6 @@ <translation>Není dostupný žádný zdroj bloků...</translation> </message> <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Zpracováno %1 bloků transakční historie.</translation> - </message> - <message> <source>%1 and %2</source> <translation>%1 a %2</translation> </message> @@ -513,10 +505,6 @@ Adresa: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Volba adres v rámci ruční správy mincí</translation> - </message> - <message> <source>Quantity:</source> <translation>Počet:</translation> </message> @@ -565,10 +553,6 @@ Adresa: %4 <translation>Částka</translation> </message> <message> - <source>Address</source> - <translation>Adresa</translation> - </message> - <message> <source>Date</source> <translation>Datum</translation> </message> @@ -900,15 +884,7 @@ Adresa: %4 <source>Error</source> <translation>Chyba</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB volného místa</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(z potřebných %1 GB)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -943,14 +919,6 @@ Adresa: %4 <translation>&Hlavní</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Dobrovolný transakční poplatek za každý započatý kB dopomáhá k rychlému zpracování tvých transakcí. Většina transakcí má do 1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Platit &transakční poplatek</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> @@ -979,14 +947,6 @@ Adresa: %4 <translation>Přijímat příchozí spojení</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Připojí se do Bitcoinové sítě přes SOCKS proxy.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Připojit přes SOCKS proxy (výchozí proxy):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>IP adresa proxy (např. IPv4: 127.0.0.1/IPv6: ::1)</translation> </message> @@ -1150,10 +1110,6 @@ Adresa: %4 <translation>Zobrazené informace nemusí být aktuální. Tvá peněženka se automaticky sesynchronizuje s Bitcoinovou sítí, jakmile se s ní spojí. Zatím ale ještě není synchronizace dokončena.</translation> </message> <message> - <source>Wallet</source> - <translation>Peněženka</translation> - </message> - <message> <source>Watch-only:</source> <translation>Sledované:</translation> </message> @@ -1206,10 +1162,6 @@ Adresa: %4 <translation>Aktuální stav účtu sledovaných adres</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Poslední transakce</b></translation> - </message> - <message> <source>out of sync</source> <translation>nesynchronizováno</translation> </message> @@ -1469,10 +1421,6 @@ Adresa: %4 <translation>Služby</translation> </message> <message> - <source>Sync Node</source> - <translation>Synchronizační uzel</translation> - </message> - <message> <source>Starting Height</source> <translation>Prvotní výška</translation> </message> @@ -1601,14 +1549,6 @@ Adresa: %4 <translation>Ven</translation> </message> <message> - <source>Yes</source> - <translation>Ano</translation> - </message> - <message> - <source>No</source> - <translation>Ne</translation> - </message> - <message> <source>Unknown</source> <translation>Neznámá</translation> </message> @@ -2453,6 +2393,10 @@ Adresa: %4 <translation>Vytěženo</translation> </message> <message> + <source>watch-only</source> + <translation>sledovací</translation> + </message> + <message> <source>(n/a)</source> <translation>(n/a)</translation> </message> @@ -2679,26 +2623,10 @@ Adresa: %4 <translation>Možnosti:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Konfigurační soubor (výchozí: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>PID soubor (výchozí: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Adresář pro data</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Čekat na spojení na <portu> (výchozí: 8333 nebo testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Povolit nejvýše <n> protějšků (výchozí: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Připojit se k uzlu, získat adresy jeho protějšků a odpojit se</translation> </message> @@ -2707,18 +2635,6 @@ Adresa: %4 <translation>Specifikuj svou veřejnou adresu</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Práh pro odpojování zlobivých protějšků (výchozí: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Doba ve vteřinách, po kterou se nebudou moci zlobivé protějšky znovu připojit (výchozí: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Čekat na JSON RPC spojení na <portu> (výchozí: 8332 nebo testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Akceptovat příkazy z příkazové řádky a přes JSON-RPC</translation> </message> @@ -2759,18 +2675,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Akceptovatelné šifry (výchozí: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Poslouchat na zadané adrese. Pro zápis IPv6 adresy použij notaci [adresa]:port</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Kontinuálně omezovat bezpoplatkové transakce na <n>*1000 bajtů za minutu (výchozí: 15)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Smazat všechny transakce peněženky a při startu obnovit pouze relevantní části řetězce bloků pomocí -rescan</translation> </message> @@ -2791,14 +2699,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Promítnout databázovou aktivitu z paměťového prostoru do záznamu na disku každých <n> megabajtů (výchozí: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Jak moc důkladná má být verifikace bloků -checkblocks (0-4, výchozí: 3)</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> </message> @@ -2807,10 +2707,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Nastavení počtu vláken pro verifikaci skriptů (%u až %d, 0 = automaticky, <0 = nechat daný počet jader volný, výchozí: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Nastavit omezení procesoru pro zapnuté generování (-1 = bez omezení, výchozí: -1)</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>Tohle je testovací verze – používej ji jen na vlastní riziko, ale rozhodně ji nepoužívej k těžbě nebo pro obchodní aplikace</translation> </message> @@ -2819,10 +2715,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Nedaří se mi připojit na %s na tomhle počítači. Bitcoin Core už pravděpodobně jednou běží.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Použít samostatnou SOCKS5 proxy ke spojení s protějšky přes skryté služby v Toru (výchozí: -proxy)</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> @@ -2847,10 +2739,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(výchozí: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(výchozí: wallet.dat)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> může být:</translation> </message> @@ -2879,10 +2767,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Možnosti ladění/testování:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Vypnout bezpečný režim (safemode), překrýt skutečnou událost bezpečného režimu (výchozí: 0)</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> @@ -2919,66 +2803,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Chyba: Peněženka je zamčená, nemohu vytvořit transakci!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Chyba: systémová chyba: </translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Nepodařilo se naslouchat na žádném portu. Použij -listen=0, pokud to byl tvůj záměr.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Nepodařilo se přečíst informace o bloku</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Nepodařilo se přečíst blok</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Nepodařilo se sesynchronizovat index bloků</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Nepodařilo se zapsat index bloků</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Nepodařilo se zapsat informace o bloku</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Nepodařilo se zapsat blok</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Nepodařilo se zapsat informace o souboru</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Selhal zápis do databáze mincí</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Nepodařilo se zapsat index transakcí</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Nepodařilo se zapsat data o vracení změn</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Vynutit bezpečný mód (výchozí: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Generovat mince (výchozí: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Kolik bloků při startu zkontrolovat (výchozí: 288, 0 = všechny)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Pokud není <category> zadána, bude tisknout veškeré ladicí informace.</translation> </message> @@ -2999,10 +2827,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Je nedostatek deskriptorů souborů.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Připojit před ladicí výstup časové razítko (výchozí: 1)</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> </message> @@ -3015,22 +2839,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Nastavit maximální velikost bloku v bajtech (výchozí: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Nastavení počtu vláken pro servisní RPC volání (výchozí: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Udej název souboru s peněženkou (v rámci datového adresáře)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Utrácet i ještě nepotvrzené drobné při posílání transakcí (výchozí: 1)</translation> - </message> - <message> - <source>Stop running after importing blocks from disk (default: 0)</source> - <translation>Ukončit se po importu bloků z disku (výchozí: 0)</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> @@ -3059,10 +2871,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Importovat bloky z externího souboru blk000??.dat</translation> </message> <message> - <source>(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> - <translation>(výchozí: 1, 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>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>Povolit JSON-RPC spojení ze specifikovaného zdroje. Platnou hodnotou <ip> je jednotlivá IP adresa (např. 1.2.3.4), síť/maska (např. 1.2.3.4/255.255.255.0) nebo síť/CIDR (např. 1.2.3.4/24). Tuto volbu lze použít i vícekrát</translation> </message> @@ -3087,10 +2895,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> - <translation>Šířen pod licencí MIT/X11, viz přiložený soubor COPYING nebo <http://www.opensource.org/licenses/mit-license.php>.</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> @@ -3099,10 +2903,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Chyba: Byl použit nepodporovaný argument -socks. Nastavení verze SOCKS už není možné, podporovány jsou pouze SOCKS5 proxy.</translation> </message> <message> - <source>Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)</source> - <translation>Spustit příkaz, když nějaká transakce na síti znovu utrácí vstup transakce této peněženky (%s=TxID cizí transakce, %t=TxID transakce peněženky)</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>Spustit příkaz, když přijde relevantní upozornění nebo když dojde k opravdu dlouhému rozštěpení řetezce bloků (%s se v příkazu nahradí zprávou)</translation> </message> @@ -3115,14 +2915,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Poplatky (v BTC/Kb) menší než tato hodnota jsou považovány za nulové pro účely vytváření transakcí (výchozí: %s)</translation> </message> <message> - <source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: 1)</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í: 1)</translation> - </message> - <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Tisknout ladicí informace (výchozí: 0, zadání <category> je volitelné)</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> @@ -3139,18 +2931,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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> <message> - <source>Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.</source> - <translation>Umístit na bílou listinu protějšky připojující se z dané podsítě či ip. Lze zadat i vícekrát.</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>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>Always query for peer addresses via DNS lookup (default: 0)</source> - <translation>Vždy získávat adresy dalších protějšků přes DNS (výchozí: 0)</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Nemohu přeložit -whitebind adresu: '%s'</translation> </message> @@ -3179,10 +2963,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Poplatek (v BTC/kB), který se přidá ke každé odeslané transakci (výchozí: %s)</translation> </message> <message> - <source>Include IP addresses in debug output (default: 0)</source> - <translation>Zaznamenávat do ladicích výstupů i IP adresy (výchozí: 0)</translation> - </message> - <message> <source>Information</source> <translation>Informace</translation> </message> @@ -3211,26 +2991,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Držet v paměti nejvýše <n> nespojitelných bloků (výchozí: %u)</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Omezit velikost vyrovnávací paměti pro podpisy na <n> položek (výchozí: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Zaznamenávat během těžení bloků prioritu transakce a poplatek za kB (výchozí: 0)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Spravovat úplný index transakcí (výchozí: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maximální velikost přijímacího bufferu pro každé spojení, <n>*1000 bajtů (výchozí: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maximální velikost odesílacího bufferu pro každé spojení, <n>*1000 bajtů (výchozí: 1000)</translation> - </message> - <message> <source>Need to specify a port with -whitebind: '%s'</source> <translation>V rámci -whitebind je třeba specifikovat i port: '%s'</translation> </message> @@ -3239,22 +2999,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Možnosti přeposílání:</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Uznávat pouze řetězec bloků, který odpovídá vnitřním kontrolním bodům (výchozí: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Připojit se pouze k uzlům v <net> síti (IPv4, IPv6 nebo Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>Vypsat při startu blok,pokud se nachází v indexu bloků</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Vypsat při startu strom bloků (výchozí: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Možnosti SSL pro RPC: (viz instrukce nastavení SSL na Bitcoin Wiki)</translation> </message> @@ -3271,30 +3019,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Náhodně pozměňovat jednu z každých <n> síťových zpráv</translation> </message> <message> - <source>Relay and mine data carrier transactions (default: 1)</source> - <translation>Přeposílat a těžit transakce nesoucí data (výchozí: 1)</translation> - </message> - <message> - <source>Relay non-P2SH multisig (default: 1)</source> - <translation>Přeposílat ne-P2SH multisig (výchozí: 1)</translation> - </message> - <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Spustit vlákno pročišťující periodicky peněženku (výchozí: 1)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Posílat stopovací/ladicí informace do konzole místo do souboru debug.log</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Nastavit minimální velikost bloku v bajtech (výchozí: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Nastavit příznak DB_PRIVATE v databázovém prostředí peněženky (výchozí: 1)</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> @@ -3307,14 +3035,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Nepodařilo se podepsat transakci</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Zadej časový limit spojení v milisekundách (výchozí: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Systémová chyba: </translation> - </message> - <message> <source>This is experimental software.</source> <translation>Tohle je experimentální program.</translation> </message> @@ -3335,10 +3055,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Nedaří se mi připojit na %s na tomhle počítači (operace bind vrátila chybu %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Použít UPnP k namapování naslouchacího portu (výchozí: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Použít UPnP k namapování naslouchacího portu (výchozí: 1, pokud naslouchá)</translation> </message> @@ -3391,10 +3107,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Převést peněženku na nejnovější formát</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Nastavit zásobník klíčů na velikost <n> (výchozí: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Přeskenovat řetězec bloků na chybějící transakce tvé pěněženky</translation> </message> @@ -3403,14 +3115,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Použít OpenSSL (https) pro JSON-RPC spojení</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Soubor se serverovým certifikátem (výchozí: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Soubor se serverovým soukromým klíčem (výchozí: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Tato nápověda</translation> </message> diff --git a/src/qt/locale/bitcoin_cy.ts b/src/qt/locale/bitcoin_cy.ts index 3380733c63..c68fc274f3 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> @@ -155,10 +155,6 @@ <translation>Bar offer tabiau</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Error</source> <translation>Gwall</translation> </message> @@ -201,10 +197,6 @@ <context> <name>CoinControlDialog</name> <message> - <source>Address</source> - <translation>Cyfeiriad</translation> - </message> - <message> <source>Date</source> <translation>Dyddiad</translation> </message> @@ -285,10 +277,6 @@ <source>Form</source> <translation>Ffurflen</translation> </message> - <message> - <source><b>Recent transactions</b></source> - <translation><b>Trafodion diweddar</b></translation> - </message> </context> <context> <name>PaymentServer</name> diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index f292766ec8..f733591098 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> @@ -11,7 +11,7 @@ </message> <message> <source>&New</source> - <translation>Ny</translation> + <translation>&Ny</translation> </message> <message> <source>Copy the currently selected address to the system clipboard</source> @@ -19,15 +19,15 @@ </message> <message> <source>&Copy</source> - <translation>Kopiér</translation> + <translation>&Kopiér</translation> </message> <message> <source>C&lose</source> - <translation>Luk</translation> + <translation>&Luk</translation> </message> <message> <source>&Copy Address</source> - <translation>Kopiér adresse</translation> + <translation>&Kopiér adresse</translation> </message> <message> <source>Delete the currently selected address from the list</source> @@ -39,11 +39,11 @@ </message> <message> <source>&Export</source> - <translation>Eksportér</translation> + <translation>&Eksportér</translation> </message> <message> <source>&Delete</source> - <translation>Slet</translation> + <translation>&Slet</translation> </message> <message> <source>Choose the address to send coins to</source> @@ -55,7 +55,7 @@ </message> <message> <source>C&hoose</source> - <translation>Vælg</translation> + <translation>&Vælg</translation> </message> <message> <source>Sending addresses</source> @@ -75,11 +75,11 @@ </message> <message> <source>Copy &Label</source> - <translation>Kopiér mærkat</translation> + <translation>Kopiér &mærkat</translation> </message> <message> <source>&Edit</source> - <translation>Redigér</translation> + <translation>&Redigér</translation> </message> <message> <source>Export Address List</source> @@ -224,7 +224,7 @@ <name>BitcoinGUI</name> <message> <source>Sign &message...</source> - <translation>Underskriv besked …</translation> + <translation>Underskriv &besked …</translation> </message> <message> <source>Synchronizing with network...</source> @@ -232,7 +232,7 @@ </message> <message> <source>&Overview</source> - <translation>Oversigt</translation> + <translation>&Oversigt</translation> </message> <message> <source>Node</source> @@ -244,7 +244,7 @@ </message> <message> <source>&Transactions</source> - <translation>Transaktioner</translation> + <translation>&Transaktioner</translation> </message> <message> <source>Browse transaction history</source> @@ -252,7 +252,7 @@ </message> <message> <source>E&xit</source> - <translation>Luk</translation> + <translation>&Luk</translation> </message> <message> <source>Quit application</source> @@ -260,7 +260,7 @@ </message> <message> <source>About &Qt</source> - <translation>Om Qt</translation> + <translation>Om &Qt</translation> </message> <message> <source>Show information about Qt</source> @@ -268,31 +268,31 @@ </message> <message> <source>&Options...</source> - <translation>Indstillinger …</translation> + <translation>&Indstillinger …</translation> </message> <message> <source>&Encrypt Wallet...</source> - <translation>Kryptér tegnebog …</translation> + <translation>&Kryptér tegnebog …</translation> </message> <message> <source>&Backup Wallet...</source> - <translation>Sikkerhedskopiér tegnebog …</translation> + <translation>&Sikkerhedskopiér tegnebog …</translation> </message> <message> <source>&Change Passphrase...</source> - <translation>Skift adgangskode …</translation> + <translation>&Skift adgangskode …</translation> </message> <message> <source>&Sending addresses...</source> - <translation>Afsendelsesadresser …</translation> + <translation>&Afsendelsesadresser …</translation> </message> <message> <source>&Receiving addresses...</source> - <translation>Modtagelsesadresser …</translation> + <translation>&Modtagelsesadresser …</translation> </message> <message> <source>Open &URI...</source> - <translation>Åbn URI …</translation> + <translation>&Åbn URI …</translation> </message> <message> <source>Bitcoin Core client</source> @@ -324,7 +324,7 @@ </message> <message> <source>&Debug window</source> - <translation>Fejlsøgningsvindue</translation> + <translation>&Fejlsøgningsvindue</translation> </message> <message> <source>Open debugging and diagnostic console</source> @@ -332,7 +332,7 @@ </message> <message> <source>&Verify message...</source> - <translation>Verificér besked …</translation> + <translation>&Verificér besked …</translation> </message> <message> <source>Bitcoin</source> @@ -344,11 +344,11 @@ </message> <message> <source>&Send</source> - <translation>Send</translation> + <translation>&Send</translation> </message> <message> <source>&Receive</source> - <translation>Modtag</translation> + <translation>&Modtag</translation> </message> <message> <source>Show information about Bitcoin Core</source> @@ -356,7 +356,7 @@ </message> <message> <source>&Show / Hide</source> - <translation>Vis / skjul</translation> + <translation>&Vis / skjul</translation> </message> <message> <source>Show or hide the main Window</source> @@ -376,25 +376,21 @@ </message> <message> <source>&File</source> - <translation>Fil</translation> + <translation>&Fil</translation> </message> <message> <source>&Settings</source> - <translation>Opsætning</translation> + <translation>&Opsætning</translation> </message> <message> <source>&Help</source> - <translation>Hjælp</translation> + <translation>&Hjælp</translation> </message> <message> <source>Tabs toolbar</source> <translation>Faneværktøjslinje</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnetværk]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -404,7 +400,7 @@ </message> <message> <source>&About Bitcoin Core</source> - <translation>Om Bitcoin Core</translation> + <translation>&Om Bitcoin Core</translation> </message> <message> <source>Show the list of used sending addresses and labels</source> @@ -420,7 +416,7 @@ </message> <message> <source>&Command-line options</source> - <translation>Tilvalg for kommandolinje</translation> + <translation>Tilvalg for &kommandolinje</translation> </message> <message> <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> @@ -434,10 +430,6 @@ <source>No block source available...</source> <translation>Ingen blokkilde tilgængelig …</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Behandlet %1 blokke af transaktionshistorikken.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n time</numerusform><numerusform>%n timer</numerusform></translation> @@ -486,6 +478,10 @@ <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> @@ -529,8 +525,8 @@ Adresse: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Adressevalg for coin-styring</translation> + <source>Coin Selection</source> + <translation>Coin-styring</translation> </message> <message> <source>Quantity:</source> @@ -581,8 +577,12 @@ Adresse: %4 <translation>Beløb</translation> </message> <message> - <source>Address</source> - <translation>Adresse</translation> + <source>Received with label</source> + <translation>Modtaget med mærke</translation> + </message> + <message> + <source>Received with address</source> + <translation>Modtaget med adresse</translation> </message> <message> <source>Date</source> @@ -753,7 +753,7 @@ Adresse: %4 </message> <message> <source>&Label</source> - <translation>Mærkat</translation> + <translation>&Mærkat</translation> </message> <message> <source>The label associated with this address list entry</source> @@ -765,7 +765,7 @@ Adresse: %4 </message> <message> <source>&Address</source> - <translation>Adresse</translation> + <translation>&Adresse</translation> </message> <message> <source>New receiving address</source> @@ -916,15 +916,11 @@ Adresse: %4 <source>Error</source> <translation>Fejl</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB fri plads tilgængelig</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(ud af %1 GB behøvet)</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB fri plads tilgængelig</numerusform><numerusform>%n GB fri plads tilgængelig</numerusform></translation> </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -956,15 +952,7 @@ Adresse: %4 </message> <message> <source>&Main</source> - <translation>Generelt</translation> - </message> - <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Valgfrit transaktionsgebyr pr. kB, der hjælper dine transaktioner med at blive behandlet hurtigt. De fleste transaktioner er på 1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Betal transaktionsgebyr</translation> + <translation>&Generelt</translation> </message> <message> <source>Automatically start Bitcoin after logging in to the system.</source> @@ -972,11 +960,11 @@ Adresse: %4 </message> <message> <source>&Start Bitcoin on system login</source> - <translation>Start Bitcoin ved systemlogin</translation> + <translation>&Start Bitcoin ved systemlogin</translation> </message> <message> <source>Size of &database cache</source> - <translation>Størrelsen på databasens cache</translation> + <translation>Størrelsen på &databasens cache</translation> </message> <message> <source>MB</source> @@ -984,7 +972,7 @@ Adresse: %4 </message> <message> <source>Number of script &verification threads</source> - <translation>Antallet af scriptverificeringstråde</translation> + <translation>Antallet af script&verificeringstråde</translation> </message> <message> <source>Accept connections from outside</source> @@ -995,14 +983,6 @@ Adresse: %4 <translation>Tillad indkommende forbindelser</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Forbind til Bitcoin-netværket gennem en SOCKS-proxy.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>Forbind gennem SOCKS-proxy (standard-proxy):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>IP-adresse for proxyen (fx IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1024,11 +1004,11 @@ Adresse: %4 </message> <message> <source>&Reset Options</source> - <translation>Nulstil indstillinger</translation> + <translation>&Nulstil indstillinger</translation> </message> <message> <source>&Network</source> - <translation>Netværk</translation> + <translation>&Netværk</translation> </message> <message> <source>(0 = auto, <0 = leave that many cores free)</source> @@ -1036,7 +1016,7 @@ Adresse: %4 </message> <message> <source>W&allet</source> - <translation>Tegnebog</translation> + <translation>&Tegnebog</translation> </message> <message> <source>Expert</source> @@ -1044,7 +1024,7 @@ Adresse: %4 </message> <message> <source>Enable coin &control features</source> - <translation>Slå egenskaber for coin-styring til</translation> + <translation>Slå egenskaber for &coin-styring til</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> @@ -1052,7 +1032,7 @@ Adresse: %4 </message> <message> <source>&Spend unconfirmed change</source> - <translation>Brug ubekræftede byttepenge</translation> + <translation>&Brug ubekræftede byttepenge</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> @@ -1060,15 +1040,23 @@ Adresse: %4 </message> <message> <source>Map port using &UPnP</source> - <translation>Konfigurér port vha. UPnP</translation> + <translation>Konfigurér port vha. &UPnP</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Forbind til Bitcoin-netværket gennem en SOCKS5-proxy.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Forbind gennem SOCKS5-proxy (standard-proxy):</translation> </message> <message> <source>Proxy &IP:</source> - <translation>Proxy-IP:</translation> + <translation>Proxy-&IP:</translation> </message> <message> <source>&Port:</source> - <translation>Port:</translation> + <translation>&Port:</translation> </message> <message> <source>Port of the proxy (e.g. 9050)</source> @@ -1076,7 +1064,7 @@ Adresse: %4 </message> <message> <source>&Window</source> - <translation>Vindue</translation> + <translation>&Vindue</translation> </message> <message> <source>Show only a tray icon after minimizing the window.</source> @@ -1084,7 +1072,7 @@ Adresse: %4 </message> <message> <source>&Minimize to the tray instead of the taskbar</source> - <translation>Minimér til statusfeltet i stedet for proceslinjen</translation> + <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> @@ -1092,15 +1080,15 @@ Adresse: %4 </message> <message> <source>M&inimize on close</source> - <translation>Minimér ved lukning</translation> + <translation>M&inimér ved lukning</translation> </message> <message> <source>&Display</source> - <translation>Visning</translation> + <translation>&Visning</translation> </message> <message> <source>User Interface &language:</source> - <translation>Sprog for brugergrænseflade:</translation> + <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> @@ -1108,7 +1096,7 @@ Adresse: %4 </message> <message> <source>&Unit to show amounts in:</source> - <translation>Enhed at vise beløb i:</translation> + <translation>&Enhed at vise beløb i:</translation> </message> <message> <source>Choose the default subdivision unit to show in the interface and when sending coins.</source> @@ -1120,11 +1108,11 @@ Adresse: %4 </message> <message> <source>&OK</source> - <translation>OK</translation> + <translation>&O.k.</translation> </message> <message> <source>&Cancel</source> - <translation>Annullér</translation> + <translation>&Annullér</translation> </message> <message> <source>default</source> @@ -1166,10 +1154,6 @@ Adresse: %4 <translation>Den viste information kan være forældet. Din tegnebog synkroniserer automatisk med Bitcoin-netværket, når en forbindelse etableres, men denne proces er ikke gennemført endnu.</translation> </message> <message> - <source>Wallet</source> - <translation>Tegnebog</translation> - </message> - <message> <source>Watch-only:</source> <translation>Kigge:</translation> </message> @@ -1198,6 +1182,10 @@ Adresse: %4 <translation>Minet saldo, som endnu ikke er modnet</translation> </message> <message> + <source>Balances</source> + <translation>Saldi:</translation> + </message> + <message> <source>Total:</source> <translation>Total:</translation> </message> @@ -1210,6 +1198,14 @@ Adresse: %4 <translation>Din nuværende saldo på kigge-adresser</translation> </message> <message> + <source>Spendable:</source> + <translation>Spendérbar:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Nylige transaktioner</translation> + </message> + <message> <source>Unconfirmed transactions to watch-only addresses</source> <translation>Ubekræftede transaktioner til kigge-adresser</translation> </message> @@ -1222,10 +1218,6 @@ Adresse: %4 <translation>Nuværende totalsaldo på kigge-adresser</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Nyeste transaktioner</b></translation> - </message> - <message> <source>out of sync</source> <translation>ikke synkroniseret</translation> </message> @@ -1379,11 +1371,11 @@ Adresse: %4 <name>QRImageWidget</name> <message> <source>&Save Image...</source> - <translation>Gem billede …</translation> + <translation>&Gem billede …</translation> </message> <message> <source>&Copy Image</source> - <translation>Kopiér foto</translation> + <translation>&Kopiér foto</translation> </message> <message> <source>Save QR Code</source> @@ -1410,7 +1402,7 @@ Adresse: %4 </message> <message> <source>&Information</source> - <translation>Information</translation> + <translation>&Information</translation> </message> <message> <source>Debug window</source> @@ -1462,7 +1454,7 @@ Adresse: %4 </message> <message> <source>&Peers</source> - <translation>Andre knuder</translation> + <translation>Andre &knuder</translation> </message> <message> <source>Select a peer to view detailed information.</source> @@ -1485,10 +1477,6 @@ Adresse: %4 <translation>Tjenester</translation> </message> <message> - <source>Sync Node</source> - <translation>Synkroniseringsknude</translation> - </message> - <message> <source>Starting Height</source> <translation>Starthøjde</translation> </message> @@ -1530,19 +1518,19 @@ Adresse: %4 </message> <message> <source>&Open</source> - <translation>Åbn</translation> + <translation>&Åbn</translation> </message> <message> <source>&Console</source> - <translation>Konsol</translation> + <translation>&Konsol</translation> </message> <message> <source>&Network Traffic</source> - <translation>Netværkstrafik</translation> + <translation>&Netværkstrafik</translation> </message> <message> <source>&Clear</source> - <translation>Ryd</translation> + <translation>&Ryd</translation> </message> <message> <source>Totals</source> @@ -1617,14 +1605,6 @@ Adresse: %4 <translation>Udgående</translation> </message> <message> - <source>Yes</source> - <translation>Ja</translation> - </message> - <message> - <source>No</source> - <translation>Nej</translation> - </message> - <message> <source>Unknown</source> <translation>Ukendt</translation> </message> @@ -1637,15 +1617,15 @@ Adresse: %4 <name>ReceiveCoinsDialog</name> <message> <source>&Amount:</source> - <translation>Beløb:</translation> + <translation>&Beløb:</translation> </message> <message> <source>&Label:</source> - <translation>Mærkat:</translation> + <translation>&Mærkat:</translation> </message> <message> <source>&Message:</source> - <translation>Besked:</translation> + <translation>&Besked:</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> @@ -1653,7 +1633,7 @@ Adresse: %4 </message> <message> <source>R&euse an existing receiving address (not recommended)</source> - <translation>Genbrug en eksisterende modtagelsesadresse (anbefales ikke)</translation> + <translation>&Genbrug en eksisterende modtagelsesadresse (anbefales ikke)</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> @@ -1685,7 +1665,7 @@ Adresse: %4 </message> <message> <source>&Request payment</source> - <translation>Anmod om betaling</translation> + <translation>&Anmod om betaling</translation> </message> <message> <source>Show the selected request (does the same as double clicking an entry)</source> @@ -1724,15 +1704,15 @@ Adresse: %4 </message> <message> <source>Copy &URI</source> - <translation>Kopiér URI</translation> + <translation>Kopiér &URI</translation> </message> <message> <source>Copy &Address</source> - <translation>Kopiér adresse</translation> + <translation>Kopiér &adresse</translation> </message> <message> <source>&Save Image...</source> - <translation>Gem billede …</translation> + <translation>&Gem billede …</translation> </message> <message> <source>Request payment to %1</source> @@ -1861,12 +1841,84 @@ Adresse: %4 <translation>Tilpasset byttepengeadresse</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Transaktionsgebyr:</translation> + </message> + <message> + <source>Choose...</source> + <translation>Vælg …</translation> + </message> + <message> + <source>collapse fee-settings</source> + <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> + <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>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>total at least</source> + <translation>total mindst</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>Det er helt fint kun at betale det minimale gebyr, så længe den totale transaktionsvolumen er mindre end den plads, der er tilgængelig i blokkene. Men vær opmærksom på, at dette kan ende ud i transaktioner, der aldrig bliver bekræftet, når der bliver større forespørgsel efter bitcoin-transaktioner, end hvad netværket kan bearbejde.</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(læs værktøjstippet)</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Anbefalet:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Brugertilpasset:</translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation>(Smart-gebyr er ikke initialiseret endnu. Dette tager typisk nogle få blokke …)</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Bekræftelsestid:</translation> + </message> + <message> + <source>normal</source> + <translation>normal</translation> + </message> + <message> + <source>fast</source> + <translation>hurtig</translation> + </message> + <message> + <source>Send as zero-fee transaction if possible</source> + <translation>Send som nul-gebyr-transaktion hvis muligt</translation> + </message> + <message> + <source>(confirmation may take longer)</source> + <translation>(bekræftelse kan tage længere)</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Send til flere modtagere på en gang</translation> </message> <message> <source>Add &Recipient</source> - <translation>Tilføj modtager</translation> + <translation>Tilføj &modtager</translation> </message> <message> <source>Clear all fields of the form.</source> @@ -1878,7 +1930,7 @@ Adresse: %4 </message> <message> <source>Clear &All</source> - <translation>Ryd alle</translation> + <translation>Ryd &alle</translation> </message> <message> <source>Balance:</source> @@ -1890,7 +1942,7 @@ Adresse: %4 </message> <message> <source>S&end</source> - <translation>Afsend</translation> + <translation>&Afsend</translation> </message> <message> <source>Confirm send coins</source> @@ -1965,6 +2017,18 @@ 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> + </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> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Advarsel: Ugyldig Bitcoin-adresse</translation> </message> @@ -1993,11 +2057,11 @@ Adresse: %4 <name>SendCoinsEntry</name> <message> <source>A&mount:</source> - <translation>Beløb:</translation> + <translation>&Beløb:</translation> </message> <message> <source>Pay &To:</source> - <translation>Betal til:</translation> + <translation>Betal &til:</translation> </message> <message> <source>Enter a label for this address to add it to your address book</source> @@ -2005,7 +2069,7 @@ Adresse: %4 </message> <message> <source>&Label:</source> - <translation>Mærkat:</translation> + <translation>&Mærkat:</translation> </message> <message> <source>Choose previously used address</source> @@ -2083,7 +2147,7 @@ Adresse: %4 </message> <message> <source>&Sign Message</source> - <translation>Underskriv besked</translation> + <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> @@ -2127,7 +2191,7 @@ Adresse: %4 </message> <message> <source>Sign &Message</source> - <translation>Underskriv besked</translation> + <translation>Underskriv &besked</translation> </message> <message> <source>Reset all sign message fields</source> @@ -2135,11 +2199,11 @@ Adresse: %4 </message> <message> <source>Clear &All</source> - <translation>Ryd alle</translation> + <translation>Ryd &alle</translation> </message> <message> <source>&Verify Message</source> - <translation>Verificér besked</translation> + <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> @@ -2155,7 +2219,7 @@ Adresse: %4 </message> <message> <source>Verify &Message</source> - <translation>Verificér besked</translation> + <translation>Verificér &besked</translation> </message> <message> <source>Reset all verify message fields</source> @@ -2473,6 +2537,10 @@ Adresse: %4 <translation>Minet</translation> </message> <message> + <source>watch-only</source> + <translation>kigge</translation> + </message> + <message> <source>(n/a)</source> <translation>(n/a)</translation> </message> @@ -2489,6 +2557,10 @@ Adresse: %4 <translation>Transaktionstype.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <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> </message> @@ -2584,6 +2656,10 @@ Adresse: %4 <translation>Historik for eksport af transaktioner</translation> </message> <message> + <source>Watch-only</source> + <translation>Kigge</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Eksport mislykkedes</translation> </message> @@ -2661,7 +2737,7 @@ Adresse: %4 <name>WalletView</name> <message> <source>&Export</source> - <translation>Eksportér</translation> + <translation>&Eksportér</translation> </message> <message> <source>Export the data in the current tab to a file</source> @@ -2699,26 +2775,10 @@ Adresse: %4 <translation>Indstillinger:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Angiv konfigurationsfil (standard: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Angiv pid-fil (default: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Angiv datamappe</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Lyt til forbindelser på <port> (standard: 8333 eller testnetværk: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Oprethold højest <n> forbindelser til andre knuder i netværket (standard: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Forbind til en knude for at modtage adresser på andre knuder, og afbryd derefter</translation> </message> @@ -2727,18 +2787,6 @@ Adresse: %4 <translation>Angiv din egen offentlige adresse</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Grænse for frakobling fra andre knuder, der opfører sig dårligt (standard: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Antal sekunder, som andre knuder der opfører sig dårligt, skal vente før reetablering af forbindelse (standard: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Lyt til JSON-RPC-forbindelser på <port> (standard: 8332 eller testnetværk: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Acceptér kommandolinje- og JSON-RPC-kommandoer</translation> </message> @@ -2779,22 +2827,18 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Accepterede krypteringer (standard: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Tildel til den givne adresse og lyt altid på den. Brug [vært]:port-notation for IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Rate-begræns kontinuerligt frie transaktioner til <n>*1000 byte i minuttet (standard:15)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Slet alle transaktioner i tegnebogen og genskab kun disse dele af blokkæden gennem -rescan under opstart</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>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> @@ -2811,14 +2855,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Udfør kommando, når en transaktion i tegnebogen ændres (%s i kommandoen erstattes med TxID)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Flyt databaseaktivitet fra hukommelsespulje til disklog hver <n> megabytes (standard: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Hvor gennemarbejdet blokverificeringen for -checkblocks er (0-4; standard: 3)</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> </message> @@ -2827,10 +2863,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Sæt antallet af scriptverificeringstråde (%u til %d, 0 = auto, <0 = efterlad det antal kernet fri, standard: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Sæt processorbegrænsning for når generering er slået til (-1 = ubegrænset, standard: -1)</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>Dette er en foreløbig testudgivelse - brug på eget ansvar - brug ikke til udvinding eller handelsprogrammer</translation> </message> @@ -2839,10 +2871,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ikke i stand til at tildele til %s på denne computer. Bitcoin Core kører sansynligvis allerede.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Brug separat SOCS5-proxy for at nå andre knuder via tjenester skjult med Tor (standard: -proxy)</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> @@ -2863,12 +2891,12 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Advarsel: wallet.dat ødelagt, data reddet! Oprindelig wallet.dat gemt som wallet.{timestamp}.bak i %s; hvis din saldo eller dine transaktioner er forkert, bør du genskabe fra en sikkerhedskopi.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(standard: 1)</translation> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Sæt andre knuder, der forbinder fra den angivne netmaske eller IP, på hvidliste. Kan angives flere gange.</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(standard: wallet.dat)</translation> + <source>(default: 1)</source> + <translation>(standard: 1)</translation> </message> <message> <source><category> can be:</source> @@ -2899,10 +2927,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Tilvalg for fejlfinding/test:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Slå sikker tilstand fra, tilsidesæt hændelser fra sikker tilstand (standard: 0)</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> @@ -2931,6 +2955,10 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Åbning af blokdatabase mislykkedes</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Fejl: En fatal intern fejl opstod; se debug.log for detaljer</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Fejl: Mangel på ledig diskplads!</translation> </message> @@ -2939,66 +2967,10 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Fejl: Tegnebog låst, kan ikke oprette transaktion!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Fejl: systemfejl: </translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Lytning på enhver port mislykkedes. Brug -listen=0, hvis du ønsker dette.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Læsning af blokinformation mislykkedes</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Læsning af blok mislykkedes</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Synkronisering af blokindeks mislykkedes</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Skrivning af blokindeks mislykkedes</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Skrivning af blokinformation mislykkedes</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Skrivning af blok mislykkedes</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Skriving af filinformation mislykkedes</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Skrivning af bitcoin-database mislykkedes</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Skrivning af transaktionsindeks mislykkedes</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Skrivning af genskabelsesdata mislykkedes</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Gennemtving sikker tilstand (standard: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Generér bitcoins (standard: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Antal blokke som tjekkes ved opstart (standard: 288, 0=alle)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Hvis <kategori> ikke angives, udskriv al fejlsøgningsinformation.</translation> </message> @@ -3019,8 +2991,8 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>For få tilgængelige fildeskriptorer.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Føj tidsstempel foran fejlsøgningsoutput (standard: 1)</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <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> @@ -3035,26 +3007,18 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Sæt maksimum blokstørrelse i byte (standard: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Angiv antallet af tråde til at håndtere RPC-kald (standard: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Angiv tegnebogsfil (inden for datamappe)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Brug ubekræftede byttepenge under afsendelse af transaktioner (standard: 1)</translation> - </message> - <message> - <source>Stop running after importing blocks from disk (default: 0)</source> - <translation>Stop kørsel efter import af blokke fra disk (standard: 0)</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> + <message> <source>Verifying blocks...</source> <translation>Verificerer blokke …</translation> </message> @@ -3079,10 +3043,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Importerer blokke fra ekstern blk000??.dat fil</translation> </message> <message> - <source>(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> - <translation>(standard: 1, 1 = behold metadata for transaktion, fx kontoindehaver og information om betalingsanmodning, 2 = drop metadata for transaktion)</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>Tillad JSON-RPC-forbindelser fra angivet kilde. Gyldig for <ip> er en enkelt IP (fx 1.2.3.4), et netværk/netmaske (fx 1.2.3.4/255.255.255.0) eller et netværk/CIDR (fx 1.2.3.4/24). Dette tilvalg kan angives flere gange</translation> </message> @@ -3103,12 +3063,12 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Kan ikke opnå en lås på datamappe %s. Bitcoin Core kører sansynligvis allerede.</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> + <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>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> - <translation>Distribueret under MIT/X11-softwarelicensen. Se medfølgende fil COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation> + <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>Error: Listening for incoming connections failed (listen returned error %s)</source> @@ -3119,10 +3079,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Fejl: Ikke understøttet argument -socks blev fundet. Det er ikke muligt at angive SOCKS-version længere, da kun SOCKS5-proxier er understøttet.</translation> </message> <message> - <source>Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)</source> - <translation>Udfør kommando når en netværkstransaktion genspenderer input fra tegnebogstransaktion (%s=transaktions-ID fra genspendering, %t=transaktions-ID fra tegnebog)</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>Udfør kommando, når en relevant alarm modtages eller vi ser en virkelig lang udsplitning (%s i cmd erstattes af besked)</translation> </message> @@ -3135,12 +3091,8 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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 are confirmed on average within n blocks (default: 1)</source> - <translation>Hvis paytxfee ikke er angivet, inkludér da nok gebyr til at transaktioner gennemsnitligt bekræftes inden for n blokke (standard: 1)</translation> - </message> - <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Udskriv fejlsøgningsinformation (standard: 0, angivelse af <kategori> er valgfri)</translation> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>Maksimal størrelse på data i transaktioner til dataoverførsel, som vi videresender og miner (standard: %u)</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> @@ -3151,6 +3103,10 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Sæt maksimumstørrelse for højprioritet/lavgebyr-transaktioner i byte (standard: %d)</translation> </message> <message> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <translation>Sæt antaller af tråde for coin-generering, hvis aktiveret (-1 = alle kerner, standard: %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>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> @@ -3159,18 +3115,10 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Advarsel: Undersøg venligst at din computers dato og klokkeslet er korrekt indstillet! Hvis der er fejl i disse vil Bitcoin Core ikke fungere korrekt.</translation> </message> <message> - <source>Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.</source> - <translation>Sæt andre knuder, der forbinder fra den angivne netmaske eller ip, på hvidliste. Kan angives flere gange.</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>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>Always query for peer addresses via DNS lookup (default: 0)</source> - <translation>Forespørg altid adresser på andre knuder via DNS-opslag (default: 0)</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Kan ikke løse -whitebind adresse: "%s"</translation> </message> @@ -3199,10 +3147,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Gebyr (i BTC/kB) som skal føjes til transaktioner, du sender (standard: %s)</translation> </message> <message> - <source>Include IP addresses in debug output (default: 0)</source> - <translation>Inkludér IP-adresser i fejlretningsoutput (standard: 0)</translation> - </message> - <message> <source>Information</source> <translation>Information</translation> </message> @@ -3231,24 +3175,8 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Behold højest <n> uforbindelige blokke i hukommelsen (standard: %u)</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Begræns størrelsen på signaturcache til <n> indgange (standard: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Prioritet for transaktionslog og gebyr pr. kB under udvinding af blokke (standard: 0)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Vedligehold et komplet transaktionsindeks (standard: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maksimum for modtagelsesbuffer pr. forbindelse, <n>*1000 byte (standard: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maksimum for afsendelsesbuffer pr. forbindelse, <n>*1000 byte (standard: 1000)</translation> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Behold højest <n> uforbindelige transaktioner i hukommelsen (standard: %u)</translation> </message> <message> <source>Need to specify a port with -whitebind: '%s'</source> @@ -3259,22 +3187,10 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Videresendelsesvalgmuligheder for knude:</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Acceptér kun blokkæde, som matcher indbyggede kontrolposter (standard: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Tilslut kun til knuder i netværk <net> (IPv4, IPv6 eller Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>Udskriv blok under opstart, hvis den findes i blokindeks</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Udskriv bloktræ under startop (standard: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Tilvalg for RPC SSL: (se Bitcoin Wiki for instruktioner i SSL-opstart)</translation> </message> @@ -3291,28 +3207,12 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Slør tilfældigt 1 ud af hver <n> netværksbeskeder</translation> </message> <message> - <source>Relay and mine data carrier transactions (default: 1)</source> - <translation>Videresend og mine databærer-transaktioner (standard: 1)</translation> - </message> - <message> - <source>Relay non-P2SH multisig (default: 1)</source> - <translation>Videresend ikke-P2SH multisig (standard: 1)</translation> - </message> - <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Kør en tråd for at rydde tegnebog periodisk (standard: 1)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Send sporings-/fejlsøgningsinformation til konsollen i stedet for debug.log filen</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Angiv minimumsblokstørrelse i byte (standard: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Sætter DB_PRIVATE-flaget i tegnebogens db-miljø (standard: 1)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Send transaktioner som nul-gebyr-transaktioner hvis muligt (standard: %u)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> @@ -3327,14 +3227,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Underskrift af transaktion mislykkedes</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Angiv tilslutningstimeout i millisekunder (standard: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Systemfejl: </translation> - </message> - <message> <source>This is experimental software.</source> <translation>Dette er eksperimentelt software.</translation> </message> @@ -3355,10 +3247,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ikke i stand til at tildele til %s på denne computer (bind returnerede fejl %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Brug UPnP til at konfigurere den lyttende port (standard: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Brug UPnP til at konfigurere den lyttende port (standard: 1 under lytning)</translation> </message> @@ -3411,10 +3299,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Opgrader tegnebog til seneste format</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Angiv nøglepoolstørrelse til <n> (standard: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Gennemsøg blokkæden for manglende tegnebogstransaktioner</translation> </message> @@ -3423,14 +3307,6 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Brug OpenSSL (https) for JSON-RPC-forbindelser</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Servercertifikat-fil (standard: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Serverens private nøgle (standard: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Denne hjælpebesked</translation> </message> @@ -3447,14 +3323,180 @@ fx: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Fejl ved indlæsning af wallet.dat: Tegnebog ødelagt</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 = 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>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source> + <translation>Hvis paytxfee ikke er angivet, inkludér da nok gebyr til at transaktioner gennemsnitligt bekræftes inden for n blokke (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> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Antal sekunder, som knuder der opfører sig upassende, skal vente før reetablering (standard: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Udskriv fejlsøgningsinformation (standard: %u, angivelse af <kategori> er valgfri)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Brug separat SOCS5-proxy for at nå andre knuder via Tor skjulte tjenester (standard: %s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(standard: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Accepterede kodninger (standard: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <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> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Antal blokke som tjekkes ved opstart (standard: %u, 0 = alle)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Inkludér IP-adresser i fejlretningsoutput (standard: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <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> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Lyt efter forbindelser på <port> (standard: %u eller testnet: %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Oprethold højest <n> forbindelser til andre knuder (standard: %u)</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> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <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> + <message> + <source>Print block tree on startup (default: %u)</source> + <translation>Udskriv bloktræ under opstart (standard: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Videresend og udvind databærer-transaktioner (standard: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <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> + </message> + <message> + <source>Server private key (default: %s)</source> + <translation>Serverens private nøgle (standard: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Sæt nøglepuljestørrelse til <n> (standard: %u) +</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Angiv minimumsblokstørrelse i byte (standard: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <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> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Angiv tilslutningstimeout i millisekunder (minimum: 1, standard: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Angiv pid-fil (standard: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <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> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Ukendt netværk anført i -onlynet: "%s"</translation> </message> diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 667f0eb239..2804d2d665 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> @@ -391,10 +391,6 @@ <translation>Registerkartenleiste</translation> </message> <message> - <source>[testnet]</source> - <translation>[Testnetz]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -434,10 +430,6 @@ <source>No block source available...</source> <translation>Keine Blockquelle verfügbar...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>%1 Blöcke des Transaktionsverlaufs verarbeitet.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n Stunde</numerusform><numerusform>%n Stunden</numerusform></translation> @@ -528,8 +520,8 @@ Adresse: %4</translation> <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>"Coin Control"-Adressauswahl</translation> + <source>Coin Selection</source> + <translation>Münzauswahl ("Coin Control")</translation> </message> <message> <source>Quantity:</source> @@ -580,8 +572,12 @@ Adresse: %4</translation> <translation>Betrag</translation> </message> <message> - <source>Address</source> - <translation>Adresse</translation> + <source>Received with label</source> + <translation>Empfangen über Bezeichnung</translation> + </message> + <message> + <source>Received with address</source> + <translation>Empfangen über Adresse</translation> </message> <message> <source>Date</source> @@ -915,13 +911,13 @@ Adresse: %4</translation> <source>Error</source> <translation>Fehler</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB freier Speicherplatz verfügbar</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB freier Speicherplatz verfügbar</numerusform><numerusform>%n GB freier Speicherplatz verfügbar</numerusform></translation> </message> - <message> - <source>(of %1GB needed)</source> - <translation>(von benötigten %1GB)</translation> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(von benötigtem %n GB)</numerusform><numerusform>(von benötigten %n GB)</numerusform></translation> </message> </context> <context> @@ -958,14 +954,6 @@ Adresse: %4</translation> <translation>&Allgemein</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Optionale Transaktionsgebühr pro kB, die sicherstellt, dass Ihre Transaktionen schnell bearbeitet werden. Die meisten Transaktionen sind 1 kB groß.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Transaktions&gebühr bezahlen</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> @@ -994,14 +982,6 @@ Adresse: %4</translation> <translation>Erlaubt eingehende Verbindungen</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Über einen SOCKS-Proxy mit dem Bitcoin-Netzwerk verbinden.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>Über einen SOCKS-Proxy &verbinden (Standardproxy):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>IP-Adresse des Proxies (z.B. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1062,6 +1042,14 @@ Adresse: %4</translation> <translation>Portweiterleitung via &UPnP</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Über einen SOCKS5-Proxy mit dem Bitcoin-Netzwerk verbinden.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>Über einen SOCKS5-Proxy &verbinden (Standardproxy):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>Proxy-&IP:</translation> </message> @@ -1165,10 +1153,6 @@ Adresse: %4</translation> <translation>Die angezeigten Informationen sind möglicherweise nicht mehr aktuell. Ihre Wallet wird automatisch synchronisiert, nachdem eine Verbindung zum Bitcoin-Netzwerk hergestellt wurde. Dieser Prozess ist jedoch derzeit noch nicht abgeschlossen.</translation> </message> <message> - <source>Wallet</source> - <translation>Wallet</translation> - </message> - <message> <source>Watch-only:</source> <translation>Beobachtet:</translation> </message> @@ -1197,6 +1181,10 @@ Adresse: %4</translation> <translation>Erarbeiteter Betrag der noch nicht gereift ist</translation> </message> <message> + <source>Balances</source> + <translation>Kontostände</translation> + </message> + <message> <source>Total:</source> <translation>Gesamtbetrag:</translation> </message> @@ -1209,6 +1197,14 @@ Adresse: %4</translation> <translation>Ihr aktueller Kontostand beobachteter Adressen</translation> </message> <message> + <source>Spendable:</source> + <translation>Verfügbar:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Letzte Transaktionen</translation> + </message> + <message> <source>Unconfirmed transactions to watch-only addresses</source> <translation>Unbestätigte Transaktionen von beobachteten Adressen</translation> </message> @@ -1221,10 +1217,6 @@ Adresse: %4</translation> <translation>Aktueller Gesamtbetrag in beobachteten Adressen aus obigen Kategorien</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Letzte Transaktionen</b></translation> - </message> - <message> <source>out of sync</source> <translation>nicht synchron</translation> </message> @@ -1484,10 +1476,6 @@ Adresse: %4</translation> <translation>Dienste</translation> </message> <message> - <source>Sync Node</source> - <translation>Sync-Knoten</translation> - </message> - <message> <source>Starting Height</source> <translation>Start-Höhe</translation> </message> @@ -1616,14 +1604,6 @@ Adresse: %4</translation> <translation>ausgehend</translation> </message> <message> - <source>Yes</source> - <translation>Ja</translation> - </message> - <message> - <source>No</source> - <translation>Nein</translation> - </message> - <message> <source>Unknown</source> <translation>Unbekannt</translation> </message> @@ -1860,6 +1840,78 @@ Adresse: %4</translation> <translation>Benutzerdefinierte Wechselgeld-Adresse</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Transaktionsgebühr:</translation> + </message> + <message> + <source>Choose...</source> + <translation>Auswählen...</translation> + </message> + <message> + <source>collapse fee-settings</source> + <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> + <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>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>total at least</source> + <translation>Mindestbetrag</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>Nur die minimale Gebühr zu bezahlen ist so lange in Ordnung, wie weniger Transaktionsvolumen als Platz in den Blöcken vorhanden ist. Aber Vorsicht, diese Option kann dazu führen, dass Transaktionen nicht bestätigt werden, wenn mehr Bedarf an Bitcoin-Transaktionen besteht als das Netzwerk verarbeiten kann.</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(den Hinweistext lesen)</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Empfehlungen:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Benutzerdefiniert:</translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation>(Intelligente Gebührenlogik ist noch nicht verfügbar. Normalerweise dauert dies einige Blöcke lang...)</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Bestätigungszeit:</translation> + </message> + <message> + <source>normal</source> + <translation>normal</translation> + </message> + <message> + <source>fast</source> + <translation>schnell</translation> + </message> + <message> + <source>Send as zero-fee transaction if possible</source> + <translation>Wenn möglich als gebührenfreie Transaktion senden</translation> + </message> + <message> + <source>(confirmation may take longer)</source> + <translation>(Bestätigung kann länger dauern)</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>An mehrere Empfänger auf einmal überweisen</translation> </message> @@ -1964,6 +2016,18 @@ 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> + <translation>Eine höhere Gebühr als %1 wird als unsinnig hohe Gebühr angesehen.</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> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Warnung: Ungültige Bitcoin-Adresse</translation> </message> @@ -2472,6 +2536,10 @@ Adresse: %4</translation> <translation>Erarbeitet</translation> </message> <message> + <source>watch-only</source> + <translation>beobachtet</translation> + </message> + <message> <source>(n/a)</source> <translation>(k.A.)</translation> </message> @@ -2488,6 +2556,10 @@ Adresse: %4</translation> <translation>Art der Transaktion</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <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> </message> @@ -2583,6 +2655,10 @@ Adresse: %4</translation> <translation>Transaktionsverlauf exportieren</translation> </message> <message> + <source>Watch-only</source> + <translation>Beobachtet</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Exportieren fehlgeschlagen</translation> </message> @@ -2698,26 +2774,10 @@ Adresse: %4</translation> <translation>Optionen:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Konfigurationsdatei festlegen (Standard: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>PID-Datei festlegen (Standard: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Datenverzeichnis festlegen</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation><port> nach Verbindungen abhören (Standard: 8333 oder Testnetz: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Maximal <n> Verbindungen zu Gegenstellen aufrechterhalten (Standard: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Mit dem angegebenen Knoten verbinden, um Adressen von Gegenstellen abzufragen, danach trennen</translation> </message> @@ -2726,18 +2786,6 @@ Adresse: %4</translation> <translation>Die eigene öffentliche Adresse angeben</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Schwellenwert, um Verbindungen zu sich nicht konform verhaltenden Gegenstellen zu beenden (Standard: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Anzahl Sekunden, während denen sich nicht konform verhaltenden Gegenstellen die Wiederverbindung verweigert wird (Standard: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation><port> nach JSON-RPC-Verbindungen abhören (Standard: 8332 oder Testnetz: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Kommandozeilen- und JSON-RPC-Befehle annehmen</translation> </message> @@ -2778,22 +2826,18 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Zulässige Chiffren (Standard: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> - <translation>An die angegebene Adresse binden und immer abhören. Für IPv6 "[Host]:Port"-Schreibweise verwenden</translation> - </message> - <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Anzahl der freien Transaktionen auf <n> * 1000 Byte pro Minute begrenzen (Standard: 15)</translation> + <translation>An die angegebene Adresse binden und immer abhören. Für IPv6 "[Host]:Port"-Notation verwenden</translation> </message> <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Alle Wallet-Transaktionen löschen und nur diese Teilbereiche der Blockkette durch -rescan beim Starten wiederherstellen</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>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> @@ -2807,15 +2851,7 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com </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 TxID ersetzt)</translation> - </message> - <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Datenbankaktivitäten vom Arbeitsspeicher-Pool alle <n> Megabyte auf den Datenträger schreiben (Standard: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Legt fest, wie gründlich die Blockverifikation von -checkblocks ist (0-4, Standard: 3)</translation> + <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> @@ -2826,10 +2862,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Maximale Anzahl an Skript-Verifizierungs-Threads festlegen (%u bis %d, 0 = automatisch, <0 = so viele Kerne frei lassen, Standard: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Legt ein Prozessor-/CPU-Kernlimit fest, wenn CPU-Mining aktiviert ist (-1 = unbegrenzt, Standard: -1)</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>Dies ist eine Vorab-Testversion - Verwendung auf eigene Gefahr - nicht für Mining- oder Handelsanwendungen nutzen!</translation> </message> @@ -2838,10 +2870,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Kann auf diesem Computer nicht an %s binden, da Bitcoin Core wahrscheinlich bereits gestartet wurde.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Separaten SOCKS5-Proxy verwenden, um Gegenstellen über versteckte Tor-Dienste zu erreichen (Standard: -proxy)</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> @@ -2862,12 +2890,12 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Warnung: wallet.dat beschädigt, Datenrettung erfolgreich! Original wallet.dat wurde als wallet.{Zeitstempel}.dat in %s gespeichert. Falls Ihr Kontostand oder Transaktionen nicht korrekt sind, sollten Sie von einer Datensicherung wiederherstellen.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(Standard: 1)</translation> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Gegenstellen die sich von der angegebenen Netzmaske oder IP-Adresse aus verbinden immer zulassen. Kann mehrmals angegeben werden.</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(Standard: wallet.dat)</translation> + <source>(default: 1)</source> + <translation>(Standard: 1)</translation> </message> <message> <source><category> can be:</source> @@ -2898,10 +2926,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Debugging-/Testoptionen:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Sicherheitsmodus deaktivieren, übergeht ein echtes Sicherheitsmodusereignis (Standard: 0)</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> @@ -2930,6 +2954,10 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Fehler beim Öffnen der Blockdatenbank</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Fehler: Ein schwerer Fehler ist aufgetreten, für Details debug.log ansehen.</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Fehler: Zu wenig freier Speicherplatz auf dem Datenträger!</translation> </message> @@ -2938,66 +2966,10 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Fehler: Wallet gesperrt, Transaktion kann nicht erstellt werden!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Fehler: Systemfehler: </translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Fehler, es konnte kein Port abgehört werden. Wenn dies so gewünscht wird -listen=0 verwenden.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Lesen der Blockinformationen fehlgeschlagen</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Lesen des Blocks fehlgeschlagen</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Synchronisation des Blockindex fehlgeschlagen</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Schreiben des Blockindex fehlgeschlagen</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Schreiben der Blockinformationen fehlgeschlagen</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Schreiben des Blocks fehlgeschlagen</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Schreiben der Dateiinformationen fehlgeschlagen</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Schreiben in die Münzendatenbank fehlgeschlagen</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Schreiben des Transaktionsindex fehlgeschlagen</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Schreiben der Rücksetzdaten fehlgeschlagen</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Sicherheitsmodus erzwingen (Standard: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Bitcoins erzeugen (Standard: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Wieviele Blöcke beim Starten geprüft werden sollen (Standard: 288, 0 = alle)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Wenn <category> nicht angegeben wird, jegliche Debugginginformationen ausgeben.</translation> </message> @@ -3018,8 +2990,8 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Nicht genügend Datei-Deskriptoren verfügbar.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Debugausgaben einen Zeitstempel voranstellen (Standard: 1)</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <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> @@ -3034,26 +3006,18 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Maximale Blockgröße in Byte festlegen (Standard: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Maximale Anzahl an Threads zur Verarbeitung von RPC-Anfragen festlegen (Standard: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Wallet-Datei angeben (innerhalb des Datenverzeichnisses)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Unbestätigtes Wechselgeld beim Senden von Transaktionen ausgeben (Standard: 1)</translation> - </message> - <message> - <source>Stop running after importing blocks from disk (default: 0)</source> - <translation>Beenden, nachdem Blöcke vom Datenträger importiert wurden (Standard: 0)</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> + <message> <source>Verifying blocks...</source> <translation>Verifiziere Blöcke...</translation> </message> @@ -3078,16 +3042,32 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Blöcke aus externer Datei blk000??.dat importieren</translation> </message> <message> - <source>(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> - <translation>(Standard: 1, 1 = TX-Metadaten wie z.B. Accountbesitzer und Zahlungsanforderungsinformationen behalten, 2 = TX-Metadaten verwerfen)</translation> + <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>JSON-RPC-Verbindungen von der angegeben Quelle erlauben. Gültig für <ip> ist eine einzelne IP-Adresse (z.B. 1.2.3.4), ein Netzwerk bzw. eine Netzmaske (z.B. 1.2.3.4/255.255.255.0), oder die CIDR-Notation (z.B. 1.2.3.4/24). Kann mehrmals angegeben werden.</translation> + </message> + <message> + <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> + <translation>Beim Einrichten der abzuhörenden RPC-Adresse %s auf Port %u ist ein Fehler aufgetreten: %s</translation> + </message> + <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>An die angegebene Adresse binden und Gegenstellen, die sich dorthin verbinden, immer zulassen. Für IPv6 "[Host]:Port"-Notation verwenden</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>An die angegebene Adresse binden und nach eingehenden JSON-RPC-Verbindungen abhören. Für IPv6 "[Host]:Port"-Notation verwenden. Kann mehrmals angegeben werden. (Standard: an alle Schnittstellen binden)</translation> </message> <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Datenverzeichnis %s kann nicht gesperrt werden, da Bitcoin Core wahrscheinlich bereits gestartet wurde.</translation> </message> <message> - <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> - <translation>Veröffentlicht unter der MIT/X11-Softwarelizenz, siehe beiligende Datei COPYING oder <http://www.opensource.org/licenses/mit-license.php>.</translation> + <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>Error: Listening for incoming connections failed (listen returned error %s)</source> @@ -3103,19 +3083,27 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com </message> <message> <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Niedrigere Gebühren (in BTC/Kb) als diese werden bei der Vermittlung als gebührenfrei angesehen (Standard: %s)</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>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Debugginginformationen ausgeben (Standard: 0, <category> anzugeben ist optional)</translation> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>Maximale Datengröße in "Data Carrier"-Transaktionen die weitergeleitet und erarbeitet werden (Standard: %u)</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>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> - <translation>Maximale Größe in Byte von Transaktionen hoher Priorität/mit niedrigen Gebühren festlegen (Standard: %d)</translation> + <translation>Maximale Größe in Byte von "high-priority/low-fee"-Transaktionen festlegen (Standard: %d)</translation> + </message> + <message> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <translation>Maximale Anzahl an Threads zur Bitcoinerzeugung, wenn aktiviert, festlegen (-1 = alle Kerne, Standard: %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> @@ -3123,7 +3111,15 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com </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>Warnung: Bitte korrigieren Sie die Datums- und Uhrzeiteinstellungen Ihres Computers, da Bitcoin Core ansonsten nicht ordnungsgemäß funktionieren wird!</translation> + <translation>Warnung: Bitte korrigieren Sie die Datums- und Uhrzeiteinstellungen Ihres Computers, da Bitcoin Core ansonsten nicht ordnungsgemäß funktionieren wird.</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>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>Cannot resolve -whitebind address: '%s'</source> + <translation>Kann Adresse in -whitebind nicht auflösen: '%s'</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3146,10 +3142,18 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Fehler: Nicht unterstütztes Argument -tor gefunden, bitte -onion verwenden.</translation> </message> <message> + <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> + <translation>Gebühr (in BTC/kB), die von Ihnen gesendeten Transaktionen hinzugefügt wird (Standard: %s)</translation> + </message> + <message> <source>Information</source> <translation>Hinweis</translation> </message> <message> + <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source> + <translation>Initialisierungsplausibilitätsprüfung fehlgeschlagen. Bitcoin Core wird beendet.</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Ungültiger Betrag für -minrelaytxfee=<amount>: '%s'</translation> </message> @@ -3158,46 +3162,34 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Ungültiger Betrag für -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Größe des Signaturcaches auf <n> Einträge begrenzen (Standard: 50000)</translation> + <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> + <translation>Ungültiger Betrag für -paytxfee=<amount>: '%s' (muss mindestens %s sein)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Transaktionspriorität und Gebühr pro kB beim Erzeugen von Blöcken protokollieren (Standard: 0)</translation> + <source>Invalid netmask specified in -whitelist: '%s'</source> + <translation>Ungültige Netzmaske angegeben in -whitelist: '%s'</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Einen vollständigen Transaktionsindex führen (Standard: 0)</translation> + <source>Keep at most <n> unconnectable blocks in memory (default: %u)</source> + <translation>Maximal <n> nicht-verbindbare Blöcke im Speicher halten (Standard: %u)</translation> </message> <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maximale Größe des Empfangspuffers pro Verbindung, <n> * 1000 Byte (Standard: 5000)</translation> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Maximal <n> nicht-verbindbare Transaktionen im Speicher halten (Standard: %u)</translation> </message> <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maximale Größe des Sendepuffers pro Verbindung, <n> * 1000 Byte (Standard: 1000)</translation> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>Angabe eines Ports benötigt für -whitebind: '%s'</translation> </message> <message> <source>Node relay options:</source> - <translation>Knoten-Vermittlungsoptionen:</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Blockkette nur als gültig ansehen, wenn sie mit den integrierten Prüfpunkten übereinstimmt (Standard: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Verbinde nur zu Knoten des Netztyps <net> (IPv4, IPv6 oder Tor)</translation> + <translation>Knoten-Weiterleitungsoptionen:</translation> </message> <message> <source>Print block on startup, if found in block index</source> <translation>Block beim Starten ausgeben, wenn dieser im Blockindex gefunden wurde.</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Blockbaum beim Starten ausgeben (Standard: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>RPC-SSL-Optionen (siehe Bitcoin-Wiki für SSL-Einrichtung):</translation> </message> @@ -3214,20 +3206,12 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Zufällig eine von <n> Netzwerknachrichten verwürfeln</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Einen Thread starten, der periodisch die Wallet sicher auf den Datenträger schreibt (Standard: 1)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Rückverfolgungs- und Debuginformationen an die Konsole senden, anstatt sie in debug.log zu schreiben</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Minimale Blockgröße in Byte festlegen (Standard: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>DB_PRIVATE-Flag in der Wallet-Datenbankumgebung setzen (Standard: 1)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Transaktionen, wenn möglich, als gebührenfreie Transaktion senden (Standard: %u)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> @@ -3242,14 +3226,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Signierung der Transaktion fehlgeschlagen</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Verbindungzeitüberschreitung in Millisekunden festlegen (Standard: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Systemfehler: </translation> - </message> - <message> <source>This is experimental software.</source> <translation>Dies ist experimentelle Software.</translation> </message> @@ -3266,8 +3242,8 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Transaktion zu groß</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: 0)</translation> + <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> <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> @@ -3322,10 +3298,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Wallet auf das neueste Format aktualisieren</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Größe des Schlüsselpools festlegen auf <n> (Standard: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Blockkette erneut nach fehlenden Wallet-Transaktionen durchsuchen</translation> </message> @@ -3334,14 +3306,6 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>OpenSSL (https) für JSON-RPC-Verbindungen verwenden</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Serverzertifikat (Standard: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Privater Serverschlüssel (Standard: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Dieser Hilfetext</translation> </message> @@ -3358,14 +3322,174 @@ zum Beispiel: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com <translation>Fehler beim Laden von wallet.dat: Wallet beschädigt</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 = 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>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source> + <translation>Wenn keine Transaktionsgebühr festgelegt wurde eine Gebühr einbeziehen, sodass Transaktionen im Schnitt innerhalb von <n> Blöcken bestätigt werden (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> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Anzahl Sekunden, während denen sich nicht konform verhaltenden Gegenstellen die Wiederverbindung verweigert wird (Standard: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Debugginginformationen ausgeben (Standard: %u, <category> anzugeben ist optional)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Separaten SOCKS5-Proxy verwenden, um Gegenstellen über versteckte Tor-Dienste zu erreichen (Standard: %s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(Standard: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Zulässige Chiffren (Standard: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <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> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Wieviele Blöcke beim Starten geprüft werden sollen (Standard: %u, 0 = alle)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>IP-Adressen in Debugausgabe einschließen (Standard: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <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> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Maximal <n> Verbindungen zu Gegenstellen aufrechterhalten (Standard: %u)</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> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <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> + <message> + <source>Print block tree on startup (default: %u)</source> + <translation>Blockbaum beim Starten ausgeben (Standard: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>"Data Carrier"-Transaktionen weiterleiten und erarbeiten (Standard: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <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> + <message> + <source>Server private key (default: %s)</source> + <translation>Privater Serverschlüssel (Standard: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Größe des Schlüsselpools festlegen auf <n> (Standard: %u)</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Minimale Blockgröße in Byte festlegen (Standard: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <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> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Verbindungzeitüberschreitung in Millisekunden festlegen (Minimum: 1, Standard: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>PID-Datei festlegen (Standard: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <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> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Unbekannter Netztyp in -onlynet angegeben: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts index d5e9b57d99..cf29c222ed 100644 --- a/src/qt/locale/bitcoin_el_GR.ts +++ b/src/qt/locale/bitcoin_el_GR.ts @@ -1,4 +1,4 @@ -<TS language="el_GR" version="2.1"> +<TS language="el_GR" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -7,7 +7,7 @@ </message> <message> <source>Create a new address</source> - <translation>Δημιούργησε νέα διεύθυνση</translation> + <translation>Δημιουργία νέας διεύθυνσης</translation> </message> <message> <source>&New</source> @@ -54,6 +54,10 @@ <translation>Επιλογή διεύθυνσης απ' όπου θα ληφθούν νομίσματα</translation> </message> <message> + <source>C&hoose</source> + <translation>Ε&πιλογή</translation> + </message> + <message> <source>Sending addresses</source> <translation>Διευθύνσεις αποστολής</translation> </message> @@ -66,6 +70,10 @@ <translation>Αυτές είναι οι Bitcoin διευθύνσεις σας για να λαμβάνετε πληρωμές. Δίνοντας μία ξεχωριστή διεύθυνση σε κάθε αποστολέα, θα μπορείτε να ελέγχετε ποιος σας πληρώνει.</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>Αυτές είναι οι Bitcoin διευθύνσεις σας για να λαμβάνετε πληρωμές. Δίνοντας μία ξεχωριστή διεύθυνση σε κάθε αποστολέα, θα μπορείτε να ελέγχετε ποιος σας πληρώνει.</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> @@ -113,7 +125,7 @@ </message> <message> <source>New passphrase</source> - <translation>Νέος κωδικός πρόσβασης</translation> + <translation>&Αλλαγή κωδικού</translation> </message> <message> <source>Repeat new passphrase</source> @@ -121,7 +133,7 @@ </message> <message> <source>Encrypt wallet</source> - <translation>Κρυπτογράφησε το πορτοφόλι</translation> + <translation>&Κρυπτογράφηση πορτοφολιού</translation> </message> <message> <source>This operation needs your wallet passphrase to unlock the wallet.</source> @@ -173,6 +185,10 @@ <translation>Κρυπτογραφημενο πορτοφολι</translation> </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> 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> @@ -220,6 +236,10 @@ <translation>&Επισκόπηση</translation> </message> <message> + <source>Node</source> + <translation>Κόμβος</translation> + </message> + <message> <source>Show general overview of wallet</source> <translation>Εμφάνισε τη γενική εικόνα του πορτοφολιού</translation> </message> @@ -264,6 +284,22 @@ <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> + <message> + <source>Bitcoin Core client</source> + <translation>Εφαρμογή Bitcoin Core</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>Εισαγωγή μπλοκ από τον σκληρο δίσκο ... </translation> </message> @@ -316,6 +352,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> @@ -352,10 +392,6 @@ <translation>Εργαλειοθήκη καρτελών</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -375,6 +411,18 @@ <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>Άνοιγμα bitcoin: 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-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> @@ -383,10 +431,6 @@ <source>No block source available...</source> <translation>Η πηγή του μπλοκ δεν ειναι διαθέσιμη... </translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Έγινε λήψη %1 μπλοκ ιστορικού συναλλαγών</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n ώρες </numerusform><numerusform>%n ώρες </numerusform></translation> @@ -478,6 +522,10 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>Επιλογή κερμάτων</translation> + </message> + <message> <source>Quantity:</source> <translation>Ποσότητα:</translation> </message> @@ -494,6 +542,18 @@ Address: %4 <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>Change:</source> <translation>Ρέστα:</translation> </message> @@ -502,12 +562,24 @@ Address: %4 <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>Address</source> - <translation>Διεύθυνση</translation> + <source>Received with label</source> + <translation>Παραλήφθηκε με επιγραφή</translation> + </message> + <message> + <source>Received with address</source> + <translation>Παραλείφθηκε με την εξής διεύθυνση</translation> </message> <message> <source>Date</source> @@ -542,10 +614,26 @@ 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>Αντιγραφή των byte</translation> </message> @@ -554,6 +642,10 @@ Address: %4 <translation>Αντιγραφή προτεραιότητας</translation> </message> <message> + <source>Copy dust</source> + <translation>Αντιγραφή 'σκόνης'</translation> + </message> + <message> <source>Copy change</source> <translation>Αντιγραφή των ρέστων</translation> </message> @@ -610,6 +702,26 @@ 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> + <message> + <source>Transactions with higher priority are more likely to get included into a block.</source> + <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> @@ -638,6 +750,10 @@ Address: %4 <translation>Η ετικέτα που συνδέεται με αυτήν την καταχώρηση στο βιβλίο διευθύνσεων</translation> </message> <message> + <source>The address associated with this address list entry. This can only be modified for sending addresses.</source> + <translation>Η διεύθυνση σχετίζεται με αυτή την καταχώρηση του βιβλίου διευθύνσεων. Μπορεί να τροποποιηθεί μόνο για τις διευθύνσεις αποστολής.</translation> + </message> + <message> <source>&Address</source> <translation>&Διεύθυνση</translation> </message> @@ -685,6 +801,14 @@ 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> + <message> <source>Cannot create data directory here.</source> <translation>Δεν μπορεί να δημιουργηθεί φάκελος δεδομένων εδώ.</translation> </message> @@ -732,10 +856,18 @@ Address: %4 <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> - </context> + <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>Επιλογή καταλόγου</translation> + </message> +</context> <context> <name>Intro</name> <message> @@ -751,6 +883,10 @@ Address: %4 <translation>Καθώς αυτή είναι η πρώτη φορά που εκκινείται το πρόγραμμα, μπορείτε να διαλέξετε πού θα αποθηκεύει το Bitcoin Core τα δεδομένα του.</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>O πυρήνας Bitcoin θα κατεβάσει και να αποθηκεύσει ένα αντίγραφο της αλυσίδας μπλοκ Bitcoin. Τουλάχιστον %1GB δεδομένων θα αποθηκευτούν σε αυτόν τον κατάλογο, και θα αυξηθεί με την πάροδο του χρόνου. Το πορτοφόλι θα αποθηκευτεί σε αυτόν τον κατάλογο.</translation> + </message> + <message> <source>Use the default data directory</source> <translation>Χρήση του προεπιλεγμένου φακέλου δεδομένων</translation> </message> @@ -763,22 +899,38 @@ Address: %4 <translation>Bitcoin Core</translation> </message> <message> + <source>Error: Specified data directory "%1" cannot be created.</source> + <translation>Σφάλμα: Ο καθορισμένος φάκελος δεδομένων "%1" δεν μπορεί να δημιουργηθεί.</translation> + </message> + <message> <source>Error</source> <translation>Σφάλμα</translation> </message> + </context> +<context> + <name>OpenURIDialog</name> + <message> + <source>Open URI</source> + <translation>'Ανοιγμα &URI</translation> + </message> <message> - <source>GB of free space available</source> - <translation>GB ελεύθερου χώρου διαθέσιμα</translation> + <source>Open payment request from URI or file</source> + <translation>Ανοιχτό αίτημα πληρωμής από URI ή απο αρχείο</translation> </message> <message> - <source>(of %1GB needed)</source> - <translation>(από τα %1GB που χρειάζονται)</translation> + <source>URI:</source> + <translation>URI:</translation> + </message> + <message> + <source>Select payment request file</source> + <translation>Επιλέξτε πληρωμή αρχείου αίτησης</translation> + </message> + <message> + <source>Select payment request file to open</source> + <translation>Επιλέξτε αρχείο πληρωμής για άνοιγμα.</translation> </message> </context> <context> - <name>OpenURIDialog</name> - </context> -<context> <name>OptionsDialog</name> <message> <source>Options</source> @@ -789,14 +941,6 @@ Address: %4 <translation>&Κύριο</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Η προαιρετική αμοιβή για κάθε kB επισπεύδει την επεξεργασία των συναλλαγών σας. Οι περισσότερες συναλλαγές είναι 1 kB. </translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Αμοιβή &συναλλαγής</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>Αυτόματη εκκίνηση του Bitcoin μετά την εισαγωγή στο σύστημα</translation> </message> @@ -805,10 +949,34 @@ Address: %4 <translation>&Έναρξη του Βιtcoin κατά την εκκίνηση του συστήματος</translation> </message> <message> + <source>Size of &database cache</source> + <translation>Μέγεθος κρυφής μνήμης βάσης δεδομένων.</translation> + </message> + <message> <source>MB</source> <translation>MB</translation> </message> <message> + <source>Number of script &verification threads</source> + <translation>Αριθμός script και γραμμές επαλήθευσης </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 του διαμεσολαβητή (π.χ. 127.0.0.1 / IPv6: ::1)</translation> + </message> + <message> + <source>Third party transaction URLs</source> + <translation>Διευθύνσεις τρίτων συναλλαγών.</translation> + </message> + <message> <source>Reset all client options to default.</source> <translation>Επαναφορα όλων των επιλογων του πελάτη σε default.</translation> </message> @@ -821,10 +989,18 @@ Address: %4 <translation>&Δίκτυο</translation> </message> <message> + <source>W&allet</source> + <translation>Π&ορτοφόλι</translation> + </message> + <message> <source>Expert</source> <translation>Έμπειρος</translation> </message> <message> + <source>Enable coin &control features</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> @@ -833,6 +1009,14 @@ Address: %4 <translation>Απόδοση θυρών με χρήστη &UPnP</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Σύνδεση στο Bitcoin δίκτυο μέσω διαμεσολαβητή SOCKS5 (π.χ. για σύνδεση μέσω Tor)</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Σύνδεση μέσω διαμεσολαβητή SOCKS5 (προεπιλεγμένος)</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>&IP διαμεσολαβητή:</translation> </message> @@ -885,6 +1069,10 @@ Address: %4 <translation>Διαλέξτε την προεπιλεγμένη υποδιαίρεση που θα εμφανίζεται όταν στέλνετε νομίσματα.</translation> </message> <message> + <source>Whether to show coin control features or not.</source> + <translation>Επιλογή κατα πόσο να αναδείχνονται οι δυνατότητες ελέγχου κερμάτων.</translation> + </message> + <message> <source>&OK</source> <translation>&ΟΚ</translation> </message> @@ -909,6 +1097,14 @@ 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> + <message> <source>The supplied proxy address is invalid.</source> <translation>Δεν είναι έγκυρη η διεύθυνση διαμεσολαβητή</translation> </message> @@ -924,8 +1120,8 @@ Address: %4 <translation>Οι πληροφορίες που εμφανίζονται μπορεί να είναι ξεπερασμένες. Το πορτοφόλι σας συγχρονίζεται αυτόματα με το δίκτυο Bitcoin μετά από μια σύνδεση, αλλά αυτή η διαδικασία δεν έχει ακόμη ολοκληρωθεί. </translation> </message> <message> - <source>Wallet</source> - <translation>Πορτοφόλι</translation> + <source>Watch-only:</source> + <translation>Επίβλεψη μόνο:</translation> </message> <message> <source>Available:</source> @@ -936,6 +1132,10 @@ Address: %4 <translation>Το τρέχον διαθέσιμο υπόλοιπο</translation> </message> <message> + <source>Pending:</source> + <translation>Εκκρεμούν:</translation> + </message> + <message> <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source> <translation>Το άθροισμα των συναλλαγών που δεν έχουν ακόμα επιβεβαιωθεί και δεν προσμετρώνται στο τρέχον διαθέσιμο υπόλοιπό σας</translation> </message> @@ -948,6 +1148,10 @@ Address: %4 <translation>Εξορυγμενο υπόλοιπο που δεν έχει ακόμα ωριμάσει </translation> </message> <message> + <source>Balances</source> + <translation>Υπόλοιπο:</translation> + </message> + <message> <source>Total:</source> <translation>Σύνολο:</translation> </message> @@ -956,8 +1160,12 @@ Address: %4 <translation>Το τρέχον συνολικό υπόλοιπο</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Πρόσφατες συναλλαγές</b></translation> + <source>Spendable:</source> + <translation>Ξοδεμένα:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Πρόσφατες συναλλαγές</translation> </message> <message> <source>out of sync</source> @@ -975,6 +1183,18 @@ Address: %4 <translation>Μη έγκυρη διεύθυνση πληρωμής %1</translation> </message> <message> + <source>Payment request rejected</source> + <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>Payment request error</source> <translation>Σφάλμα αιτήματος πληρωμής</translation> </message> @@ -983,6 +1203,18 @@ Address: %4 <translation>Δεν είναι δυνατή η εκκίνηση του Bitcoin: click-to-pay handler</translation> </message> <message> + <source>Payment request fetch URL is invalid: %1</source> + <translation>Η διεύθυνση πληρωμής (URL) δεν είναι έγκυρη: %1</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 acknowledged</source> <translation>Πληρωμή αναγνωρίστηκε</translation> </message> @@ -993,7 +1225,15 @@ Address: %4 </context> <context> <name>PeerTableModel</name> - </context> + <message> + <source>Address/Hostname</source> + <translation>Διεύθυθνση/Όνομα υπολογιστή</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Χρόνος καθυστέρησης</translation> + </message> +</context> <context> <name>QObject</name> <message> @@ -1001,6 +1241,14 @@ Address: %4 <translation>Ποσό</translation> </message> <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>Εισάγετε μια διεύθυνση Bitcoin (π.χ. %1)</translation> + </message> + <message> + <source>%1 d</source> + <translation>%1 d</translation> + </message> + <message> <source>%1 h</source> <translation>%1 ώ</translation> </message> @@ -1009,10 +1257,30 @@ Address: %4 <translation>%1 λ</translation> </message> <message> + <source>%1 s</source> + <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> + <message> <source>N/A</source> <translation>Μη διαθέσιμο</translation> </message> - </context> + <message> + <source>%1 ms</source> + <translation>%1 ms</translation> + </message> +</context> <context> <name>QRImageWidget</name> <message> @@ -1087,6 +1355,22 @@ Address: %4 <translation>Τρέχον αριθμός μπλοκ</translation> </message> <message> + <source>Received</source> + <translation>Παραλήφθησαν</translation> + </message> + <message> + <source>Version</source> + <translation>Έκδοση</translation> + </message> + <message> + <source>Services</source> + <translation>Υπηρεσίες</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Χρόνος καθυστέρησης</translation> + </message> + <message> <source>Last block time</source> <translation>Χρόνος τελευταίου μπλοκ</translation> </message> @@ -1162,6 +1446,26 @@ Address: %4 <source>%1 GB</source> <translation>%1 GB</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> </context> <context> <name>ReceiveCoinsDialog</name> @@ -1217,6 +1521,10 @@ Address: %4 <translation>Κώδικας QR</translation> </message> <message> + <source>Copy &URI</source> + <translation>Αντιγραφη της επιλεγμενης διεύθυνσης στο πρόχειρο του συστηματος</translation> + </message> + <message> <source>&Save Image...</source> <translation>&Αποθήκευση εικόνας...</translation> </message> @@ -1225,6 +1533,10 @@ Address: %4 <translation>Πληροφορίες πληρωμής</translation> </message> <message> + <source>URI</source> + <translation>URI:</translation> + </message> + <message> <source>Address</source> <translation>Διεύθυνση</translation> </message> @@ -1287,6 +1599,10 @@ Address: %4 <translation>Αποστολή νομισμάτων</translation> </message> <message> + <source>Coin Control Features</source> + <translation>Χαρακτηρηστικά επιλογής κερμάτων</translation> + </message> + <message> <source>automatically selected</source> <translation>επιλεγμένο αυτόματα</translation> </message> @@ -1311,10 +1627,34 @@ Address: %4 <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>Transaction Fee:</source> + <translation>Τέλος συναλλαγής:</translation> + </message> + <message> + <source>Choose...</source> + <translation>Επιλογή...</translation> + </message> + <message> + <source>Minimize</source> + <translation>Ελαχιστοποίηση</translation> + </message> + <message> + <source>fast</source> + <translation>Γρήγορο</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Αποστολή σε πολλούς αποδέκτες ταυτόχρονα</translation> </message> @@ -1327,6 +1667,10 @@ Address: %4 <translation>Καθαρισμός όλων των πεδίων της φόρμας.</translation> </message> <message> + <source>Dust:</source> + <translation>Σκόνη</translation> + </message> + <message> <source>Clear &All</source> <translation>Καθαρισμός &Όλων</translation> </message> @@ -1359,6 +1703,14 @@ Address: %4 <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>Αντιγραφή των byte</translation> </message> @@ -1411,6 +1763,10 @@ Address: %4 <translation>(χωρίς ετικέτα)</translation> </message> <message> + <source>Copy dust</source> + <translation>Αντιγραφή 'σκόνης'</translation> + </message> + <message> <source>Are you sure you want to send?</source> <translation>Είστε βέβαιοι για την αποστολή;</translation> </message> @@ -1496,6 +1852,10 @@ Address: %4 <translation>Μπορείτε να υπογράφετε μηνύματα με τις διευθύνσεις σας, ώστε ν' αποδεικνύετε πως αυτές σας ανήκουν. Αποφεύγετε να υπογράφετε κάτι αόριστο καθώς ενδέχεται να εξαπατηθείτε. Υπογράφετε μόνο πλήρης δηλώσεις με τις οποίες συμφωνείτε.</translation> </message> <message> + <source>The Bitcoin address to sign the message with</source> + <translation>Διεύθυνση Bitcoin που θα σταλεί το μήνυμα</translation> + </message> + <message> <source>Choose previously used address</source> <translation>Επιλογή διεύθυνσης που έχει ήδη χρησιμοποιηθεί</translation> </message> @@ -1548,6 +1908,10 @@ Address: %4 <translation>Πληκτρολογήστε την υπογραφή διεύθυνσης, μήνυμα (βεβαιωθείτε ότι έχετε αντιγράψει τις αλλαγές γραμμής, κενά, tabs, κ.λπ. ακριβώς) και την υπογραφή παρακάτω, για να ελέγξει το μήνυμα. Να είστε προσεκτικοί για να μην διαβάσετε περισσότερα στην υπογραφή ό, τι είναι στην υπογραφή ίδιο το μήνυμα , για να μην εξαπατηθούν από έναν άνθρωπο -in - the-middle επίθεση.</translation> </message> <message> + <source>The Bitcoin address the message was signed with</source> + <translation>Διεύθυνση Bitcoin η οποία το μήνυμα έχει υπογραφεί</translation> + </message> + <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>Υπογράψτε ένα μήνυμα για ν' αποδείξετε πως υπογραφθηκε απο μια συγκεκριμένη διεύθυνση Bitcoin</translation> </message> @@ -1641,6 +2005,10 @@ Address: %4 <translation>Ανοιχτό μέχρι %1</translation> </message> <message> + <source>conflicted</source> + <translation>σύγκρουση</translation> + </message> + <message> <source>%1/offline</source> <translation>%1/χωρίς σύνδεση;</translation> </message> @@ -1685,6 +2053,10 @@ Address: %4 <translation> δική σας διεύθυνση </translation> </message> <message> + <source>watch-only</source> + <translation>Επίβλεψη μόνο:</translation> + </message> + <message> <source>label</source> <translation>eπιγραφή</translation> </message> @@ -1705,6 +2077,14 @@ Address: %4 <translation>Debit</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> @@ -1729,6 +2109,10 @@ 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> @@ -1819,6 +2203,10 @@ Address: %4 <translation>Ανεπιβεβαίωτες</translation> </message> <message> + <source>Conflicted</source> + <translation>Σύγκρουση</translation> + </message> + <message> <source>Received with</source> <translation>Παραλαβή με</translation> </message> @@ -1839,6 +2227,10 @@ Address: %4 <translation>Εξόρυξη</translation> </message> <message> + <source>watch-only</source> + <translation>Επίβλεψη μόνο:</translation> + </message> + <message> <source>(n/a)</source> <translation>(δ/α)</translation> </message> @@ -1950,6 +2342,10 @@ Address: %4 <translation>Εξαγωγή Ιστορικού Συναλλαγών</translation> </message> <message> + <source>Watch-only</source> + <translation>Επίβλεψη μόνο:</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Η Εξαγωγή Απέτυχε</translation> </message> @@ -2053,26 +2449,10 @@ Address: %4 <translation>Επιλογές:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Ορίστε αρχείο ρυθμίσεων (προεπιλογή: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Ορίστε αρχείο pid (προεπιλογή: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Ορισμός φακέλου δεδομένων</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Εισερχόμενες συνδέσεις στη θύρα <port> (προεπιλογή: 8333 ή στο testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Μέγιστες αριθμός συνδέσεων με τους peers <n> (προεπιλογή: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Σύνδεση σε έναν κόμβο για την ανάκτηση διευθύνσεων από ομοτίμους, και αποσυνδέσh</translation> </message> @@ -2081,18 +2461,6 @@ Address: %4 <translation>Διευκρινίστε τη δικιά σας δημόσια διεύθυνση.</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Όριο αποσύνδεσης προβληματικών peers (προεπιλογή: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Δευτερόλεπτα πριν επιτραπεί ξανά η σύνδεση των προβληματικών peers (προεπιλογή: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Εισερχόμενες συνδέσεις JSON-RPC στη θύρα <port> (προεπιλογή: 8332 or testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Αποδοχή εντολών κονσόλας και JSON-RPC</translation> </message> @@ -2170,10 +2538,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(προεπιλογή: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(προεπιλογή: wallet.dat)</translation> - </message> - <message> <source>Attempt to recover private keys from a corrupt wallet.dat</source> <translation>Προσπάθεια για ανακτησει ιδιωτικων κλειδιων από ενα διεφθαρμένο αρχειο wallet.dat </translation> </message> @@ -2218,6 +2582,10 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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> @@ -2226,60 +2594,12 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Σφάλμα: το πορτοφόλι είναι κλειδωμένο, δεν μπορεί να δημιουργηθεί συναλλαγή</translation> </message> <message> - <source>Error: system error: </source> - <translation>Λάθος: λάθος συστήματος:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>ταλαιπωρηθειτε για να ακούσετε σε οποιαδήποτε θύρα. Χρήση - ακούστε = 0 , αν θέλετε αυτό.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Αποτυχία αναγνωσης των block πληροφοριων</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Η αναγνωση του μπλοκ απετυχε</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Ο συγχρονισμος του μπλοκ ευρετηριου απετυχε</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Η δημιουργια του μπλοκ ευρετηριου απετυχε</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Η δημιουργια των μπλοκ πληροφοριων απετυχε</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Η δημιουργια του μπλοκ απετυχε</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Αδυναμία εγγραφής πληροφοριων αρχειου</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Αποτυχία εγγραφής στη βάση δεδομένων νομίσματος</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Αποτυχία εγγραφής δείκτη συναλλαγών </translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Αποτυχία εγγραφής αναίρεσης δεδομένων </translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Δημιουργία νομισμάτων (προκαθορισμος: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Πόσα μπλοκ να ελέγχθουν κατά την εκκίνηση (προεπιλογή:288,0=όλα)</translation> + <source>Importing...</source> + <translation>ΕΙσαγωγή...</translation> </message> <message> <source>Invalid -onion address: '%s'</source> @@ -2294,8 +2614,8 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Εισαγωγή μπλοκ από εξωτερικό αρχείο blk000?.dat</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Ορίσμος του αριθμόυ θεματων στην υπηρεσία κλήσεων RPC (προεπιλογή: 4) </translation> + <source>Specify wallet file (within data directory)</source> + <translation>Επιλέξτε αρχείο πορτοφολιού (μέσα απο κατάλογο δεδομένων)</translation> </message> <message> <source>Verifying blocks...</source> @@ -2314,44 +2634,44 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Εισαγωγή μπλοκ από εξωτερικό αρχείο blk000?.dat</translation> </message> <message> - <source>Information</source> - <translation>Πληροφορία</translation> + <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> + <translation>Αδυναμία κλειδώματος του φακέλου δεδομένων %s. Πιθανώς το Bitcoin να είναι ήδη ενεργό.</translation> </message> <message> - <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> - <translation>Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s'</translation> + <source>Connect through SOCKS5 proxy</source> + <translation>Σύνδεση μέσω διαμεσολαβητή SOCKS5</translation> </message> <message> - <source>Invalid amount for -mintxfee=<amount>: '%s'</source> - <translation>Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s'</translation> + <source>Could not parse -rpcbind value %s as network address</source> + <translation>Δεν μπόρεσε να αναλυθεί η παράμετρος -rpcbind value %s ως διεύθυνση δικτύου</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Διατηρήση ένος πλήρες ευρετήριου συναλλαγών (προεπιλογή: 0) </translation> + <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> + <translation>Σφάλμα φόρτωσης wallet.dat: Το Πορτοφόλι απαιτεί μια νεότερη έκδοση του Bitcoin</translation> </message> <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Μέγιστος buffer λήψης ανά σύνδεση, <n>*1000 bytes (προεπιλογή: 5000)</translation> + <source>Error: Unsupported argument -tor found, use -onion.</source> + <translation>Σφάλμα: Μη συμβατή παράμετρος -tor. Χρησιμοποιήσε την παράμετρο -onion</translation> </message> <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Μέγιστος buffer αποστολής ανά σύνδεση, <n>*1000 bytes (προεπιλογή: 1000)</translation> + <source>Information</source> + <translation>Πληροφορία</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Μονο αποδοχη αλυσίδας μπλοκ που ταιριάζει με τα ενσωματωμένα σημεία ελέγχου (προεπιλογή: 1) </translation> + <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> + <translation>Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s'</translation> </message> <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation> Συνδέση μόνο σε κόμβους του δικτύου <net> (IPv4, IPv6 ή Tor) </translation> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s'</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Αποστολή πληροφοριών εντοπισμού σφαλμάτων στην κονσόλα αντί του αρχείου debug.log</translation> + <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> + <translation>Ρυθμίσεις SSL: (ανατρέξτε στο Bitcoin Wiki για οδηγίες ρυθμίσεων SSL)</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Ορίστε το μέγιστο μέγεθος μπλοκ σε bytes (προεπιλογή: 0)</translation> + <source>Send trace/debug info to console instead of debug.log file</source> + <translation>Αποστολή πληροφοριών εντοπισμού σφαλμάτων στην κονσόλα αντί του αρχείου debug.log</translation> </message> <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> @@ -2362,12 +2682,8 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Η υπογραφή συναλλαγής απέτυχε </translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Ορισμός λήξης χρονικού ορίου σε χιλιοστά του δευτερολέπτου(προεπιλογή:5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Λάθος Συστήματος:</translation> + <source>This is experimental software.</source> + <translation>Η εφαρμογή είναι σε πειραματικό στάδιο.</translation> </message> <message> <source>Transaction amount too small</source> @@ -2382,10 +2698,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Η συναλλαγή ειναι πολύ μεγάλη </translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Χρησιμοποίηση του UPnP για την χρήση της πόρτας αναμονής (προεπιλογή:0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Χρησιμοποίηση του UPnP για την χρήση της πόρτας αναμονής (προεπιλογή:1)</translation> </message> @@ -2402,6 +2714,10 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Προειδοποίηση: Αυτή η έκδοση είναι ξεπερασμένη, απαιτείται αναβάθμιση </translation> </message> <message> + <source>Zapping all transactions from wallet...</source> + <translation>Μεταφορά όλων των συναλλαγών απο το πορτοφόλι</translation> + </message> + <message> <source>on startup</source> <translation>κατά την εκκίνηση</translation> </message> @@ -2422,10 +2738,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Αναβάθμισε το πορτοφόλι στην τελευταία έκδοση</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Όριο πλήθους κλειδιών pool <n> (προεπιλογή: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Επανέλεγχος της αλυσίδας μπλοκ για απούσες συναλλαγές</translation> </message> @@ -2434,14 +2746,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Χρήση του OpenSSL (https) για συνδέσεις JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Αρχείο πιστοποιητικού του διακομιστή (προεπιλογή: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Προσωπικό κλειδί του διακομιστή (προεπιλογή: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Αυτό το κείμενο βοήθειας</translation> </message> @@ -2458,14 +2762,62 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Σφάλμα φόρτωσης wallet.dat: Κατεστραμμένο Πορτοφόλι</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>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> + <translation>Διατηρήση ένος πλήρες ευρετήριου συναλλαγών (προεπιλογή: %u) </translation> + </message> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Δευτερόλεπτα πριν επιτραπεί ξανά η σύνδεση των προβληματικών peers (προεπιλογή: %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> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Πόσα μπλοκ να ελέγχθουν κατά την εκκίνηση (προεπιλογή: %u, 0 = όλα)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Να συμπεριληφθεί η διεύθυνση IP στην αναφορά? (προεπιλογή: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <translation>Δεν είναι έγκυρη η διεύθυνση διαμεσολαβητή: '%s'</translation> </message> <message> + <source>Print block tree on startup (default: %u)</source> + <translation>Εκτύπωση μπλοκ δέντρου κατά την εκκίνηση (προεπιλογή: %u)</translation> + </message> + <message> + <source>Server certificate file (default: %s)</source> + <translation>Αρχείο πιστοποιητικού του διακομιστή (προεπιλογή: %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Ορισμός λήξης χρονικού ορίου σε χιλιοστά του δευτερολέπτου(προεπιλογή: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Ορίστε αρχείο pid (προεπιλογή: %s)</translation> + </message> + <message> + <source>Threshold for disconnecting misbehaving peers (default: %u)</source> + <translation>Όριο αποσύνδεσης προβληματικών peers (προεπιλογή: %u)</translation> + </message> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Άγνωστo δίκτυο ορίζεται σε onlynet: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index a527602b5a..71c626be4b 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.1" language="en"> +<TS version="2.0" language="en"> <context> <name>AddressBookPage</name> <message> @@ -19,7 +19,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+14"/> <source>Copy the currently selected address to the system clipboard</source> <translation>Copy the currently selected address to the system clipboard</translation> </message> @@ -29,7 +29,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+58"/> + <location line="+67"/> <source>C&lose</source> <translation type="unfinished"></translation> </message> @@ -39,12 +39,12 @@ <translation>&Copy Address</translation> </message> <message> - <location filename="../forms/addressbookpage.ui" line="-47"/> + <location filename="../forms/addressbookpage.ui" line="-53"/> <source>Delete the currently selected address from the list</source> <translation>Delete the currently selected address from the list</translation> </message> <message> - <location line="+27"/> + <location line="+30"/> <source>Export the data in the current tab to a file</source> <translation>Export the data in the current tab to a file</translation> </message> @@ -54,7 +54,7 @@ <translation>&Export</translation> </message> <message> - <location line="-27"/> + <location line="-30"/> <source>&Delete</source> <translation>&Delete</translation> </message> @@ -150,7 +150,7 @@ <translation>Passphrase Dialog</translation> </message> <message> - <location line="+21"/> + <location line="+30"/> <source>Enter passphrase</source> <translation>Enter passphrase</translation> </message> @@ -165,7 +165,7 @@ <translation>Repeat new passphrase</translation> </message> <message> - <location filename="../askpassphrasedialog.cpp" line="+41"/> + <location filename="../askpassphrasedialog.cpp" line="+45"/> <source>Encrypt wallet</source> <translation>Encrypt wallet</translation> </message> @@ -200,7 +200,7 @@ <translation>Enter the old and new passphrase to the wallet.</translation> </message> <message> - <location line="+46"/> + <location line="+45"/> <source>Confirm wallet encryption</source> <translation>Confirm wallet encryption</translation> </message> @@ -232,12 +232,12 @@ <translation>Wallet encrypted</translation> </message> <message> - <location line="-135"/> + <location line="-136"/> <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 type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <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 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.</translation> </message> @@ -286,7 +286,7 @@ <context> <name>BitcoinGUI</name> <message> - <location filename="../bitcoingui.cpp" line="+300"/> + <location filename="../bitcoingui.cpp" line="+311"/> <source>Sign &message...</source> <translation>Sign &message...</translation> </message> @@ -296,17 +296,17 @@ <translation>Synchronizing with network...</translation> </message> <message> - <location line="-411"/> + <location line="-407"/> <source>&Overview</source> <translation>&Overview</translation> </message> <message> - <location line="-142"/> + <location line="-129"/> <source>Node</source> <translation type="unfinished"></translation> </message> <message> - <location line="+143"/> + <location line="+130"/> <source>Show general overview of wallet</source> <translation>Show general overview of wallet</translation> </message> @@ -321,7 +321,7 @@ <translation>Browse transaction history</translation> </message> <message> - <location line="+17"/> + <location line="+19"/> <source>E&xit</source> <translation>E&xit</translation> </message> @@ -331,7 +331,7 @@ <translation>Quit application</translation> </message> <message> - <location line="+10"/> + <location line="+7"/> <location line="+2"/> <source>About &Qt</source> <translation>About &Qt</translation> @@ -347,7 +347,7 @@ <translation>&Options...</translation> </message> <message> - <location line="+9"/> + <location line="+6"/> <source>&Encrypt Wallet...</source> <translation>&Encrypt Wallet...</translation> </message> @@ -377,13 +377,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+168"/> - <location line="+5"/> + <location line="+172"/> <source>Bitcoin Core client</source> <translation type="unfinished"></translation> </message> <message> - <location line="+156"/> + <location line="+157"/> <source>Importing blocks from disk...</source> <translation>Importing blocks from disk...</translation> </message> @@ -393,17 +392,17 @@ <translation>Reindexing blocks on disk...</translation> </message> <message> - <location line="-409"/> + <location line="-405"/> <source>Send coins to a Bitcoin address</source> <translation>Send coins to a Bitcoin address</translation> </message> <message> - <location line="+49"/> + <location line="+48"/> <source>Modify configuration options for Bitcoin</source> <translation>Modify configuration options for Bitcoin</translation> </message> <message> - <location line="+12"/> + <location line="+9"/> <source>Backup wallet to another location</source> <translation>Backup wallet to another location</translation> </message> @@ -433,12 +432,12 @@ <translation>Bitcoin</translation> </message> <message> - <location line="-655"/> + <location line="-638"/> <source>Wallet</source> <translation>Wallet</translation> </message> <message> - <location line="+151"/> + <location line="+138"/> <source>&Send</source> <translation>&Send</translation> </message> @@ -448,13 +447,12 @@ <translation>&Receive</translation> </message> <message> - <location line="+33"/> + <location line="+32"/> <source>Show information about Bitcoin Core</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <location line="+2"/> + <location line="+12"/> <source>&Show / Hide</source> <translation>&Show / Hide</translation> </message> @@ -499,29 +497,22 @@ <translation>Tabs toolbar</translation> </message> <message> - <location line="-289"/> - <location line="+386"/> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> - <location line="-411"/> + <location line="-297"/> <source>Bitcoin Core</source> <translation type="unfinished">Bitcoin Core</translation> </message> <message> - <location line="+168"/> + <location line="+155"/> <source>Request payments (generates QR codes and bitcoin: URIs)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+29"/> - <location line="+2"/> + <location line="+30"/> <source>&About Bitcoin Core</source> <translation type="unfinished"></translation> </message> <message> - <location line="+35"/> + <location line="+32"/> <source>Show the list of used sending addresses and labels</source> <translation type="unfinished"></translation> </message> @@ -546,7 +537,7 @@ <translation type="unfinished"></translation> </message> <message numerus="yes"> - <location line="+310"/> + <location line="+307"/> <source>%n active connection(s) to Bitcoin network</source> <translation> <numerusform>%n active connection to Bitcoin network</numerusform> @@ -554,17 +545,12 @@ </translation> </message> <message> - <location line="+22"/> + <location line="+25"/> <source>No block source available...</source> <translation>No block source available...</translation> </message> - <message> - <location line="+10"/> - <source>Processed %1 blocks of transaction history.</source> - <translation>Processed %1 blocks of transaction history.</translation> - </message> <message numerus="yes"> - <location line="+26"/> + <location line="+36"/> <source>%n hour(s)</source> <translation> <numerusform>%n hour</numerusform> @@ -636,8 +622,16 @@ <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="+44"/> + <location line="+49"/> <source>Catching up...</source> <translation>Catching up...</translation> </message> @@ -665,7 +659,7 @@ Address: %4 </translation> </message> <message> - <location line="+69"/> + <location line="+68"/> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Wallet is <b>encrypted</b> and currently <b>unlocked</b></translation> </message> @@ -678,7 +672,7 @@ Address: %4 <context> <name>ClientModel</name> <message> - <location filename="../clientmodel.cpp" line="+138"/> + <location filename="../clientmodel.cpp" line="+140"/> <source>Network Alert</source> <translation>Network Alert</translation> </message> @@ -687,7 +681,7 @@ Address: %4 <name>CoinControlDialog</name> <message> <location filename="../forms/coincontroldialog.ui" line="+14"/> - <source>Coin Control Address Selection</source> + <source>Coin Selection</source> <translation type="unfinished"></translation> </message> <message> @@ -736,24 +730,29 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Tree mode</source> <translation type="unfinished"></translation> </message> <message> - <location line="+16"/> + <location line="+13"/> <source>List mode</source> <translation type="unfinished"></translation> </message> <message> - <location line="+53"/> + <location line="+56"/> <source>Amount</source> <translation type="unfinished">Amount</translation> </message> <message> - <location line="+10"/> - <source>Address</source> - <translation type="unfinished">Address</translation> + <location line="+5"/> + <source>Received with label</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>Received with address</source> + <translation type="unfinished"></translation> </message> <message> <location line="+5"/> @@ -776,7 +775,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location filename="../coincontroldialog.cpp" line="+43"/> + <location filename="../coincontroldialog.cpp" line="+44"/> <source>Copy address</source> <translation type="unfinished">Copy address</translation> </message> @@ -842,17 +841,17 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+333"/> + <location line="+347"/> <source>highest</source> <translation type="unfinished"></translation> </message> <message> - <location line="+0"/> + <location line="+1"/> <source>higher</source> <translation type="unfinished"></translation> </message> <message> - <location line="+0"/> + <location line="+1"/> <source>high</source> <translation type="unfinished"></translation> </message> @@ -862,18 +861,17 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+0"/> - <location line="+12"/> + <location line="+1"/> <source>medium</source> <translation type="unfinished"></translation> </message> <message> - <location line="-11"/> + <location line="+1"/> <source>low-medium</source> <translation type="unfinished"></translation> </message> <message> - <location line="+0"/> + <location line="+1"/> <source>low</source> <translation type="unfinished"></translation> </message> @@ -883,7 +881,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+1"/> <source>lowest</source> <translation type="unfinished"></translation> </message> @@ -898,12 +896,12 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+162"/> + <location line="+165"/> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-28"/> + <location line="-32"/> <source>yes</source> <translation type="unfinished"></translation> </message> @@ -944,7 +942,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+50"/> + <location line="+55"/> <location line="+61"/> <source>(no label)</source> <translation type="unfinished">(no label)</translation> @@ -1059,7 +1057,7 @@ Address: %4 <context> <name>HelpMessageDialog</name> <message> - <location filename="../utilitydialog.cpp" line="+29"/> + <location filename="../utilitydialog.cpp" line="+31"/> <source>Bitcoin Core</source> <translation type="unfinished">Bitcoin Core</translation> </message> @@ -1172,15 +1170,21 @@ Address: %4 <source>Error</source> <translation>Error</translation> </message> - <message> + <message numerus="yes"> <location line="+9"/> - <source>GB of free space available</source> - <translation>GB of free space available</translation> + <source>%n GB of free space available</source> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> </message> - <message> + <message numerus="yes"> <location line="+3"/> - <source>(of %1GB needed)</source> - <translation>(of %1GB needed)</translation> + <source>(of %n GB needed)</source> + <translation type="unfinished"> + <numerusform></numerusform> + <numerusform></numerusform> + </translation> </message> </context> <context> @@ -1201,7 +1205,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+10"/> <source>Select payment request file</source> <translation type="unfinished"></translation> </message> @@ -1224,17 +1228,7 @@ Address: %4 <translation>&Main</translation> </message> <message> - <location line="+116"/> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</translation> - </message> - <message> - <location line="+15"/> - <source>Pay transaction &fee</source> - <translation>Pay transaction &fee</translation> - </message> - <message> - <location line="-125"/> + <location line="+6"/> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>Automatically start Bitcoin after logging in to the system.</translation> </message> @@ -1259,7 +1253,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+160"/> + <location line="+114"/> <source>Accept connections from outside</source> <translation type="unfinished"></translation> </message> @@ -1269,17 +1263,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+34"/> + <location line="+44"/> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation type="unfinished"></translation> </message> @@ -1315,7 +1299,7 @@ Address: %4 <translation>&Network</translation> </message> <message> - <location line="-131"/> + <location line="-85"/> <source>(0 = auto, <0 = leave that many cores free)</source> <translation type="unfinished"></translation> </message> @@ -1325,7 +1309,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+65"/> + <location line="+6"/> <source>Expert</source> <translation type="unfinished"></translation> </message> @@ -1345,7 +1329,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> + <location line="+30"/> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> <translation>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</translation> </message> @@ -1355,7 +1339,17 @@ Address: %4 <translation>Map port using &UPnP</translation> </message> <message> - <location line="+29"/> + <location line="+17"/> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+9"/> <source>Proxy &IP:</source> <translation>Proxy &IP:</translation> </message> @@ -1420,32 +1414,32 @@ Address: %4 <translation>Choose the default subdivision unit to show in the interface and when sending coins.</translation> </message> <message> - <location line="-240"/> + <location line="-253"/> <source>Whether to show coin control features or not.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+402"/> + <location line="+415"/> <source>&OK</source> <translation>&OK</translation> </message> <message> - <location line="+7"/> + <location line="+13"/> <source>&Cancel</source> <translation>&Cancel</translation> </message> <message> - <location filename="../optionsdialog.cpp" line="+68"/> + <location filename="../optionsdialog.cpp" line="+76"/> <source>default</source> <translation>default</translation> </message> <message> - <location line="+63"/> + <location line="+60"/> <source>none</source> <translation type="unfinished"></translation> </message> <message> - <location line="+82"/> + <location line="+76"/> <source>Confirm options reset</source> <translation>Confirm options reset</translation> </message> @@ -1466,7 +1460,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+34"/> + <location line="+25"/> <source>The supplied proxy address is invalid.</source> <translation>The supplied proxy address is invalid.</translation> </message> @@ -1479,23 +1473,18 @@ Address: %4 <translation>Form</translation> </message> <message> - <location line="+52"/> - <location line="+394"/> + <location line="+53"/> + <location line="+372"/> <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="-401"/> - <source>Wallet</source> - <translation>Wallet</translation> - </message> - <message> - <location line="+33"/> + <location line="-133"/> <source>Watch-only:</source> <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+10"/> <source>Available:</source> <translation type="unfinished"></translation> </message> @@ -1505,62 +1494,72 @@ Address: %4 <translation>Your current spendable balance</translation> </message> <message> - <location line="+16"/> + <location line="+41"/> <source>Pending:</source> <translation type="unfinished"></translation> </message> <message> - <location line="+16"/> + <location line="-236"/> <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source> <translation>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</translation> </message> <message> - <location line="+16"/> + <location line="+112"/> <source>Immature:</source> <translation>Immature:</translation> </message> <message> - <location line="+16"/> + <location line="-29"/> <source>Mined balance that has not yet matured</source> <translation>Mined balance that has not yet matured</translation> </message> <message> - <location line="+23"/> + <location line="-163"/> + <source>Balances</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+147"/> <source>Total:</source> <translation>Total:</translation> </message> <message> - <location line="+16"/> + <location line="+61"/> <source>Your current total balance</source> <translation>Your current total balance</translation> </message> <message> - <location line="+38"/> + <location line="+92"/> <source>Your current balance in watch-only addresses</source> <translation type="unfinished"></translation> </message> <message> - <location line="+25"/> + <location line="+23"/> + <source>Spendable:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+49"/> + <source>Recent transactions</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="-317"/> <source>Unconfirmed transactions to watch-only addresses</source> <translation type="unfinished"></translation> </message> <message> - <location line="+25"/> + <location line="+50"/> <source>Mined balance in watch-only addresses that has not yet matured</source> <translation type="unfinished"></translation> </message> <message> - <location line="+44"/> + <location line="+128"/> <source>Current total balance in watch-only addresses</source> <translation type="unfinished"></translation> </message> <message> - <location line="+67"/> - <source><b>Recent transactions</b></source> - <translation><b>Recent transactions</b></translation> - </message> - <message> - <location filename="../overviewpage.cpp" line="+123"/> + <location filename="../overviewpage.cpp" line="+131"/> <location line="+1"/> <source>out of sync</source> <translation>out of sync</translation> @@ -1569,7 +1568,7 @@ Address: %4 <context> <name>PaymentServer</name> <message> - <location filename="../paymentserver.cpp" line="+405"/> + <location filename="../paymentserver.cpp" line="+410"/> <location line="+14"/> <location line="+7"/> <source>URI handling</source> @@ -1681,7 +1680,7 @@ Address: %4 <context> <name>PeerTableModel</name> <message> - <location filename="../peertablemodel.cpp" line="+112"/> + <location filename="../peertablemodel.cpp" line="+118"/> <source>User Agent</source> <translation type="unfinished"></translation> </message> @@ -1699,17 +1698,17 @@ Address: %4 <context> <name>QObject</name> <message> - <location filename="../bitcoinunits.cpp" line="+200"/> + <location filename="../bitcoinunits.cpp" line="+196"/> <source>Amount</source> <translation type="unfinished">Amount</translation> </message> <message> - <location filename="../guiutil.cpp" line="+97"/> + <location filename="../guiutil.cpp" line="+106"/> <source>Enter a Bitcoin address (e.g. %1)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+673"/> + <location line="+698"/> <source>%1 d</source> <translation type="unfinished"></translation> </message> @@ -1795,8 +1794,7 @@ Address: %4 <location line="+23"/> <location line="+36"/> <location line="+23"/> - <location line="+462"/> - <location line="+23"/> + <location line="+465"/> <location line="+23"/> <location line="+23"/> <location line="+23"/> @@ -1813,7 +1811,7 @@ Address: %4 <translation>N/A</translation> </message> <message> - <location line="-987"/> + <location line="-967"/> <source>Client version</source> <translation>Client version</translation> </message> @@ -1873,7 +1871,7 @@ Address: %4 <translation>Current number of blocks</translation> </message> <message> - <location line="+300"/> + <location line="+303"/> <source>Received</source> <translation type="unfinished"></translation> </message> @@ -1889,7 +1887,7 @@ Address: %4 </message> <message> <location line="+39"/> - <location filename="../rpcconsole.cpp" line="+234"/> + <location filename="../rpcconsole.cpp" line="+236"/> <location line="+327"/> <source>Select a peer to view detailed information.</source> <translation type="unfinished"></translation> @@ -1916,11 +1914,6 @@ Address: %4 </message> <message> <location line="+23"/> - <source>Sync Node</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+23"/> <source>Starting Height</source> <translation type="unfinished"></translation> </message> @@ -1965,7 +1958,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="-761"/> + <location line="-741"/> <source>Last block time</source> <translation>Last block time</translation> </message> @@ -1990,7 +1983,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> + <location line="+16"/> <source>Totals</source> <translation type="unfinished"></translation> </message> @@ -2005,7 +1998,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location filename="../forms/rpcconsole.ui" line="-354"/> + <location filename="../forms/rpcconsole.ui" line="-357"/> <source>Build date</source> <translation>Build date</translation> </message> @@ -2081,17 +2074,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <source>Yes</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+0"/> - <source>No</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+12"/> + <location line="+13"/> <source>Unknown</source> <translation type="unfinished"></translation> </message> @@ -2163,12 +2146,12 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+78"/> + <location line="+75"/> <source>Requested payments history</source> <translation type="unfinished"></translation> </message> <message> - <location line="-98"/> + <location line="-95"/> <source>&Request payment</source> <translation type="unfinished"></translation> </message> @@ -2183,7 +2166,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+14"/> + <location line="+17"/> <source>Remove the selected entries from the list</source> <translation type="unfinished"></translation> </message> @@ -2221,12 +2204,12 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> + <location line="+10"/> <source>Copy &Address</source> <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> + <location line="+10"/> <source>&Save Image...</source> <translation type="unfinished"></translation> </message> @@ -2279,7 +2262,7 @@ Address: %4 <context> <name>RecentRequestsTableModel</name> <message> - <location filename="../recentrequeststablemodel.cpp" line="+24"/> + <location filename="../recentrequeststablemodel.cpp" line="+28"/> <source>Date</source> <translation type="unfinished">Date</translation> </message> @@ -2318,7 +2301,7 @@ Address: %4 <name>SendCoinsDialog</name> <message> <location filename="../forms/sendcoinsdialog.ui" line="+14"/> - <location filename="../sendcoinsdialog.cpp" line="+447"/> + <location filename="../sendcoinsdialog.cpp" line="+529"/> <source>Send Coins</source> <translation>Send Coins</translation> </message> @@ -2333,7 +2316,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> + <location line="+10"/> <source>automatically selected</source> <translation type="unfinished"></translation> </message> @@ -2388,7 +2371,98 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+206"/> + <source>Transaction Fee:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+14"/> + <source>Choose...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>collapse fee-settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Minimize</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+78"/> + <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 type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>per kilobyte</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+13"/> + <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 type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>total at least</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <location line="+13"/> + <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 type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>(read the tooltip)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+29"/> + <source>Recommended:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Custom:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+52"/> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+29"/> + <source>Confirmation time:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+60"/> + <source>normal</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+20"/> + <source>fast</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+38"/> + <source>Send as zero-fee transaction if possible</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>(confirmation may take longer)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+110"/> <source>Send to multiple recipients at once</source> <translation>Send to multiple recipients at once</translation> </message> @@ -2398,22 +2472,22 @@ Address: %4 <translation>Add &Recipient</translation> </message> <message> - <location line="-23"/> + <location line="-20"/> <source>Clear all fields of the form.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-271"/> + <location line="-858"/> <source>Dust:</source> <translation type="unfinished"></translation> </message> <message> - <location line="+274"/> + <location line="+861"/> <source>Clear &All</source> <translation>Clear &All</translation> </message> <message> - <location line="+58"/> + <location line="+55"/> <source>Balance:</source> <translation>Balance:</translation> </message> @@ -2428,12 +2502,12 @@ Address: %4 <translation>S&end</translation> </message> <message> - <location filename="../sendcoinsdialog.cpp" line="-215"/> + <location filename="../sendcoinsdialog.cpp" line="-221"/> <source>Confirm send coins</source> <translation>Confirm send coins</translation> </message> <message> - <location line="-74"/> + <location line="-77"/> <location line="+5"/> <location line="+5"/> <location line="+4"/> @@ -2441,7 +2515,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="-122"/> + <location line="-192"/> <source>Copy quantity</source> <translation type="unfinished"></translation> </message> @@ -2476,7 +2550,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+171"/> + <location line="+244"/> <source>Total Amount %1 (= %2)</source> <translation type="unfinished"></translation> </message> @@ -2486,7 +2560,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+189"/> + <location line="+192"/> <source>The recipient address is not valid, please recheck.</source> <translation>The recipient address is not valid, please recheck.</translation> </message> @@ -2521,7 +2595,22 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+113"/> + <location line="+4"/> + <source>A fee higher than %1 is considered an insanely high fee.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+87"/> + <source>Pay only the minimum fee of %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+22"/> + <source>Estimated to begin confirmation within %1 block(s).</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+107"/> <source>Warning: Invalid Bitcoin address</source> <translation type="unfinished"></translation> </message> @@ -2536,12 +2625,12 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="-504"/> + <location line="-687"/> <source>Copy dust</source> <translation type="unfinished"></translation> </message> <message> - <location line="+151"/> + <location line="+221"/> <source>Are you sure you want to send?</source> <translation type="unfinished"></translation> </message> @@ -2653,7 +2742,7 @@ Address: %4 <context> <name>ShutdownWindow</name> <message> - <location filename="../utilitydialog.cpp" line="+51"/> + <location filename="../utilitydialog.cpp" line="+47"/> <source>Bitcoin Core is shutting down...</source> <translation type="unfinished"></translation> </message> @@ -2671,7 +2760,7 @@ Address: %4 <translation>Signatures - Sign / Verify a Message</translation> </message> <message> - <location line="+10"/> + <location line="+13"/> <source>&Sign Message</source> <translation>&Sign Message</translation> </message> @@ -2848,7 +2937,7 @@ Address: %4 <context> <name>SplashScreen</name> <message> - <location filename="../splashscreen.cpp" line="+32"/> + <location filename="../splashscreen.cpp" line="+35"/> <source>Bitcoin Core</source> <translation type="unfinished">Bitcoin Core</translation> </message> @@ -2858,7 +2947,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> + <location filename="../networkstyle.cpp" line="+19"/> <source>[testnet]</source> <translation>[testnet]</translation> </message> @@ -2874,7 +2963,7 @@ Address: %4 <context> <name>TransactionDesc</name> <message> - <location filename="../transactiondesc.cpp" line="+33"/> + <location filename="../transactiondesc.cpp" line="+34"/> <source>Open until %1</source> <translation>Open until %1</translation> </message> @@ -3098,7 +3187,7 @@ Address: %4 <context> <name>TransactionTableModel</name> <message> - <location filename="../transactiontablemodel.cpp" line="+237"/> + <location filename="../transactiontablemodel.cpp" line="+229"/> <source>Date</source> <translation>Date</translation> </message> @@ -3113,7 +3202,7 @@ Address: %4 <translation>Address</translation> </message> <message> - <location line="+76"/> + <location line="+79"/> <source>Immature (%1 confirmations, will be available after %2)</source> <translation type="unfinished"></translation> </message> @@ -3166,7 +3255,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+51"/> + <location line="+48"/> <source>Received with</source> <translation>Received with</translation> </message> @@ -3191,12 +3280,17 @@ Address: %4 <translation>Mined</translation> </message> <message> - <location line="+41"/> + <location line="+28"/> + <source>watch-only</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+15"/> <source>(n/a)</source> <translation>(n/a)</translation> </message> <message> - <location line="+193"/> + <location line="+210"/> <source>Transaction status. Hover over this field to show number of confirmations.</source> <translation>Transaction status. Hover over this field to show number of confirmations.</translation> </message> @@ -3212,6 +3306,11 @@ Address: %4 </message> <message> <location line="+2"/> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> <source>Destination address of transaction.</source> <translation>Destination address of transaction.</translation> </message> @@ -3224,7 +3323,7 @@ Address: %4 <context> <name>TransactionView</name> <message> - <location filename="../transactionview.cpp" line="+60"/> + <location filename="../transactionview.cpp" line="+67"/> <location line="+16"/> <source>All</source> <translation>All</translation> @@ -3325,12 +3424,17 @@ Address: %4 <translation>Show transaction details</translation> </message> <message> - <location line="+163"/> + <location line="+179"/> <source>Export Transaction History</source> <translation type="unfinished"></translation> </message> <message> - <location line="+19"/> + <location line="+12"/> + <source>Watch-only</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+9"/> <source>Exporting Failed</source> <translation type="unfinished"></translation> </message> @@ -3350,7 +3454,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="-22"/> + <location line="-24"/> <source>Comma separated file (*.csv)</source> <translation>Comma separated file (*.csv)</translation> </message> @@ -3360,7 +3464,7 @@ Address: %4 <translation>Confirmed</translation> </message> <message> - <location line="+1"/> + <location line="+3"/> <source>Date</source> <translation>Date</translation> </message> @@ -3398,7 +3502,7 @@ Address: %4 <context> <name>UnitDisplayStatusBarControl</name> <message> - <location filename="../bitcoingui.cpp" line="+101"/> + <location filename="../bitcoingui.cpp" line="+106"/> <source>Unit to show amounts in. Click to select another unit.</source> <translation type="unfinished"></translation> </message> @@ -3414,7 +3518,7 @@ Address: %4 <context> <name>WalletModel</name> <message> - <location filename="../walletmodel.cpp" line="+280"/> + <location filename="../walletmodel.cpp" line="+276"/> <source>Send Coins</source> <translation>Send Coins</translation> </message> @@ -3432,7 +3536,7 @@ Address: %4 <translation>Export the data in the current tab to a file</translation> </message> <message> - <location line="+184"/> + <location line="+187"/> <source>Backup Wallet</source> <translation>Backup Wallet</translation> </message> @@ -3465,67 +3569,32 @@ Address: %4 <context> <name>bitcoin-core</name> <message> - <location filename="../bitcoinstrings.cpp" line="+249"/> + <location filename="../bitcoinstrings.cpp" line="+239"/> <source>Options:</source> <translation>Options:</translation> </message> <message> - <location line="+28"/> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Specify configuration file (default: bitcoin.conf)</translation> - </message> - <message> - <location line="+3"/> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Specify pid file (default: bitcoind.pid)</translation> - </message> - <message> - <location line="-1"/> + <location line="+31"/> <source>Specify data directory</source> <translation>Specify data directory</translation> </message> <message> - <location line="-44"/> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Listen for connections on <port> (default: 8333 or testnet: 18333)</translation> - </message> - <message> - <location line="+6"/> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Maintain at most <n> connections to peers (default: 125)</translation> - </message> - <message> - <location line="-62"/> + <location line="-91"/> <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="+103"/> + <location line="+94"/> <source>Specify your own public address</source> <translation>Specify your own public address</translation> </message> <message> - <location line="+7"/> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Threshold for disconnecting misbehaving peers (default: 100)</translation> - </message> - <message> - <location line="-181"/> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</translation> - </message> - <message> - <location line="-2"/> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</translation> - </message> - <message> - <location line="+59"/> + <location line="-109"/> <source>Accept command line and JSON-RPC commands</source> <translation>Accept command line and JSON-RPC commands</translation> </message> <message> - <location line="+99"/> + <location line="+90"/> <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> @@ -3535,12 +3604,12 @@ Address: %4 <translation>Use the test network</translation> </message> <message> - <location line="-134"/> + <location line="-125"/> <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="-154"/> + <location line="-153"/> <source>%s, you must set a rpcpassword in the configuration file: %s It is recommended you use the following random password: @@ -3565,27 +3634,22 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </translation> </message> <message> - <location line="+15"/> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+10"/> + <location line="+22"/> <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:15)</source> + <location line="+19"/> + <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> - <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> + <location line="+3"/> + <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <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> @@ -3600,37 +3664,22 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</translation> </message> <message> - <location line="+12"/> + <location line="+9"/> <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="+12"/> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+5"/> + <location line="+20"/> <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+15"/> + <location line="+20"/> <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="+3"/> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> + <location line="+6"/> <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> @@ -3640,12 +3689,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> + <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> @@ -3670,13 +3714,13 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>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.</translation> </message> <message> - <location line="+10"/> - <source>(default: 1)</source> + <location line="+4"/> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>(default: wallet.dat)</source> + <location line="+7"/> + <source>(default: 1)</source> <translation type="unfinished"></translation> </message> <message> @@ -3685,7 +3729,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <location line="+7"/> <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> @@ -3715,12 +3759,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> + <location line="+2"/> <source>Discover own IP address (default: 1 when listening and no -externalip)</source> <translation>Discover own IP address (default: 1 when listening and no -externalip)</translation> </message> @@ -3756,6 +3795,11 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <location line="+2"/> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source>Error: Disk space is low!</source> <translation>Error: Disk space is low!</translation> </message> @@ -3766,81 +3810,11 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <location line="+1"/> - <source>Error: system error: </source> - <translation>Error: system error: </translation> - </message> - <message> - <location line="+1"/> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Failed to listen on any port. Use -listen=0 if you want this.</translation> </message> <message> - <location line="+1"/> - <source>Failed to read block info</source> - <translation>Failed to read block info</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to read block</source> - <translation>Failed to read block</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to sync block index</source> - <translation>Failed to sync block index</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write block index</source> - <translation>Failed to write block index</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write block info</source> - <translation>Failed to write block info</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write block</source> - <translation>Failed to write block</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write file info</source> - <translation>Failed to write file info</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write to coin database</source> - <translation>Failed to write to coin database</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write transaction index</source> - <translation>Failed to write transaction index</translation> - </message> - <message> - <location line="+1"/> - <source>Failed to write undo data</source> - <translation>Failed to write undo data</translation> - </message> - <message> - <location line="+2"/> - <source>Force safe mode (default: 0)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> - <source>Generate coins (default: 0)</source> - <translation>Generate coins (default: 0)</translation> - </message> - <message> - <location line="+1"/> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>How many blocks to check at startup (default: 288, 0 = all)</translation> - </message> - <message> - <location line="+1"/> + <location line="+5"/> <source>If <category> is not supplied, output all debugging information.</source> <translation type="unfinished"></translation> </message> @@ -3865,17 +3839,17 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Not enough file descriptors available.</translation> </message> <message> - <location line="+5"/> - <source>Prepend debug output with timestamp (default: 1)</source> + <location line="+2"/> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> + <location line="+10"/> <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="+10"/> + <location line="+11"/> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation type="unfinished"></translation> </message> @@ -3885,32 +3859,22 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Set the number of threads to service RPC calls (default: 4)</translation> - </message> - <message> - <location line="+9"/> + <location line="+11"/> <source>Specify wallet file (within data directory)</source> <translation>Specify wallet file (within data directory)</translation> </message> <message> - <location line="+2"/> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> + <location line="+6"/> + <source>This is intended for regression testing tools and app development.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>Stop running after importing blocks from disk (default: 0)</source> + <location line="+10"/> + <source>Use UPnP to map the listening port (default: %u)</source> <translation type="unfinished"></translation> </message> <message> <location line="+4"/> - <source>This is intended for regression testing tools and app development.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+14"/> <source>Verifying blocks...</source> <translation>Verifying blocks...</translation> </message> @@ -3940,12 +3904,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Imports blocks from external blk000??.dat file</translation> </message> <message> - <location line="-195"/> - <source>(default: 1, 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="+6"/> + <location line="-182"/> <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> @@ -3970,17 +3929,17 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> - <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> + <location line="+3"/> + <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> - <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> + <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> <message> - <location line="+6"/> + <location line="+12"/> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation type="unfinished"></translation> </message> @@ -3991,11 +3950,6 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <location line="+3"/> - <source>Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> <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>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</translation> </message> @@ -4010,17 +3964,12 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> - <source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: 1)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+11"/> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> + <location line="+19"/> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> + <location line="+7"/> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation type="unfinished"></translation> </message> @@ -4030,32 +3979,27 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> - <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> + <location line="+5"/> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+13"/> - <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> + <location line="+6"/> + <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 type="unfinished"></translation> </message> <message> - <location line="+16"/> - <source>Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.</source> + <location line="+13"/> + <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"/> + <location line="+19"/> <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> <message> - <location line="+10"/> - <source>Always query for peer addresses via DNS lookup (default: 0)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+6"/> + <location line="+17"/> <source>Cannot resolve -whitebind address: '%s'</source> <translation type="unfinished"></translation> </message> @@ -4080,22 +4024,17 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> + <location line="+5"/> <source>Error: Unsupported argument -tor found, use -onion.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+14"/> + <location line="+3"/> <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> - <source>Include IP addresses in debug output (default: 0)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+2"/> + <location line="+9"/> <source>Information</source> <translation>Information</translation> </message> @@ -4131,31 +4070,11 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. </message> <message> <location line="+1"/> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+5"/> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Maintain a full transaction index (default: 0)</translation> - </message> - <message> - <location line="+2"/> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</translation> - </message> - <message> - <location line="+1"/> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</translation> - </message> - <message> - <location line="+1"/> + <location line="+10"/> <source>Need to specify a port with -whitebind: '%s'</source> <translation type="unfinished"></translation> </message> @@ -4165,27 +4084,12 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Only accept block chain matching built-in checkpoints (default: 1)</translation> - </message> - <message> - <location line="+1"/> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</translation> - </message> - <message> - <location line="+4"/> + <location line="+7"/> <source>Print block on startup, if found in block index</source> <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>Print block tree on startup (default: 0)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> + <location line="+2"/> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation type="unfinished"></translation> </message> @@ -4205,37 +4109,17 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <source>Relay and mine data carrier transactions (default: 1)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> - <source>Relay non-P2SH multisig (default: 1)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+2"/> + <location line="+8"/> <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> <message> - <location line="+6"/> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Set minimum block size in bytes (default: 0)</translation> - </message> - <message> - <location line="+2"/> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> + <location line="+1"/> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> + <location line="+9"/> <source>Show all debugging options (usage: --help -help-debug)</source> <translation type="unfinished"></translation> </message> @@ -4250,17 +4134,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Signing transaction failed</translation> </message> <message> - <location line="+2"/> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Specify connection timeout in milliseconds (default: 5000)</translation> - </message> - <message> - <location line="+7"/> - <source>System error: </source> - <translation>System error: </translation> - </message> - <message> - <location line="+2"/> + <location line="+10"/> <source>This is experimental software.</source> <translation type="unfinished"></translation> </message> @@ -4285,12 +4159,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Use UPnP to map the listening port (default: 0)</translation> - </message> - <message> - <location line="+1"/> + <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> @@ -4345,22 +4214,17 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Password for JSON-RPC connections</translation> </message> <message> - <location line="-164"/> + <location line="-160"/> <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="+210"/> + <location line="+206"/> <source>Upgrade wallet to latest format</source> <translation>Upgrade wallet to latest format</translation> </message> <message> - <location line="-27"/> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Set key pool size to <n> (default: 100)</translation> - </message> - <message> - <location line="-8"/> + <location line="-35"/> <source>Rescan the block chain for missing wallet transactions</source> <translation>Rescan the block chain for missing wallet transactions</translation> </message> @@ -4370,52 +4234,247 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Use OpenSSL (https) for JSON-RPC connections</translation> </message> <message> - <location line="-31"/> - <source>Server certificate file (default: server.cert)</source> - <translation>Server certificate file (default: server.cert)</translation> - </message> - <message> - <location line="+1"/> - <source>Server private key (default: server.pem)</source> - <translation>Server private key (default: server.pem)</translation> - </message> - <message> - <location line="+19"/> + <location line="-11"/> <source>This help message</source> <translation>This help message</translation> </message> <message> - <location line="-118"/> + <location line="-108"/> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> <translation>Allow DNS lookups for -addnode, -seednode and -connect</translation> </message> <message> - <location line="+68"/> + <location line="+60"/> <source>Loading addresses...</source> <translation>Loading addresses...</translation> </message> <message> - <location line="-42"/> + <location line="-34"/> <source>Error loading wallet.dat: Wallet corrupted</source> <translation>Error loading wallet.dat: Wallet corrupted</translation> </message> <message> - <location line="-1"/> + <location line="-170"/> + <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="+65"/> + <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"/> + <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+6"/> + <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> + <message> + <location line="+6"/> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+23"/> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+28"/> + <source>(default: %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>Acceptable ciphers (default: %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> + <source>Disable safemode, override a real safe mode event (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+8"/> <source>Error loading wallet.dat</source> <translation>Error loading wallet.dat</translation> </message> <message> - <location line="+33"/> + <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> + <message> + <location line="+1"/> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Include IP addresses in debug output (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+6"/> <source>Invalid -proxy address: '%s'</source> <translation>Invalid -proxy address: '%s'</translation> </message> <message> - <location line="+69"/> + <location line="+9"/> + <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> + <message> + <location line="+1"/> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <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"/> + <source>Prepend debug output with timestamp (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Print block tree on startup (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+6"/> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Relay non-P2SH multisig (default: %u)</source> + <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="+2"/> + <source>Set key pool size to <n> (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Set minimum block size in bytes (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <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="+4"/> + <source>Specify configuration file (default: %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Specify pid file (default: %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Stop running after importing blocks from disk (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Threshold for disconnecting misbehaving peers (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+6"/> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Unknown network specified in -onlynet: '%s'</translation> </message> <message> - <location line="-122"/> + <location line="-112"/> <source>Cannot resolve -bind address: '%s'</source> <translation>Cannot resolve -bind address: '%s'</translation> </message> @@ -4425,7 +4484,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Cannot resolve -externalip address: '%s'</translation> </message> <message> - <location line="+56"/> + <location line="+46"/> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> <translation>Invalid amount for -paytxfee=<amount>: '%s'</translation> </message> @@ -4440,22 +4499,22 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Insufficient funds</translation> </message> <message> - <location line="+13"/> + <location line="+15"/> <source>Loading block index...</source> <translation>Loading block index...</translation> </message> <message> - <location line="-70"/> + <location line="-62"/> <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="+71"/> + <location line="+63"/> <source>Loading wallet...</source> <translation>Loading wallet...</translation> </message> <message> - <location line="-66"/> + <location line="-58"/> <source>Cannot downgrade wallet</source> <translation>Cannot downgrade wallet</translation> </message> @@ -4465,22 +4524,22 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Cannot write default address</translation> </message> <message> - <location line="+86"/> + <location line="+76"/> <source>Rescanning...</source> <translation>Rescanning...</translation> </message> <message> - <location line="-73"/> + <location line="-63"/> <source>Done loading</source> <translation>Done loading</translation> </message> <message> - <location line="+101"/> + <location line="+91"/> <source>To use the %s option</source> <translation>To use the %s option</translation> </message> <message> - <location line="-93"/> + <location line="-83"/> <source>Error</source> <translation>Error</translation> </message> diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts index 652ee2d9bf..5189310e64 100644 --- a/src/qt/locale/bitcoin_eo.ts +++ b/src/qt/locale/bitcoin_eo.ts @@ -1,4 +1,4 @@ -<TS language="eo" version="2.1"> +<TS language="eo" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -371,10 +371,6 @@ <translation>Langeto-breto</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Kerno de Bitmono</translation> </message> @@ -410,10 +406,6 @@ <source>No block source available...</source> <translation>Neniu fonto de blokoj trovebla...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Traktis %1 blokoj de la transakcia historio.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n horo</numerusform><numerusform>%n horoj</numerusform></translation> @@ -545,10 +537,6 @@ Adreso: %4 <translation>Sumo</translation> </message> <message> - <source>Address</source> - <translation>Adreso</translation> - </message> - <message> <source>Date</source> <translation>Dato</translation> </message> @@ -856,15 +844,7 @@ Adreso: %4 <source>Error</source> <translation>Eraro</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB de libera loko disponebla</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(el %1GB bezonataj)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -899,14 +879,6 @@ Adreso: %4 <translation>Ĉ&efa</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Nedeviga krompago por ĉiu kB, kiu helpas plirapidigi la traktadon de via transakcio. Plej multaj transakcioj grandas je 1kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Krompago</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> @@ -1034,10 +1006,6 @@ Adreso: %4 <translation>Eblas, ke la informoj videblaj ĉi tie estas eksdataj. Via monujo aŭtomate sinkoniĝas kun la bitmona reto kiam ili konektiĝas, sed tiu procezo ankoraŭ ne finfariĝis.</translation> </message> <message> - <source>Wallet</source> - <translation>Monujo</translation> - </message> - <message> <source>Your current spendable balance</source> <translation>via aktuala elspezebla saldo</translation> </message> @@ -1062,10 +1030,6 @@ Adreso: %4 <translation>via aktuala totala saldo</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Lastaj transakcioj</b></translation> - </message> - <message> <source>out of sync</source> <translation>nesinkronigita</translation> </message> @@ -2199,26 +2163,10 @@ Adreso: %4 <translation>Agordoj:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Specifi konfiguran dosieron (defaŭlte: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Specifi pid-dosieron (defaŭlte: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Specifi dosieron por datumoj</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Aŭskulti al <port> por konektoj (defaŭlte: 8333 aŭ testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Subteni maksimume <n> konektojn al samtavolanoj (defaŭlte: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Konekti al nodo por ricevi adresojn de samtavolanoj, kaj malkonekti</translation> </message> @@ -2227,18 +2175,6 @@ Adreso: %4 <translation>Specifi vian propran publikan adreson</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Sojlo por malkonekti misagantajn samtavolanojn (defaŭlte: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Nombro da sekundoj por rifuzi rekonekton de misagantaj samtavolanoj (defaŭlte: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Aŭskulti al <port> por JSON-RPC-konektoj (defaŭlte: 8332 aŭ testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Akcepti komandojn JSON-RPC kaj el komandlinio</translation> </message> @@ -2279,10 +2215,6 @@ ekzemple: alertnotify=echo %%s | mail -s "Averto de Bitmono" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Akcepteblaj ĉifroj (defaŭlte: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Bindi al donita adreso kaj ĉiam aŭskulti per ĝi. Uzu la formaton [gastigo]:pordo por IPv6</translation> </message> @@ -2375,62 +2307,10 @@ ekzemple: alertnotify=echo %%s | mail -s "Averto de Bitmono" admin@foo.com <translation>Eraro: monujo ŝlosita, ne eblas krei transakcion!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Eraro: sistema eraro: </translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Ne sukcesis aŭskulti ajnan pordon. Uzu -listen=0 se tion vi volas.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Malsukcesis legi blokinformojn</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Malsukcesis legi blokon</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Malsukcesis sinkronigi blokindekson</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Malsukcesis skribi blokindekson</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Malsukcesis skribi blokinformojn</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Malsukcesis skribi blokon</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Malsukcesis skribi dosierinformojn</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Malsukcesis skribi Bitmon-datumbazon</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Malsukcesis skribi transakcian indekson</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Malsukcesis skribi malfarajn datumojn</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Generi Bitmonon (defaŭlte: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Kiom da blokoj kontrolendas dum lanĉo (defaŭlte: 288, 0=ĉiuj)</translation> - </message> - <message> <source>Incorrect or no genesis block found. Wrong datadir for network?</source> <translation>Geneza bloko aŭ netrovita aŭ neĝusta. Ĉu eble la datadir de la reto malĝustas?</translation> </message> @@ -2447,10 +2327,6 @@ ekzemple: alertnotify=echo %%s | mail -s "Averto de Bitmono" admin@foo.com <translation>Rekontrui blokĉenan indekson el la aktualaj blk000??.dat dosieroj</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Specifi la nombron de fadenoj por priatenti RPC-alvokojn (defaŭlte: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Specifi monujan dosieron (ene de dosierujo por datumoj)</translation> </message> @@ -2495,34 +2371,10 @@ ekzemple: alertnotify=echo %%s | mail -s "Averto de Bitmono" admin@foo.com <translation>Nevalida sumo por -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Varti kompletan transakcian indekton (defaŭlte: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maksimuma po riceva bufro por konektoj, <n>*1000 bajtoj (defaŭlte: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maksimuma po senda bufro por konektoj, <n>*1000 bajtoj (defaŭlte: 1000)</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Akcepti nur blokĉenon, kiu kongruas kun integritaj kontrolpunktoj (defaŭlte: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Konekti nur la nodoj en la reto <net> (IPv4, IPv6 aŭ Tor)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Sendi spurajn/sencimigajn informojn al la konzolo anstataŭ al dosiero debug.log</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Agordi minimuman grandon de blokoj je bajtoj (defaŭlte: 0)</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> @@ -2531,14 +2383,6 @@ ekzemple: alertnotify=echo %%s | mail -s "Averto de Bitmono" admin@foo.com <translation>Subskriba transakcio fiaskis</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Specifi konektan tempolimon je milisekundoj (defaŭlte: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Sistema eraro: </translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Transakcia sumo tro malgranda</translation> </message> @@ -2551,10 +2395,6 @@ ekzemple: alertnotify=echo %%s | mail -s "Averto de Bitmono" admin@foo.com <translation>Transakcio estas tro granda</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Uzi UPnP por mapi la aŭskultan pordon (defaŭlte: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Uzi UPnP por mapi la aŭskultan pordon (defaŭlte: 1 dum aŭskultado)</translation> </message> @@ -2587,10 +2427,6 @@ ekzemple: alertnotify=echo %%s | mail -s "Averto de Bitmono" admin@foo.com <translation>Ĝisdatigi monujon al plej lasta formato</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Agordi la grandon de la ŝlosilo-vico al <n> (defaŭlte: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Reskani la blokĉenon por mankantaj monujaj transakcioj</translation> </message> @@ -2599,14 +2435,6 @@ ekzemple: alertnotify=echo %%s | mail -s "Averto de Bitmono" admin@foo.com <translation>Uzi OpenSSL (https) por konektoj JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Dosiero de servila atestilo (defaŭlte: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Dosiero de servila privata ŝlosilo (defaŭlte: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Tiu ĉi helpmesaĝo</translation> </message> diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index fad8c9bbe8..b701366706 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -1,4 +1,4 @@ -<TS language="es" version="2.1"> +<TS language="es" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -391,10 +391,6 @@ <translation>Barra de pestañas</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -434,10 +430,6 @@ <source>No block source available...</source> <translation>Ninguna fuente de bloques disponible ...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Procesados %1 bloques del historial de transacciones.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation> @@ -486,6 +478,10 @@ <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> @@ -529,8 +525,8 @@ Dirección: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Selección de direcciones bajo Coin Control</translation> + <source>Coin Selection</source> + <translation>Selección de la moneda</translation> </message> <message> <source>Quantity:</source> @@ -581,8 +577,12 @@ Dirección: %4 <translation>Cantidad</translation> </message> <message> - <source>Address</source> - <translation>Dirección</translation> + <source>Received with label</source> + <translation>Recibido con etiqueta</translation> + </message> + <message> + <source>Received with address</source> + <translation>Recibido con dirección</translation> </message> <message> <source>Date</source> @@ -916,13 +916,13 @@ Dirección: %4 <source>Error</source> <translation>Error</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB de espacio libre disponible</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB de espacio libre</numerusform><numerusform>%n GB de espacio disponible</numerusform></translation> </message> - <message> - <source>(of %1GB needed)</source> - <translation>(de los %1GB necesarios)</translation> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(de %n GB necesitados)</numerusform><numerusform>(de %n GB requeridos)</numerusform></translation> </message> </context> <context> @@ -959,14 +959,6 @@ Dirección: %4 <translation>&Principal</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Comisión de transacción opcional por kB que ayuda a asegurar que sus transacciones sean procesadas rápidamente. La mayoría de transacciones son de 1kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Pagar comisión de &transacción</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> @@ -995,14 +987,6 @@ Dirección: %4 <translation>Aceptar conexiones entrantes</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Conectarse a la red Bitcoin a través de un proxy SOCKS.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Conectarse a través de proxy SOCKS (proxy predeterminado):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>Dirección IP del proxy (p. ej. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1063,6 +1047,14 @@ Dirección: %4 <translation>Mapear el puerto mediante &UPnP</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Conectarse a la red Bitcoin a través de un proxy SOCKS5.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Conectarse a través de proxy SOCKS5 (proxy predeterminado):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>Dirección &IP del proxy:</translation> </message> @@ -1166,10 +1158,6 @@ Dirección: %4 <translation>La información mostrada puede estar desactualizada. Su monedero se sincroniza automáticamente con la red Bitcoin después de que se haya establecido una conexión, pero este proceso aún no se ha completado.</translation> </message> <message> - <source>Wallet</source> - <translation>Monedero</translation> - </message> - <message> <source>Watch-only:</source> <translation>De observación:</translation> </message> @@ -1198,6 +1186,10 @@ Dirección: %4 <translation>Saldo recién minado que aún no ha madurado.</translation> </message> <message> + <source>Balances</source> + <translation>Saldos</translation> + </message> + <message> <source>Total:</source> <translation>Total:</translation> </message> @@ -1210,6 +1202,14 @@ Dirección: %4 <translation>Su saldo actual en direcciones watch-only</translation> </message> <message> + <source>Spendable:</source> + <translation>Gastable:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Transacciones recientes</translation> + </message> + <message> <source>Unconfirmed transactions to watch-only addresses</source> <translation>Transacciones sin confirmar en direcciones watch-only</translation> </message> @@ -1222,10 +1222,6 @@ Dirección: %4 <translation>Saldo total en las direcciones watch-only</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Transacciones recientes</b></translation> - </message> - <message> <source>out of sync</source> <translation>desincronizado</translation> </message> @@ -1485,10 +1481,6 @@ Dirección: %4 <translation>Servicios</translation> </message> <message> - <source>Sync Node</source> - <translation>Sincronizar Nodo</translation> - </message> - <message> <source>Starting Height</source> <translation>Altura de comienzo</translation> </message> @@ -1617,14 +1609,6 @@ Dirección: %4 <translation>Saliente</translation> </message> <message> - <source>Yes</source> - <translation>Sí</translation> - </message> - <message> - <source>No</source> - <translation>No</translation> - </message> - <message> <source>Unknown</source> <translation>Desconocido</translation> </message> @@ -1861,6 +1845,50 @@ Dirección: %4 <translation>Dirección propia</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Comisión de Transacción:</translation> + </message> + <message> + <source>Minimize</source> + <translation>Minimizar</translation> + </message> + <message> + <source>per kilobyte</source> + <translation>por kilobyte</translation> + </message> + <message> + <source>total at least</source> + <translation>total por lo menos</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Recomendado:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Personalizado:</translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation>(Tarifa inteligente no inicializado aún. Esto generalmente lleva a pocos bloques...)</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Tiempo de confirmación:</translation> + </message> + <message> + <source>normal</source> + <translation>normal</translation> + </message> + <message> + <source>fast</source> + <translation>rápido</translation> + </message> + <message> + <source>(confirmation may take longer)</source> + <translation>(confirmación puede tardar más tiempo)</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Enviar a múltiples destinatarios de una vez</translation> </message> @@ -1965,6 +1993,14 @@ 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>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> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Alerta: Dirección de Bitcoin inválida</translation> </message> @@ -2473,6 +2509,10 @@ Dirección: %4 <translation>Minado</translation> </message> <message> + <source>watch-only</source> + <translation>de observación</translation> + </message> + <message> <source>(n/a)</source> <translation>(nd)</translation> </message> @@ -2489,6 +2529,10 @@ Dirección: %4 <translation>Tipo de transacción.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <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> </message> @@ -2584,6 +2628,10 @@ Dirección: %4 <translation>Exportar historial de transacciones</translation> </message> <message> + <source>Watch-only</source> + <translation>De observación</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Error exportando</translation> </message> @@ -2700,28 +2748,10 @@ Dirección: %4 </translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Especificar archivo de configuración (predeterminado: bitcoin.conf) -</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Especificar archivo pid (predeterminado: bitcoin.pid) -</translation> - </message> - <message> <source>Specify data directory</source> <translation>Especificar directorio para los datos</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Escuchar conexiones en <puerto> (predeterminado: 8333 o testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Mantener como máximo <n> conexiones a pares (predeterminado: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Conectar a un nodo para obtener direcciones de pares y desconectar</translation> </message> @@ -2730,18 +2760,6 @@ Dirección: %4 <translation>Especifique su propia dirección pública</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Umbral para la desconexión de pares con mal comportamiento (predeterminado: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Número de segundos en que se evita la reconexión de pares con mal comportamiento (predeterminado: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Escuchar conexiones JSON-RPC en <puerto> (predeterminado: 8332 o testnet:18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Aceptar comandos consola y JSON-RPC </translation> @@ -2785,16 +2803,16 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Cifrados aceptables (predeterminados: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Vincular a la dirección dada y escuchar siempre en ella. Utilice la notación [host]:port para IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Limitar continuamente las transacciones gratuitas a <n>*1000 bytes por minuto (predeterminado:15)</translation> + <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> + <translation>Borrar todas las transacciones del monedero y sólo recuperar aquellas partes de la cadena de bloques por medio de -rescan on startup.</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>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> @@ -2813,14 +2831,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Volcar la actividad de la base de datos de memoria al registro en disco cada <n> megabytes (predeterminado: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Nivel de rigor en la verificación de bloques de -checkblocks (0-4; predeterminado: 3)</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> </message> @@ -2829,10 +2839,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Establecer el número de hilos (threads) de verificación de scripts (entre %u y %d, 0 = automático, <0 = dejar libres ese número de núcleos; predeterminado: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Establecer el límite de procesadores cuando está activada la generación (-1 = sin límite; predeterminado: -1)</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>Esta es una versión de pre-prueba - utilícela bajo su propio riesgo. No la utilice para usos comerciales o de minería.</translation> </message> @@ -2841,10 +2847,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>No se ha podido acceder a %s en esta máquina. Probablemente ya se está ejecutando Bitcoin Core.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Usar proxy SOCKS5 distinto para comunicarse vía Tor de forma anónima (Predeterminado: -proxy)</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> @@ -2865,12 +2867,12 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aviso: ¡Recuperados datos de wallet.dat corrupto! El wallet.dat original se ha guardado como wallet.{timestamp}.bak en %s; si hubiera errores en su saldo o transacciones, deberá restaurar una copia de seguridad.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(predeterminado: 1)</translation> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Poner en lista blanca a los equipos que se conecten desde la máscara de subred o dirección IP especificada. Se puede especificar múltiples veces.</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(predeterminado: wallet.dat)</translation> + <source>(default: 1)</source> + <translation>(predeterminado: 1)</translation> </message> <message> <source><category> can be:</source> @@ -2901,10 +2903,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Opciones de depuración/pruebas:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Inhabilitar el modo seguro, no considerar un suceso real de modo seguro (predeterminado: 0)</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> @@ -2933,6 +2931,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Error al abrir base de datos de bloques.</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Error: un error grave interno ocurrió, sea debug.log para más detalles.</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Error: ¡Espacio en disco bajo!</translation> </message> @@ -2941,66 +2943,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Error: ¡El monedero está bloqueado; no se puede crear la transacción!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Error: error de sistema: </translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Ha fallado la escucha en todos los puertos. Use -listen=0 si desea esto.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>No se ha podido leer la información de bloque</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>No se ha podido leer el bloque</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>No se ha podido sincronizar el índice de bloques</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>No se ha podido escribir en el índice de bloques</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>No se ha podido escribir la información de bloques</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>No se ha podido escribir el bloque</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>No se ha podido escribir la información de archivo</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>No se ha podido escribir en la base de datos de bitcoins</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>No se ha podido escribir en el índice de transacciones</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>No se han podido escribir los datos de deshacer</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Forzar modo seguro (predeterminado: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Generar bitcoins (predeterminado: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Cuántos bloques comprobar al iniciar (predeterminado: 288, 0 = todos)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Si no se proporciona <category>, mostrar toda la depuración</translation> </message> @@ -3021,8 +2967,8 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>No hay suficientes descriptores de archivo disponibles. </translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Anteponer marca temporal a la información de depuración (predeterminado: 1)</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <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> @@ -3037,22 +2983,18 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Establecer tamaño máximo de bloque en bytes (predeterminado: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Establecer el número de procesos para atender las llamadas RPC (predeterminado: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Especificar archivo de monedero (dentro del directorio de datos)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Gastar cambio no confirmado al enviar transacciones (predeterminado: 1)</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> + <message> <source>Verifying blocks...</source> <translation>Verificando bloques...</translation> </message> @@ -3077,16 +3019,56 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Importa los bloques desde un archivo blk000??.dat externo</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>Permitir conexiones JSON-RPC de origen especificado. Válido para son una sola IP (por ejemplo 1.2.3.4), una red/máscara de red (por ejemplo 1.2.3.4/255.255.255.0) o una red/CIDR (e.g. 1.2.3.4/24). Esta opción se puede especificar varias veces</translation> + </message> + <message> + <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> + <translation>Ocurrió un error al configurar la dirección de RPC %s puerto %u para escuchar en: %s</translation> + </message> + <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>Ligar a las direcciones especificadas y poner en lista blanca a los equipos conectados a ellas. Usar la notación para IPv6 [host]:puerto.</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>Ligar a las direcciones especificadas para escuchar por conexiones JSON-RPC. Usar la notación para IPv6 [host]:puerto. Esta opción se puede especificar múltiples veces (por defecto: ligar a todas las interfaces)</translation> + </message> + <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <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>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> + <message> + <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Error: Unsupported argumento -socks encontrados. SOCKS versión ajuste ya no es posible, sólo SOCKS5 proxies son compatibles.</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>Ejecutar un comando cuando se reciba una alerta importante o cuando veamos un fork demasiado largo (%s en cmd se reemplazará por el mensaje)</translation> </message> <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Mostrar información de depuración (predeterminado: 0, proporcionar <category> es opcional)</translation> + <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> + <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>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>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3101,6 +3083,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aviso: ¡Comprueba la fecha y hora de tu ordenador y verifica si es correcta! Si no es correcta Bitcoin Core no funcionará adecuadamente.</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>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>Connect through SOCKS5 proxy</source> <translation>Conectar usando SOCKS5 proxy</translation> </message> @@ -3109,10 +3095,22 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation> </message> <message> + <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> + <translation>Error al cargar wallet.dat: El monedero requiere una versión más reciente de Bitcoin Core</translation> + </message> + <message> + <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> + <translation>Cuota (in BTC/kB) para añadir a las transacciones que envíes (por defecto: %s)</translation> + </message> + <message> <source>Information</source> <translation>Información</translation> </message> <message> + <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source> + <translation>La inicialización de la verificación de validez falló. Se está apagando Bitcoin Core.</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Cantidad inválida para -minrelaytxfee=<amount>: '%s'</translation> </message> @@ -3121,42 +3119,34 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Cantidad inválida para -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Limitar tamaño de la cache de firmas a <n> entradas (predeterminado: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Registrar en el log la prioridad de transacciones y la comisión por kB al minar bloques (predeterminado: 0)</translation> + <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> + <translation>Cantidad inválida para -paytxfee=<amount>: '%s' (debe ser por lo menos %s)</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Mantener índice de transacciones completo (predeterminado: 0)</translation> + <source>Invalid netmask specified in -whitelist: '%s'</source> + <translation>Máscara de red inválida especificada en -whitelist: '%s'</translation> </message> <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Búfer de recepción máximo por conexión, <n>*1000 bytes (predeterminado: 5000)</translation> + <source>Keep at most <n> unconnectable blocks in memory (default: %u)</source> + <translation>Mantener como máximo <n> bloques no conectables en memoria (por defecto: %u)</translation> </message> <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Búfer de recepción máximo por conexión, , <n>*1000 bytes (predeterminado: 1000)</translation> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Mantener como máximo <n> transacciones no conectables en memoria (por defecto: %u)</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Aceptar solamente cadena de bloques que concuerde con los puntos de control internos (predeterminado: 1)</translation> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>Necesita especificar un puerto con -whitebind: '%s'</translation> </message> <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Conectarse solo a nodos de la red <net> (IPv4, IPv6 o Tor)</translation> + <source>Node relay options:</source> + <translation>Opciones de nodos de retransmisión:</translation> </message> <message> <source>Print block on startup, if found in block index</source> <translation>Imprimir bloque al iniciar, si se encuentra en el índice de bloques</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Imprimir árbol de bloques al iniciar (predeterminado: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Opciones SSL de RPC: (véase la wiki de Bitcoin para las instrucciones de instalación de SSL)</translation> </message> @@ -3173,22 +3163,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Introducir datos fuzz en 1 de cada <n> mensajes de red al azar</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Ejecutar un hilo (thread) para limpiar de la memoria el monedero periódicamente (predeterminado: 1)</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 minimum block size in bytes (default: 0)</source> - <translation>Establecer tamaño mínimo de bloque en bytes (predeterminado: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Establece la opción DB_PRIVATE en el entorno de base de datos del monedero (predeterminado: 1)</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> @@ -3201,14 +3179,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transacción falló</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Especificar el tiempo máximo de conexión en milisegundos (predeterminado: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Error de sistema: </translation> - </message> - <message> <source>This is experimental software.</source> <translation>Este software es experimental.</translation> </message> @@ -3225,8 +3195,8 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transacción demasiado grande</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Usar UPnP para asignar el puerto de escucha (predeterminado: 0)</translation> + <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> <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> @@ -3238,6 +3208,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> + <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source> + <translation>Monedero es necesario volver a escribir: reiniciar Bitcoin Core para completar</translation> + </message> + <message> <source>Warning</source> <translation>Aviso</translation> </message> @@ -3246,6 +3220,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aviso: Esta versión es obsoleta, actualización necesaria!</translation> </message> <message> + <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Aviso: Argumento no sportado -debugnet anticuado, utilice -debug=net.</translation> + </message> + <message> <source>Zapping all transactions from wallet...</source> <translation>Eliminando todas las transacciones del monedero...</translation> </message> @@ -3271,11 +3249,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Actualizar el monedero al último formato</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Ajustar el número de claves en reserva <n> (predeterminado: 100) -</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Volver a examinar la cadena de bloques en busca de transacciones del monedero perdidas</translation> </message> @@ -3285,16 +3258,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Certificado del servidor (predeterminado: server.cert) -</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Clave privada del servidor (predeterminado: server.pem) -</translation> - </message> - <message> <source>This help message</source> <translation>Este mensaje de ayuda </translation> @@ -3312,14 +3275,166 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Error al cargar wallet.dat: el monedero está dañado</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> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Número de segundos en que se evita la reconexión de pares con mal comportamiento (predeterminado: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Mostrar depuración (por defecto: %u, proporcionar <category> es opcional)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Usar distintos proxys SOCKS5 para comunicarse vía Tor de forma anónima (Por defecto: %s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(predeterminado: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Aceptar cifrado (por defecto: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <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> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Cuántos bloques comprobar al iniciar (predeterminado: %u, 0 = todos)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Incluir direcciones IP en la salida de depuración (por defecto: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <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> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Escuchar conexiones en <puerto> (predeterminado: %u o testnet: %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Mantener como máximo <n> conexiones a pares (predeterminado: %u)</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> + <message> + <source>Maximum per-connection send 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> + <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> + <message> + <source>Print block tree on startup (default: %u)</source> + <translation>Imprimir árbol de bloques al iniciar (predeterminado: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Retransmitir y minar transacciones de transporte de datos (por defecto: %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> + <message> + <source>Server private key (default: %s)</source> + <translation>Llave privada del servidor (por defecto: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Ajustar el número de claves en reserva <n> (predeterminado: %u)</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Establecer tamaño mínimo de bloque en bytes (por defecto: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <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> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Especificar tiempo de espera de la conexión (mínimo: 1, por defecto: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Especificar archivo pid (predeterminado: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <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> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>La red especificada en -onlynet '%s' es desconocida</translation> </message> @@ -3369,7 +3484,7 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Done loading</source> - <translation>Generado pero no aceptado</translation> + <translation>Se terminó de cargar</translation> </message> <message> <source>To use the %s option</source> diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index b22ad3fb8e..e6f81e650f 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> @@ -274,10 +274,6 @@ <source>Tabs toolbar</source> <translation>Barra de pestañas</translation> </message> - <message> - <source>[testnet]</source> - <translation>[red-de-pruebas]</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> @@ -360,10 +356,6 @@ Dirección: %4</translation> <translation>Cantidad</translation> </message> <message> - <source>Address</source> - <translation>Dirección</translation> - </message> - <message> <source>Date</source> <translation>Fecha</translation> </message> @@ -483,10 +475,6 @@ Dirección: %4</translation> <translation>&Principal</translation> </message> <message> - <source>Pay transaction &fee</source> - <translation>Comisión de &transacciónes</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> @@ -574,18 +562,10 @@ Dirección: %4</translation> <translation>Formulario</translation> </message> <message> - <source>Wallet</source> - <translation>Cartera</translation> - </message> - <message> <source>Total:</source> <translation>Total:</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Transacciones recientes</b></translation> - </message> - <message> <source>out of sync</source> <translation>desincronizado</translation> </message> @@ -1280,37 +1260,11 @@ Dirección: %4</translation> </translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Especifica archivo de configuración (predeterminado: bitcoin.conf) -</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Especifica archivo pid (predeterminado: bitcoin.pid) -</translation> - </message> - <message> <source>Specify data directory</source> <translation>Especifica directorio para los datos </translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Escuchar por conecciones en <puerto> (Por defecto: 8333 o red de prueba: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Mantener al menos <n> conecciones por cliente (por defecto: 125) </translation> - </message> - <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Umbral de desconección de clientes con mal comportamiento (por defecto: 100)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Escucha conexiones JSON-RPC en el puerto <port> (predeterminado: 8332 or testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Aceptar comandos consola y JSON-RPC </translation> @@ -1343,34 +1297,6 @@ Dirección: %4</translation> <translation>Atención: Poco espacio en el disco duro</translation> </message> <message> - <source>Error: system error: </source> - <translation>Error: error de sistema:</translation> - </message> - <message> - <source>Failed to read block info</source> - <translation>Falló la lectura de la información del bloque</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Falló la lectura del bloque</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Falló sincronización del índice del bloque</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Falló la escritura del bloque del índice</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Falló la escritura de la información del bloque</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Falló la escritura del bloque</translation> - </message> - <message> <source>Imports blocks from external blk000??.dat file</source> <translation>Importar bloques desde el archivo externo blk000??.dat </translation> </message> @@ -1383,22 +1309,6 @@ Dirección: %4</translation> <translation>Enviar informacion de seguimiento a la consola en vez del archivo debug.log</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Establezca el tamaño mínimo del bloque en bytes (por defecto: 0)</translation> - </message> - <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Especifica tiempo de espera para conexion en milisegundos (predeterminado: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Error de sistema:</translation> - </message> - <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Intenta usar UPnP para mapear el puerto de escucha (default: 0)</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> @@ -1429,11 +1339,6 @@ Dirección: %4</translation> <translation>Actualizar billetera al formato actual</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Ajusta el numero de claves en reserva <n> (predeterminado: 100) -</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Rescanea la cadena de bloques para transacciones perdidas de la cartera </translation> @@ -1444,16 +1349,6 @@ Dirección: %4</translation> </translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Certificado del servidor (Predeterminado: server.cert) -</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Clave privada del servidor (Predeterminado: server.pem) -</translation> - </message> - <message> <source>This help message</source> <translation>Este mensaje de ayuda </translation> diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts index a9cfe90895..2e5daf4cdb 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> @@ -375,10 +375,6 @@ <translation>Barra de pestañas</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Núcleo de Bitcoin</translation> </message> @@ -411,10 +407,6 @@ <translation>Ninguna fuente de bloques disponible ...</translation> </message> <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Procesados %1 bloques del historial de transacciones.</translation> - </message> - <message> <source>%1 behind</source> <translation>%1 atrás</translation> </message> @@ -485,10 +477,6 @@ Dirección: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Selección de la dirección de control de la moneda</translation> - </message> - <message> <source>Quantity:</source> <translation>Cantidad:</translation> </message> @@ -533,10 +521,6 @@ Dirección: %4 <translation>Cantidad</translation> </message> <message> - <source>Address</source> - <translation>Dirección</translation> - </message> - <message> <source>Date</source> <translation>Fecha</translation> </message> @@ -848,15 +832,7 @@ Dirección: %4 <source>Error</source> <translation>Error</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB de espacio libre disponible</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(de los %1GB necesarios)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -891,14 +867,6 @@ Dirección: %4 <translation>&Principal</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Tarifa de transacción opcional por kB que ayuda a asegurar que sus transacciones sean procesadas rápidamente. La mayoría de transacciones son de 1kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Comisión de &transacciones</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> @@ -911,10 +879,6 @@ Dirección: %4 <translation>MB</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Conéctese a la red Bitcoin través de un proxy SOCKS.</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>Dirección IP del proxy (ej. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1042,10 +1006,6 @@ Dirección: %4 <translation>La información mostrada puede estar desactualizada. Su monedero se sincroniza automáticamente con la red Bitcoin después de que se haya establecido una conexión, pero este proceso aún no se ha completado.</translation> </message> <message> - <source>Wallet</source> - <translation>Monedero</translation> - </message> - <message> <source>Your current spendable balance</source> <translation>Su balance actual gastable</translation> </message> @@ -1070,10 +1030,6 @@ Dirección: %4 <translation>Su balance actual total</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Movimientos recientes</b></translation> - </message> - <message> <source>out of sync</source> <translation>desincronizado</translation> </message> @@ -2244,28 +2200,10 @@ Dirección: %4 </translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Especificar archivo de configuración (predeterminado: bitcoin.conf) -</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Especificar archivo pid (predeterminado: bitcoin.pid) -</translation> - </message> - <message> <source>Specify data directory</source> <translation>Especificar directorio para los datos</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Escuchar conexiones en <puerto> (predeterminado: 8333 o testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Mantener como máximo <n> conexiones a pares (predeterminado: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Conectar a un nodo para obtener direcciones de pares y desconectar</translation> </message> @@ -2274,18 +2212,6 @@ Dirección: %4 <translation>Especifique su propia dirección pública</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Umbral para la desconexión de pares con mal comportamiento (predeterminado: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Número de segundos en que se evita la reconexión de pares con mal comportamiento (predeterminado: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Escuchar conexiones JSON-RPC en <puerto> (predeterminado: 8332 o testnet:18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Aceptar comandos consola y JSON-RPC </translation> @@ -2329,10 +2255,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Cifradores aceptables (por defecto: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Vincular a la dirección dada y escuchar siempre en ella. Utilice la notación [host]:port para IPv6</translation> </message> @@ -2353,10 +2275,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Esta es una versión de pre-prueba - utilícela bajo su propio riesgo. No la utilice para usos comerciales o de minería.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Usar distintos proxys SOCKS5 para comunicarse vía Tor de forma anónima (Por defecto: -proxy)</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> @@ -2429,62 +2347,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Error: ¡El monedero está bloqueado; no se puede crear la transacción!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Error: error de sistema: </translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Ha fallado la escucha en todos los puertos. Use -listen=0 si desea esto.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>No se ha podido leer la información de bloque</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>No se ha podido leer el bloque</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>No se ha podido sincronizar el índice de bloques</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>No se ha podido escribir en el índice de bloques</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>No se ha podido escribir la información de bloques</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>No se ha podido escribir el bloque</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>No se ha podido escribir la información de archivo</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>No se ha podido escribir en la base de datos de monedas</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>No se ha podido escribir en el índice de transacciones</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>No se han podido escribir los datos de deshacer</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Generar monedas (por defecto: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Cuántos bloques comprobar al iniciar (predeterminado: 288, 0 = todos)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Si no se proporciona <category>, mostrar toda la depuración</translation> </message> @@ -2501,10 +2367,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>No hay suficientes descriptores de archivo disponibles. </translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Anteponer marca temporal a la información de depuración (por defecto: 1)</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> @@ -2513,10 +2375,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Establecer tamaño máximo de bloque en bytes (por defecto: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Establecer el número de hilos para atender las llamadas RPC (predeterminado: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Especificar archivo de monedero (dentro del directorio de datos)</translation> </message> @@ -2545,10 +2403,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ejecutar un comando cuando se reciba una alerta importante o cuando veamos un fork demasiado largo (%s en cmd se reemplazará por el mensaje)</translation> </message> <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Mostrar depuración (por defecto: 0, proporcionar <category> es opcional)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Establecer tamaño máximo de las transacciones de alta prioridad/comisión baja en bytes (por defecto: %d)</translation> </message> @@ -2565,34 +2419,10 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Inválido por el monto -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Mantener índice de transacciones completo (predeterminado: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Búfer de recepción máximo por conexión, <n>*1000 bytes (predeterminado: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Búfer de recepción máximo por conexión, , <n>*1000 bytes (predeterminado: 1000)</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Aceptar solamente cadena de bloques que concuerde con los puntos de control internos (predeterminado: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Conectarse solo a nodos de la red <net> (IPv4, IPv6 o Tor)</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 minimum block size in bytes (default: 0)</source> - <translation>Establecer tamaño mínimo de bloque en bytes (predeterminado: 0)</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> @@ -2601,14 +2431,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transacción falló</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Especificar el tiempo máximo de conexión en milisegundos (predeterminado: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Error de sistema: </translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Monto de la transacción muy pequeño</translation> </message> @@ -2621,10 +2443,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transacción demasiado grande</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Usar UPnP para asignar el puerto de escucha (predeterminado: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Usar UPnP para asignar el puerto de escucha (predeterminado: 1 al escuchar)</translation> </message> @@ -2659,11 +2477,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Actualizar el monedero al último formato</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Ajustar el número de claves en reserva <n> (predeterminado: 100) -</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Volver a examinar la cadena de bloques en busca de transacciones del monedero perdidas</translation> </message> @@ -2673,16 +2486,6 @@ Por ejemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Certificado del servidor (predeterminado: server.cert) -</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Clave privada del servidor (predeterminado: server.pem) -</translation> - </message> - <message> <source>This help message</source> <translation>Este mensaje de ayuda </translation> diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts index c89ac5c6ef..bedc5d243e 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> @@ -397,10 +397,6 @@ <translation>Monto</translation> </message> <message> - <source>Address</source> - <translation>Domicilio</translation> - </message> - <message> <source>Date</source> <translation>Fecha</translation> </message> @@ -569,10 +565,6 @@ <source>Form</source> <translation>Formulario</translation> </message> - <message> - <source><b>Recent transactions</b></source> - <translation><b>Transacciones recientes</b></translation> - </message> </context> <context> <name>PaymentServer</name> diff --git a/src/qt/locale/bitcoin_es_UY.ts b/src/qt/locale/bitcoin_es_UY.ts index 321e5312ad..a5a1583b19 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> @@ -162,10 +162,6 @@ <source>Tabs toolbar</source> <translation>Barra de herramientas</translation> </message> - <message> - <source>[testnet]</source> - <translation>[prueba_de_red]</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> @@ -201,10 +197,6 @@ <context> <name>CoinControlDialog</name> <message> - <source>Address</source> - <translation>Direccion </translation> - </message> - <message> <source>Date</source> <translation>Fecha</translation> </message> @@ -277,10 +269,6 @@ <source>Form</source> <translation>Formulario</translation> </message> - <message> - <source><b>Recent transactions</b></source> - <translation><b>Transacciones recientes</b></translation> - </message> </context> <context> <name>PaymentServer</name> diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index cd3a39b6b9..801fcf6258 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> @@ -311,10 +311,6 @@ <translation>Vahelehe tööriistariba</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoini tuumik</translation> </message> @@ -322,10 +318,6 @@ <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> - <source>Processed %1 blocks of transaction history.</source> - <translation>Protsessitud %1 tehingute ajaloo blokki.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n tund</numerusform><numerusform>%n tundi</numerusform></translation> @@ -416,10 +408,6 @@ Aadress: %4⏎</translation> <translation>Kogus</translation> </message> <message> - <source>Address</source> - <translation>Aadress</translation> - </message> - <message> <source>Date</source> <translation>Kuupäev</translation> </message> @@ -558,10 +546,6 @@ Aadress: %4⏎</translation> <translation>Valikud</translation> </message> <message> - <source>Pay transaction &fee</source> - <translation>Tasu tehingu &fee</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>Käivita Bitcoin süsteemi logimisel.</translation> </message> @@ -673,10 +657,6 @@ Aadress: %4⏎</translation> <translation>Kuvatav info ei pruugi olla ajakohane. Ühenduse loomisel süngitakse sinu rahakott automaatselt Bitconi võrgustikuga, kuid see toiming on hetkel lõpetamata.</translation> </message> <message> - <source>Wallet</source> - <translation>Rahakott</translation> - </message> - <message> <source>Immature:</source> <translation>Ebaküps:</translation> </message> @@ -685,10 +665,6 @@ Aadress: %4⏎</translation> <translation>Mitte aegunud mine'itud jääk</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Uuesti saadetud tehingud</b></translation> - </message> - <message> <source>out of sync</source> <translation>sünkimata</translation> </message> @@ -1494,26 +1470,10 @@ Aadress: %4⏎</translation> <translation>Valikud:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Täpsusta sätete fail (vaikimisi: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Täpsusta PID fail (vaikimisi: bitcoin.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Täpsusta andmekataloog</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Kuula ühendusi pordil <port> (vaikeväärtus: 8333 või testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Säilita vähemalt <n> ühendust peeridega (vaikeväärtus: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Peeri aadressi saamiseks ühendu korraks node'iga</translation> </message> @@ -1522,18 +1482,6 @@ Aadress: %4⏎</translation> <translation>Täpsusta enda avalik aadress</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Ulakate peeride valulävi (vaikeväärtus: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Mitme sekundi pärast ulakad peerid tagasi võivad tulla (vaikeväärtus: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Kuula JSON-RPC ühendusel seda porti <port> (vaikeväärtus: 8332 või testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Luba käsurea ning JSON-RPC käsklusi</translation> </message> @@ -1654,66 +1602,14 @@ nt: alertnotify=echo %%s | email -s "Bitcoin Alert" admin@foo.com <translation>Tõrge: Rahakott on lukus, tehingu loomine ei ole võimalik!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Tõrge: süsteemi tõrge:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Pordi kuulamine nurjus. Soovikorral kasuta -listen=0.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Tõrge bloki sisu lugemisel</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Bloki lugemine ebaõnnestus</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Bloki indeksi sünkimine ebaõnnestus</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Bloki indeksi kirjutamine ebaõnnestus</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Bloki sisu kirjutamine ebaõnnestus</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Tõrge bloki sisu kirjutamisel</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Tõrge faili info kirjutamisel</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Tõrge mündi andmebaasi kirjutamisel</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Tehingu indeksi kirjutamine ebaõnnestus</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Tagasivõtmise andmete kirjutamine ebaõnnestus</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Käivitamisel kontrollitavate blokkide arv (vaikeväärtus: 288, 0=kõik)</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>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Määra RPC kõnede haldurite arv (vaikeväärtus: 4)</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>Kontrollin blokke...</translation> </message> @@ -1730,50 +1626,14 @@ nt: alertnotify=echo %%s | email -s "Bitcoin Alert" admin@foo.com <translation>Informatsioon</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Säilita kogu tehingu indeks (vaikeväärtus: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maksimaalne saamise puhver -connection kohta , <n>*1000 baiti (vaikeväärtus: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maksimaalne saatmise puhver -connection kohta , <n>*1000 baiti (vaikeväärtus: 1000)</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Tunnusta ainult sisseehitatud turvapunktidele vastavaid bloki jadu (vaikeväärtus: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Ühenda ainult node'idega <net> võrgus (IPv4, IPv6 või Tor)</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 minimum block size in bytes (default: 0)</source> - <translation>Sea minimaalne bloki suurus baitides (vaikeväärtus: 0)</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>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Sea ühenduse timeout millisekundites (vaikeväärtus: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Süsteemi tõrge:</translation> - </message> - <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Kasuta kuulatava pordi määramiseks UPnP ühendust (vaikeväärtus: 0)</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> @@ -1806,10 +1666,6 @@ nt: alertnotify=echo %%s | email -s "Bitcoin Alert" admin@foo.com <translation>Uuenda rahakott uusimasse vormingusse</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Sea võtmete hulgaks <n> (vaikeväärtus: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Otsi ploki jadast rahakoti kadunud tehinguid</translation> </message> @@ -1818,14 +1674,6 @@ nt: alertnotify=echo %%s | email -s "Bitcoin Alert" admin@foo.com <translation>Kasuta JSON-RPC ühenduste jaoks OpenSSL'i (https)</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Serveri sertifikaadifail (vaikeväärtus: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Serveri privaatvõti (vaikeväärtus: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Käesolev abitekst</translation> </message> diff --git a/src/qt/locale/bitcoin_eu_ES.ts b/src/qt/locale/bitcoin_eu_ES.ts index f8f03c3d29..ea0ce1a67d 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> @@ -175,10 +175,6 @@ <translation>Fitxen tresna-barra</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Up to date</source> <translation>Egunean</translation> </message> @@ -217,10 +213,6 @@ <translation>Kopurua</translation> </message> <message> - <source>Address</source> - <translation>Helbidea</translation> - </message> - <message> <source>Date</source> <translation>Data</translation> </message> @@ -305,10 +297,6 @@ <source>Form</source> <translation>Inprimakia</translation> </message> - <message> - <source><b>Recent transactions</b></source> - <translation><b>Azken transakzioak</b></translation> - </message> </context> <context> <name>PaymentServer</name> @@ -695,14 +683,6 @@ <translation>Aukerak</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Ezarpen fitxategia aukeratu (berezkoa: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>pid fitxategia aukeratu (berezkoa: bitcoind.pid)</translation> - </message> - <message> <source>This help message</source> <translation>Laguntza mezu hau</translation> </message> diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index d806fa47ef..475515f4b7 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -1,4 +1,4 @@ -<TS language="fa" version="2.1"> +<TS language="fa" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -10,6 +10,10 @@ <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> @@ -61,6 +65,10 @@ <source>Comma separated file (*.csv)</source> <translation>پروندهٔ نوع CSV جداشونده با کاما (*.csv)</translation> </message> + <message> + <source>Exporting Failed</source> + <translation>استخراج انجام نشد</translation> + </message> </context> <context> <name>AddressTableModel</name> @@ -327,10 +335,6 @@ <translation>نوارابزار برگهها</translation> </message> <message> - <source>[testnet]</source> - <translation>[شبکهٔ آزمایش]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation> هسته Bitcoin </translation> </message> @@ -342,10 +346,6 @@ <source>No block source available...</source> <translation>منبعی برای دریافت بلاک در دسترس نیست...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>%1 بلاک از تاریخچهٔ تراکنشها پردازش شده است.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n ساعت</numerusform></translation> @@ -437,10 +437,6 @@ Address: %4 <translation>مبلغ</translation> </message> <message> - <source>Address</source> - <translation>نشانی</translation> - </message> - <message> <source>Date</source> <translation>تاریخ</translation> </message> @@ -612,15 +608,7 @@ Address: %4 <source>Error</source> <translation>خطا</translation> </message> - <message> - <source>GB of free space available</source> - <translation>گیگابات فضا موجود است</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(از %1 گیگابایت فضای مورد نیاز)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> </context> @@ -635,14 +623,6 @@ Address: %4 <translation>&عمومی</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>کارمزد اختیاریِ هر کیلوبایت برای انتقال سریعتر تراکنش. اکثر تراکنشها ۱ کیلوبایتی هستند.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>پرداخت &کارمزد تراکنش</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>اجرای خودکار بیتکوین در زمان ورود به سیستم.</translation> </message> @@ -762,10 +742,6 @@ Address: %4 <translation>اطلاعات نمایشداده شده ممکن است قدیمی باشند. بعد از این که یک اتصال با شبکه برقرار شد، کیف پول شما بهصورت خودکار با شبکهٔ بیتکوین همگامسازی میشود. اما این روند هنوز کامل نشده است.</translation> </message> <message> - <source>Wallet</source> - <translation>کیف پول</translation> - </message> - <message> <source>Available:</source> <translation>در دسترس:</translation> </message> @@ -794,10 +770,6 @@ Address: %4 <translation>تراز کل فعلی شما</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>تراکنشهای اخیر</b></translation> - </message> - <message> <source>out of sync</source> <translation>ناهمگام</translation> </message> @@ -924,6 +896,10 @@ Address: %4 <source>Type <b>help</b> for an overview of available commands.</source> <translation>برای نمایش یک مرور کلی از دستورات ممکن، عبارت <b>help</b> را بنویسید.</translation> </message> + <message> + <source>Unknown</source> + <translation>ناشناخته</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -1544,6 +1520,10 @@ Address: %4 <translation>نمایش جزئیات تراکنش</translation> </message> <message> + <source>Exporting Failed</source> + <translation>استخراج انجام نشد</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>پروندهٔ نوع CSV جداشونده با کاما (*.csv)</translation> </message> @@ -1627,26 +1607,10 @@ Address: %4 <translation>گزینهها:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>مشخص کردن فایل پیکربندی (پیشفرض: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>مشخص کردن فایل شناسهٔ پردازش - pid - (پیشفرض: bitcoin.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>مشخص کردن دایرکتوری دادهها</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>پذیرش اتصالات روی پورت <port> (پیشفرض: 8833 یا شبکهٔ آزمایشی: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>حداکثر <n> اتصال با همتایان برقرار شود (پیشفرض: ۱۲۵)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>اتصال به یک گره برای دریافت آدرسهای همتا و قطع اتصال پس از اتمام عملیات</translation> </message> @@ -1655,18 +1619,6 @@ Address: %4 <translation>آدرس عمومی خود را مشخص کنید</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>حد آستانه برای قطع ارتباط با همتایان بدرفتار (پیشفرض: ۱۰۰)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>مدت زمان جلوگیری از اتصال مجدد همتایان بدرفتار، به ثانیه (پیشفرض: ۸۴۶۰۰)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>پورت مورد شنود برای اتصالات JSON-RPC (پیشفرض: 8332 برای شبکهٔ تست 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>پذیرش دستورات خط فرمان و دستورات JSON-RPC</translation> </message> @@ -1739,58 +1691,10 @@ Address: %4 <translation>خطا در بازگشایی پایگاه داده ی بلوک</translation> </message> <message> - <source>Error: system error: </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>Failed to read block info</source> - <translation>خواندن اطلاعات بلوک با شکست مواجه شد</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>خواندن بلوک با شکست مواجه شد</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>همگام سازی فهرست بلوک با شکست مواجه شد</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>نوشتن فهرست بلوک با شکست مواجه شد</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>نوشتن اطلاعات بلوک با شکست مواجه شد</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>نوشتن بلوک با شکست مواجه شد</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>نوشتن اطلاعات پرونده با شکست مواجه شد</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>نوشتن اطلاعات در پایگاه داده ی سکه ها با شکست مواجه شد</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>نوشتن فهرست تراکنش ها با شکست مواجه شد</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>عملیات بازگشت دادن اطلاعات با شکست مواجه شدن</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>چند بلوک نیاز است که در ابتدای راه اندازی بررسی شوند(پیش فرض:288 ،0=همه)</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>در حال بازبینی بلوک ها...</translation> </message> @@ -1803,42 +1707,14 @@ Address: %4 <translation>اطلاعات</translation> </message> <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>حداکثر بافر دریافت شده بر اساس اتصال <n>* 1000 بایت (پیش فرض:5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>حداکثر بافر دریافت شده بر اساس اتصال <n>* 1000 بایت (پیش فرض:1000)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>تنها =به گره ها در شبکه متصا شوید <net> (IPv4, IPv6 or Tor)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>اطلاعات ردگیری/اشکالزدایی را به جای فایل لاگ اشکالزدایی به کنسول بفرستید</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>حداقل سایز بلاک بر اساس بایت تنظیم شود (پیش فرض: 0)</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>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>(میلی ثانیه )فاصله ارتباط خاص</translation> - </message> - <message> - <source>System error: </source> - <translation>خطای سامانه</translation> - </message> - <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>از UPnP برای شناسایی درگاه شنیداری استفاده کنید (پیش فرض:0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>از UPnP برای شناسایی درگاه شنیداری استفاده کنید (پیش فرض:1 در زمان شنیدن)</translation> </message> @@ -1867,10 +1743,6 @@ Address: %4 <translation>wallet را به جدیدترین فرمت روزآمد کنید</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation> (100پیش فرض:)&lt;n&gt; گذاشتن اندازه کلید روی </translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>اسکان مجدد زنجیر بلوکها برای گم والت معامله</translation> </message> @@ -1879,14 +1751,6 @@ Address: %4 <translation>JSON-RPCبرای ارتباطات استفاده کنید OpenSSL (https)</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation> (server.certپیش فرض: )گواهی نامه سرور</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>(server.pemپیش فرض: ) کلید خصوصی سرور</translation> - </message> - <message> <source>This help message</source> <translation>پیام کمکی</translation> </message> diff --git a/src/qt/locale/bitcoin_fa_IR.ts b/src/qt/locale/bitcoin_fa_IR.ts index 92e0722767..1a639a8592 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> @@ -235,10 +235,6 @@ <translation>نوار ابزار</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Error</source> <translation>خطا</translation> </message> @@ -294,10 +290,6 @@ Address: %4 <translation>میزان</translation> </message> <message> - <source>Address</source> - <translation>حساب</translation> - </message> - <message> <source>Date</source> <translation>تاریخ</translation> </message> @@ -420,14 +412,6 @@ Address: %4 <translation>اطلاعات نمایش داده شده ممکن است روزآمد نباشد. wallet شما به صورت خودکار بعد از برقراری اتصال با شبکه bitcoin به روز می شود اما این فرایند هنوز تکمیل نشده است.</translation> </message> <message> - <source>Wallet</source> - <translation>کیف پول</translation> - </message> - <message> - <source><b>Recent transactions</b></source> - <translation>تراکنشهای اخیر</translation> - </message> - <message> <source>out of sync</source> <translation>خارج از روزآمد سازی</translation> </message> @@ -938,38 +922,10 @@ Address: %4 <translation>انتخابها:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>فایل پیکربندیِ را مشخص کنید (پیش فرض: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>فایل pid را مشخص کنید (پیش فرض: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>دایرکتوری داده را مشخص کن</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>ارتباطات را در <PORT> بشنوید (پیش فرض: 8333 or testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>نگهداری <N> ارتباطات برای قرینه سازی (پیش فرض:125)</translation> - </message> - <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>آستانه قطع برای قرینه سازی اشتباه (پیش فرض:100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>تعداد ثانیه ها برای اتصال دوباره قرینه های اشتباه (پیش فرض:86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>ارتباطاتِ JSON-RPC را در <port> گوش کنید (پیش فرض:8332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>command line و JSON-RPC commands را قبول کنید</translation> </message> @@ -986,10 +942,6 @@ Address: %4 <translation>ارسال اطلاعات پیگیری/خطایابی به کنسول به جای ارسال به فایل debug.log</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>تعیین مدت زمان وقفه (time out) به هزارم ثانیه</translation> - </message> - <message> <source>Username for JSON-RPC connections</source> <translation>شناسه کاربری برای ارتباطاتِ JSON-RPC</translation> </message> @@ -1006,10 +958,6 @@ Address: %4 <translation>wallet را به جدیدترین نسخه روزآمد کنید</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>حجم key pool را به اندازه <n> تنظیم کنید (پیش فرض:100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>زنجیره بلاک را برای تراکنش جا افتاده در WALLET دوباره اسکن کنید</translation> </message> @@ -1018,14 +966,6 @@ Address: %4 <translation>برای ارتباطاتِ JSON-RPC از OpenSSL (https) استفاده کنید</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>فایل certificate سرور (پیش فرض server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>رمز اختصاصی سرور (پیش فرض: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>این پیام راهنما</translation> </message> diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index 3541c58fcf..9a2eadd6ea 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -1,4 +1,4 @@ -<TS language="fi" version="2.1"> +<TS language="fi" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -391,10 +391,6 @@ <translation>Välilehtipalkki</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin-ydin</translation> </message> @@ -434,10 +430,6 @@ <source>No block source available...</source> <translation>Lohkojen lähdettä ei saatavilla...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Käsitelty %1 lohkoa rahansiirtohistoriasta</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n tunti</numerusform><numerusform>%n tuntia</numerusform></translation> @@ -528,10 +520,6 @@ Osoite: %4</translation> <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Kolikkokontrollin osoitteen valinta</translation> - </message> - <message> <source>Quantity:</source> <translation>Määrä:</translation> </message> @@ -580,10 +568,6 @@ Osoite: %4</translation> <translation>Määrä</translation> </message> <message> - <source>Address</source> - <translation>Osoite</translation> - </message> - <message> <source>Date</source> <translation>Aika</translation> </message> @@ -915,15 +899,7 @@ Osoite: %4</translation> <source>Error</source> <translation>Virhe</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB vapaata tilaa</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(tarvitaan %1GB)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -958,14 +934,6 @@ Osoite: %4</translation> <translation>&Yleiset</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Valinnainen rahansiirtopalkkio per kB auttaa varmistamaan että rahansiirtosi prosessoidaan nopeasti. Useimmat rahansiirrot ovat alle 1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Maksa rahansiirtopalkkio</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>Käynnistä Bitcoin kirjautumisen yhteydessä.</translation> </message> @@ -994,14 +962,6 @@ Osoite: %4</translation> <translation>Hyväksy sisääntulevia yhteyksiä</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Yhdistä Bitcoin-verkkoon SOCKS proxyn kautta.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Yhdistä SOCKS proxyn kautta (oletus proxy):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>IP osoite proxille (esim. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1165,10 +1125,6 @@ Osoite: %4</translation> <translation>Näytetyt tiedot eivät välttämättä ole ajantasalla. Lompakkosi synkronoituu Bitcoin-verkon kanssa automaattisesti yhteyden muodostamisen jälkeen, mutta synkronointi on vielä meneillään.</translation> </message> <message> - <source>Wallet</source> - <translation>Lompakko</translation> - </message> - <message> <source>Watch-only:</source> <translation>Seuranta:</translation> </message> @@ -1209,8 +1165,8 @@ Osoite: %4</translation> <translation>Nykyinen tase seurantaosoitetteissa</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Viimeisimmät rahansiirrot</b></translation> + <source>Current total balance in watch-only addresses</source> + <translation>Nykyinen tase seurantaosoitetteissa</translation> </message> <message> <source>out of sync</source> @@ -1228,6 +1184,14 @@ Osoite: %4</translation> <translation>Virheellinen maksuosoite %1</translation> </message> <message> + <source>Payment request rejected</source> + <translation>Maksupyyntö hylätty</translation> + </message> + <message> + <source>Payment request has expired.</source> + <translation>Maksupyyntö on vanhentunut.</translation> + </message> + <message> <source>Requested payment amount of %1 is too small (considered dust).</source> <translation>Maksupyyntö %1 on liian pieni (huomioidaan tomuna).</translation> </message> @@ -1244,6 +1208,10 @@ Osoite: %4</translation> <translation>Maksupyynnön haku URL on virheellinen: %1</translation> </message> <message> + <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> + <translation>URIa ei voitu jäsentää! Tämä voi johtua kelvottomasta Bitcoin-osoitteesta tai virheellisistä URI parametreista.</translation> + </message> + <message> <source>Payment request file handling</source> <translation>Maksupyynnön tiedoston käsittely</translation> </message> @@ -1274,6 +1242,10 @@ Osoite: %4</translation> </context> <context> <name>PeerTableModel</name> + <message> + <source>User Agent</source> + <translation>Käyttöliittymä</translation> + </message> </context> <context> <name>QObject</name> @@ -1282,6 +1254,10 @@ Osoite: %4</translation> <translation>Määrä</translation> </message> <message> + <source>%1 d</source> + <translation>%1 d</translation> + </message> + <message> <source>%1 h</source> <translation>%1 h</translation> </message> @@ -1290,10 +1266,18 @@ Osoite: %4</translation> <translation>%1 m</translation> </message> <message> + <source>%1 s</source> + <translation>%1 s</translation> + </message> + <message> <source>N/A</source> <translation>Ei saatavilla</translation> </message> - </context> + <message> + <source>%1 ms</source> + <translation>%1 ms</translation> + </message> +</context> <context> <name>QRImageWidget</name> <message> @@ -1368,6 +1352,22 @@ Osoite: %4</translation> <translation>Nykyinen Lohkojen määrä</translation> </message> <message> + <source>Received</source> + <translation>Vastaanotetut</translation> + </message> + <message> + <source>Sent</source> + <translation>Lähetetyt</translation> + </message> + <message> + <source>Version</source> + <translation>Versio</translation> + </message> + <message> + <source>User Agent</source> + <translation>Käyttöliittymä</translation> + </message> + <message> <source>Last block time</source> <translation>Viimeisimmän lohkon aika</translation> </message> @@ -1443,6 +1443,10 @@ Osoite: %4</translation> <source>%1 GB</source> <translation>%1 GB</translation> </message> + <message> + <source>Unknown</source> + <translation>Tuntematon</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -2482,26 +2486,10 @@ Osoite: %4</translation> <translation>Asetukset:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Määritä asetustiedosto (oletus: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Määritä pid-tiedosto (oletus: bitcoin.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Määritä data-hakemisto</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Kuuntele yhteyksiä portista <port> (oletus: 8333 tai testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Pidä enintään <n> yhteyttä verkkoihin (oletus: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Yhdistä noodiin hakeaksesi naapurien osoitteet ja katkaise yhteys</translation> </message> @@ -2510,18 +2498,6 @@ Osoite: %4</translation> <translation>Määritä julkinen osoitteesi</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Kynnysarvo aikakatkaisulle heikosti toimiville verkoille (oletus: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Sekuntien määrä, kuinka kauan uudelleenkytkeydytään verkkoihin (oletus: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Kuuntele JSON-RPC -yhteyksiä portista <port> (oletus: 8332 or testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Hyväksy merkkipohjaiset- ja JSON-RPC-käskyt</translation> </message> @@ -2562,18 +2538,10 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Hyväksytyt koodit (oletus: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Kytkeydy annettuun osoitteeseen ja pidä linja aina auki. Käytä [host]:portin merkintätapaa IPv6:lle.</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Yhtäaikaisesti rajaa vapaat rahansiirrot <n>*1000 tavua per minuutti (oletus: 15)</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> @@ -2590,14 +2558,6 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Suorita käsky kun lompakossa rahansiirto muuttuu (%s cmd on vaihdettu TxID kanssa)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Aja tietokannan toimet muistivarannosta kovalevylogiin joka <n> megatavu (oletus: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Kuinka vaativa lohkonvarmistus -checkblocks on (0-4, oletus: 3)</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> @@ -2606,10 +2566,6 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aseta script varmistuksen threadien lukumäärä (%u - %d, 0= auto, <0 = jätä näin monta ydintä vapaaksi, oletus: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Aseta prosessorin raja kun luonti on päällä (-1 = rajoittamaton, oletus: -1)</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>Tämä on esi-julkaistu testiversio - Käytä omalla riskillä - Ei saa käytää louhimiseen tai kauppasovelluksiin.</translation> </message> @@ -2618,10 +2574,6 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ei voida yhdistää %s tässä tietokoneessa. Bitcoin Core on luultavasti jo käynnissä.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Käytä erillistä SOCKS5 proxya tavoittaaksesi vertaiset Tor palvelun kautta (oletus: -proxy)</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>Varoitus: -paytxfee on asetettu erittäin korkeaksi! Tämä on maksukulu jonka tulet maksamaan kun lähetät siirron.</translation> </message> @@ -2646,10 +2598,6 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(oletus: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(oletus: wallet.dat)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> voi olla:</translation> </message> @@ -2678,10 +2626,6 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Debuggaus/Testauksen valinnat:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Poista safemode, ohita oikea turvallinen mooditapahtuma (oletus: 0)</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> @@ -2718,66 +2662,10 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Virhe: Lompakko on lukittu, rahansiirtoa ei voida luoda</translation> </message> <message> - <source>Error: system error: </source> - <translation>Virhe: Järjestelmävirhe</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Ei onnistuttu kuuntelemaan missään portissa. Käytä -listen=0 jos haluat tätä.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Lohkotietojen luku epäonnistui</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Lohkon luku epäonnistui</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Lohkoindeksin synkronointi epäonnistui</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Lohkoindeksin kirjoitus epäonnistui</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Lohkotiedon kirjoitus epäonnistui</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Lohkon kirjoitus epäonnistui</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Tiedoston tietojen kirjoitus epäonnistui</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Kolikkotietokannan kirjoitus epäonnistui</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Rahasiirtojen indeksin kirjoitus epäonnistui</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Palautustiedon kirjoitus epäonnistui</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Pakota safe moodi (oletus: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Generoi kolikoita (vakio: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Kuinka monta lohkoa tarkistetaan käynnistettäessä (oletus: 288, 0 = kaikki)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Jos <kategoria> ei annettu, tulosta kaikki debuggaustieto.</translation> </message> @@ -2798,10 +2686,6 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ei tarpeeksi tiedostomerkintöjä vapaana.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Lisää aikamerkki debug tulosteen eteen (oletus: 1)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files</source> <translation>Uudelleenrakenna lohkoketjuindeksi nykyisistä blk000??.dat tiedostoista</translation> </message> @@ -2814,18 +2698,10 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aseta lohkon maksimikoko tavuissa (oletus: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Aseta threadien lukumäärä RPC kutsuille (oletus: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Aseta lompakkotiedosto (data-hakemiston sisällä)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Käytä varmistamattomia vaihtorahoja lähetettäessä rahansiirtoja (oletus: 1)</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> @@ -2862,62 +2738,38 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aja komento kun olennainen hälytys vastaanotetaan tai nähdään todella pitkä haara (%s komennossa korvataan viestillä)</translation> </message> <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Tulosta debuggaustieto (oletus: 0, annettu <kategoria> valinnainen)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Aseta maksimikoko korkea prioriteetti/pieni palkkio rahansiirtoihin tavuissa (oletus: %d)</translation> </message> <message> - <source>Information</source> - <translation>Tietoa</translation> - </message> - <message> - <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> - <translation>Virheellinen määrä -minrelaytxfee=<amount>: '%s'</translation> - </message> - <message> - <source>Invalid amount for -mintxfee=<amount>: '%s'</source> - <translation>Virheellinen määrä -mintxfee=<amount>: '%s'</translation> - </message> - <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Rajaa allekirjoituksen välimuistin koko <n> alkioon (oletus: 50000)</translation> + <source>Connect through SOCKS5 proxy</source> + <translation>Yhdistä SOCKS5 proxin kautta</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Kirjaa rahansiirron prioriteetti ja palkkio per kB kun louhitaan lohkoja (oletus: 0)</translation> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Copyright (C) 2009-%i Bitcoin kehittäjät</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Ylläpidä täydellistä rahasiirtojen indeksiä (oletus: 0)</translation> + <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> + <translation>Virhe ladattaessa wallet.dat-tiedostoa: Tarvitset uudemman version Bitcoinista</translation> </message> <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Suurin vastaanottopuskuri yksittäiselle yhteydelle, <n>*1000 tavua (vakioasetus: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Suurin lähetyspuskuri yksittäiselle yhteydelle, <n>*1000 tavua (vakioasetus: 1000)</translation> + <source>Information</source> + <translation>Tietoa</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Hyväksy vain lohkoketjua vastaavat sisäänrakennetut varmistuspisteet (Oletus: 1)</translation> + <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> + <translation>Virheellinen määrä -minrelaytxfee=<amount>: '%s'</translation> </message> <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Yhdistä vain noodeihin verkossa <net> (IPv4, IPv6 tai Tor)</translation> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>Virheellinen määrä -mintxfee=<amount>: '%s'</translation> </message> <message> <source>Print block on startup, if found in block index</source> <translation>Tulosta lohko käynnistyksessä jos löydetään lohkoindeksistä</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Tulosta lohkopuu käynnistyksessä (oletus: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>RPC SSL valinnat: (katso Bitcoin Wikistä SSL-asennuksen ohjeet)</translation> </message> @@ -2934,22 +2786,10 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Satunnaisesti sekoita 1 joka <n> verkkoviestistä</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Aja threadi jossa tallennetaan lompakko ajoittain (oletus: 1)</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 minimum block size in bytes (default: 0)</source> - <translation>Asetan pienin lohkon koko tavuissa (vakioasetus: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Asettaa DB_PRIVATE lipun lompakon tietokantaympäristössä (oletus: 1)</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> @@ -2962,14 +2802,6 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Siirron vahvistus epäonnistui</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Määritä yhteyden aikakataisu millisekunneissa (vakioasetus: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Järjestelmävirhe:</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Siirtosumma liian pieni</translation> </message> @@ -2982,10 +2814,6 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Siirtosumma liian iso</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Käytä UPnP:tä kuunneltavan portin avaamiseen (vakioasetus: 0)</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> @@ -2994,6 +2822,10 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Käyttäjätunnus JSON-RPC-yhteyksille</translation> </message> <message> + <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source> + <translation>Lompakko tarvitsee uudelleenkirjoittaa: käynnistä Bitcoin uudelleen</translation> + </message> + <message> <source>Warning</source> <translation>Varoitus</translation> </message> @@ -3026,10 +2858,6 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Päivitä lompakko uusimpaan formaattiin</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Aseta avainpoolin koko arvoon <n> (oletus: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Skannaa uudelleen lohkoketju lompakon puuttuvien rahasiirtojen vuoksi</translation> </message> @@ -3038,14 +2866,6 @@ esimerkiksi: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Käytä OpenSSL:ää (https) JSON-RPC-yhteyksille</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Palvelimen sertifikaatti-tiedosto (oletus: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Palvelimen yksityisavain (oletus: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Tämä ohjeviesti</translation> </message> diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index dfd7081593..71a1519411 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> @@ -391,10 +391,6 @@ <translation>Barre d'outils des onglets</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -434,10 +430,6 @@ <source>No block source available...</source> <translation>Aucune source de blocs disponible...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>À traité %1 blocs de l'historique des transactions.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n heure</numerusform><numerusform>%n heures</numerusform></translation> @@ -486,6 +478,10 @@ <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> @@ -529,8 +525,8 @@ Adresse : %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Sélection de l'adresse de contrôle des pièces</translation> + <source>Coin Selection</source> + <translation>Sélection des pièces</translation> </message> <message> <source>Quantity:</source> @@ -581,8 +577,12 @@ Adresse : %4 <translation>Montant</translation> </message> <message> - <source>Address</source> - <translation>Adresse</translation> + <source>Received with label</source> + <translation>Reçu avec une étiquette</translation> + </message> + <message> + <source>Received with address</source> + <translation>Reçu avec une adresse</translation> </message> <message> <source>Date</source> @@ -912,15 +912,11 @@ Adresse : %4 <source>Error</source> <translation>Erreur</translation> </message> - <message> - <source>GB of free space available</source> - <translation>Go d'espace libre disponible</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(sur %1Go nécessaires)</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n Go d'espace libre disponible</numerusform><numerusform>%n Go d'espace libre disponibles</numerusform></translation> </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -955,14 +951,6 @@ Adresse : %4 <translation>Réglages &principaux</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Frais de transaction optionnel par ko qui aident à garantir un traitement rapide des transactions. La plupart des transactions utilisent 1 ko.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Payer des &frais de transaction</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> @@ -991,14 +979,6 @@ Adresse : %4 <translation>Permettre les transactions entrantes</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Se connecter au réseau Bitcoin par un mandataire SOCKS.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>Se &connecter par un mandataire SOCKS (mandataire par défaut) :</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>Adresse IP du mandataire (par ex. IPv4 : 127.0.0.1 / IPv6 : ::1)</translation> </message> @@ -1059,6 +1039,14 @@ Adresse : %4 <translation>Mapper le port avec l'&UPnP</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Se connecter au réseau Bitcoin par un mandataire SOCKS5.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>Se &connecter par un mandataire SOCKS5 (mandataire par défaut) :</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>&IP du serveur mandataire :</translation> </message> @@ -1162,10 +1150,6 @@ Adresse : %4 <translation>Les informations affichées peuvent être obsolètes. Votre portefeuille est automatiquement synchronisé avec le réseau Bitcoin lorsque la connexion s'établit, or ce processus n'est pas encore terminé.</translation> </message> <message> - <source>Wallet</source> - <translation>Portefeuille</translation> - </message> - <message> <source>Watch-only:</source> <translation>Juste-regarder :</translation> </message> @@ -1194,6 +1178,10 @@ Adresse : %4 <translation>Le solde généré n'est pas encore mûr</translation> </message> <message> + <source>Balances</source> + <translation>Soldes</translation> + </message> + <message> <source>Total:</source> <translation>Total :</translation> </message> @@ -1206,6 +1194,14 @@ Adresse : %4 <translation>Votre balance actuelle en adresses juste-regarder</translation> </message> <message> + <source>Spendable:</source> + <translation>Disponible :</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Transactions récentes</translation> + </message> + <message> <source>Unconfirmed transactions to watch-only addresses</source> <translation>Transactions non confirmées vers des adresses juste-regarder</translation> </message> @@ -1218,10 +1214,6 @@ Adresse : %4 <translation>Solde total actuel dans des adresses juste-regarder</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Transactions récentes</b></translation> - </message> - <message> <source>out of sync</source> <translation>désynchronisé</translation> </message> @@ -1481,10 +1473,6 @@ Adresse : %4 <translation>Services</translation> </message> <message> - <source>Sync Node</source> - <translation>Nœud de synchro</translation> - </message> - <message> <source>Starting Height</source> <translation>Hauteur de démarrage</translation> </message> @@ -1613,14 +1601,6 @@ Adresse : %4 <translation>Sortant</translation> </message> <message> - <source>Yes</source> - <translation>Oui</translation> - </message> - <message> - <source>No</source> - <translation>Non</translation> - </message> - <message> <source>Unknown</source> <translation>Inconnu</translation> </message> @@ -1857,6 +1837,78 @@ Adresse : %4 <translation>Adresse personnalisée de monnaie rendue</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Frais de transaction :</translation> + </message> + <message> + <source>Choose...</source> + <translation>Choisir...</translation> + </message> + <message> + <source>collapse fee-settings</source> + <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> + <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 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>total at least</source> + <translation>total au moins</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>Il est correct de payer les frais minimum tant que le volume transactionnel est inférieur à l'espace dans les blocs. Mais soyez conscient que ceci pourrait résulter en une transaction n'étant jamais confirmée une fois qu'il y aura plus de transactions que le réseau ne pourra en traiter.</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(lire l'infobulle)</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Recommandés :</translation> + </message> + <message> + <source>Custom:</source> + <translation>Personnalisés : </translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation>(Les frais intelligents ne sont pas encore initialisés. Ceci prend habituellement quelques blocs...)</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Temps de confirmation :</translation> + </message> + <message> + <source>normal</source> + <translation>normal</translation> + </message> + <message> + <source>fast</source> + <translation>rapide</translation> + </message> + <message> + <source>Send as zero-fee transaction if possible</source> + <translation>Envoyer si possible une transaction sans frais</translation> + </message> + <message> + <source>(confirmation may take longer)</source> + <translation>(la confirmation pourrait prendre plus longtemps)</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Envoyer à plusieurs destinataires à la fois</translation> </message> @@ -1961,6 +2013,18 @@ 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> + </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> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Avertissement : adresse Bitcoin invalide</translation> </message> @@ -2469,6 +2533,10 @@ Adresse : %4 <translation>Miné</translation> </message> <message> + <source>watch-only</source> + <translation>juste-regarder</translation> + </message> + <message> <source>(n/a)</source> <translation>(n.d)</translation> </message> @@ -2485,6 +2553,10 @@ Adresse : %4 <translation>Type de transaction.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <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> </message> @@ -2580,6 +2652,10 @@ Adresse : %4 <translation>Exporter l'historique des transactions</translation> </message> <message> + <source>Watch-only</source> + <translation>Juste-regarder :</translation> + </message> + <message> <source>Exporting Failed</source> <translation>L'exportation a échoué</translation> </message> @@ -2695,26 +2771,10 @@ Adresse : %4 <translation>Options :</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Spécifier le fichier de configuration (par défaut : bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Spécifier le fichier PID (par défaut : bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Spécifier le répertoire de données</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Écouter les connexions sur le <port> (par défaut : 8333 ou testnet : 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Garder au plus <n> connexions avec les pairs (par défaut : 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Se connecter à un nœud pour obtenir des adresses de pairs puis se déconnecter</translation> </message> @@ -2723,18 +2783,6 @@ Adresse : %4 <translation>Spécifier votre propre adresse publique</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Seuil de déconnexion des pairs de mauvaise qualité (par défaut : 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Délai en secondes de refus de reconnexion aux pairs de mauvaise qualité (par défaut : 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Écouter les connexions JSON-RPC sur le <port> (par défaut : 8332 ou tesnet : 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Accepter les commandes de JSON-RPC et de la ligne de commande</translation> </message> @@ -2775,22 +2823,18 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Chiffrements acceptables (par défaut : TLSv1.2+HIGH : TLSv1+HIGH : !SSLv2 : !aNULL : !eNULL : !3DES : @STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Se lier à l'adresse donnée et toujours l'écouter. Utilisez la notation [host]:port pour l'IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Limiter continuellement les transactions gratuites à <n>*1000 octets par minute (par défaut : 15)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Supprimer toutes les transactions du portefeuille et ne récupérer que ces parties de la chaîne de bloc avec -rescan au démarrage</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>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> @@ -2807,14 +2851,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Exécuter la commande lorsqu'une transaction de portefeuille change (%s dans la commande est remplacée par TxID)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Purger l’activité de la base de données de la mémoire vers le journal sur disque tous les <n> mégaoctets (par défaut : 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>À quel point la vérification des blocs -checkblocks est approfondie (0-4, par défaut : 3)</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> </message> @@ -2823,10 +2859,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Définir le nombre d'exétrons de vérification des scripts (%u à %d, 0 = auto, < 0 = laisser ce nombre de cœurs inutilisés, par défaut : %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Définir la limite processeur définissant quand la génération est en fonction (-1 = illimité, par défaut : -1)</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>Ceci est une pré-version de test - l'utiliser à vos risques et périls - ne pas l'utiliser pour miner ou pour des applications marchandes</translation> </message> @@ -2835,10 +2867,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Impossible de se lier à %s sur cet ordinateur. Bitcoin Core fonctionne probablement déjà.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Utiliser un serveur mandataire SOCKS5 séparé pour atteindre les pairs par les services cachés de Tor (par défaut : -proxy)</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> @@ -2859,12 +2887,12 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Avertissement : wallet.dat corrompu, données récupérées ! Le fichier wallet.dat original a été enregistré en tant que wallet.{timestamp}.bak dans %s ; si votre solde ou transactions sont incorrects vous devriez effectuer une restauration depuis une sauvegarde.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(par défaut : 1)</translation> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Pairs de la liste blanche se connectant à partir du masque réseau ou de l'IP donné. Peut être spécifié plusieurs fois.</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(par défaut : wallet.dat)</translation> + <source>(default: 1)</source> + <translation>(par défaut : 1)</translation> </message> <message> <source><category> can be:</source> @@ -2895,10 +2923,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Options de test/de débogage :</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Désactiver le mode sans échec, passer outre un événement sans échec réel (par défaut : 0)</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> @@ -2927,6 +2951,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Erreur lors de l'ouverture de la base de données des blocs</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Erreur : une erreur interne fatale s'est produite. Voir debug.log pour des détails</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Erreur : l'espace disque est faible !</translation> </message> @@ -2935,66 +2963,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Erreur : Portefeuille verrouillé, impossible de créer la transaction !</translation> </message> <message> - <source>Error: system error: </source> - <translation>Erreur : erreur système :</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Échec de l'écoute sur un port quelconque. Utilisez -listen=0 si vous voulez ceci.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>La lecture des informations de bloc a échoué</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>La lecture du bloc a échoué</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>La synchronisation de l'index des blocs a échoué</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>L''écriture de l'index des blocs a échoué</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>L'écriture des informations du bloc a échoué</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>L'écriture du bloc a échoué</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>L'écriture des informations de fichier a échoué</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>L'écriture dans la base de données des pièces a échoué</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>L'écriture de l'index des transactions a échoué</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>L'écriture des données d'annulation a échoué</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Forcer le mode sans échec (par défaut : 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Générer des pièces (défaut : 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Nombre de blocs à vérifier au démarrage (par défaut : 288, 0 = tout)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Si <category> n'est pas indiqué, extraire toutes les données de débogage.</translation> </message> @@ -3015,8 +2987,8 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Pas assez de descripteurs de fichiers de disponibles.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Ajouter l'horodatage au début des résultats de débogage (par défaut : 1)</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <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> @@ -3031,26 +3003,18 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Définir la taille minimale de bloc en octets (par défaut : %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Définir le nombre d'exétrons pour desservir les appels RPC (par défaut : 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Spécifiez le fichier de portefeuille (dans le répertoire de données)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Dépenser la monnaie non confirmée lors de l'envoi de transactions (par défaut : 1)</translation> - </message> - <message> - <source>Stop running after importing blocks from disk (default: 0)</source> - <translation>Arrêter l'exécution après l'importation des blocs du disque (par défaut : 0)</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> + <message> <source>Verifying blocks...</source> <translation>Vérification des blocs en cours...</translation> </message> @@ -3075,10 +3039,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Importe des blocs depuis un fichier blk000??.dat externe</translation> </message> <message> - <source>(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> - <translation>(par défaut : 1, 1 = conserver les données de transmission c.-à-d. propriétaire du compte et information de demande de paiement, 2 = abandonner les données de transmission)</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>Permettre les connexions JSON-RPC de sources spécifiques. Valide pour <ip> qui sont une IP simple (p. ex. 1.2.3.4), un réseau/masque réseau (p. ex. 1.2.3.4/255.255.255.0) ou un réseau/CIDR (p. ex. 1.2.3.4/24). Cette option peut être être spécifiée plusieurs fois</translation> </message> @@ -3099,12 +3059,12 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Impossible d’obtenir un verrou sur le répertoire de données %s. Bitcoin Core fonctionne probablement déjà.</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> + <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>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> - <translation>Distribué sous la licence logiciel MIT/X11, consultez le fichier joint COPYING ou <http://www.opensource.org/licenses/mit-license.php>.</translation> + <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>Error: Listening for incoming connections failed (listen returned error %s)</source> @@ -3115,10 +3075,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Erreur : l'argument non pris en charge -socks a été trouvé. Il n'est plus possible de définir la version de SOCKS, seuls les serveurs mandataires SOCKS5 sont pris en charge.</translation> </message> <message> - <source>Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)</source> - <translation>Exécuter la commande quand une transmission réseau redépense l'entrée d'une transmission du portefeuille (%s=respend TxID, %t=wallet TxID)</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>Exécuter une commande lorsqu'une alerte pertinente est reçue ou si nous voyons une bifurcation vraiment étendue (%s dans la commande est remplacé par le message)</translation> </message> @@ -3131,12 +3087,8 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <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 are confirmed on average within n blocks (default: 1)</source> - <translation>Si paytxfee n'est pas défini, inclure suffisamment de frais afin que les transactions soient confirmées avant n blocs (par défaut : 1)</translation> - </message> - <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Informations du résultat de débogage (par défaut : 0, fournir <category> est optionnel)</translation> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <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>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> @@ -3147,6 +3099,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Définir la taille maximale en octets des transactions prioritaires/à frais modiques (par défaut : %d)</translation> </message> <message> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <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>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> @@ -3155,18 +3111,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Avertissement : veuillez vérifier que l'heure et la date de votre ordinateur sont correctes ! Si votre horloge n'est pas à l'heure, Bitcoin Core ne fonctionnera pas correctement.</translation> </message> <message> - <source>Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.</source> - <translation>Pairs de la liste blanche se connectant à partir du masque réseau ou de l'IP donné. Peut être spécifié plusieurs fois.</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>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>Always query for peer addresses via DNS lookup (default: 0)</source> - <translation>Toujours demander les adresses de pairs par recherche DNS (par défaut : 0)</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Impossible de résoudre l'adresse -whitebind : « %s »</translation> </message> @@ -3195,10 +3143,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Les frais (en BTC/ko) à ajouter aux transactions que vous envoyez (par défaut : %s)</translation> </message> <message> - <source>Include IP addresses in debug output (default: 0)</source> - <translation>Inclure les adresses IP dans la sortie de débogage (par défaut : 0)</translation> - </message> - <message> <source>Information</source> <translation>Informations</translation> </message> @@ -3227,24 +3171,8 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Garder au plus <n> blocs non connectables en mémoire (par défaut : %u)</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Limiter la taille du cache des signatures à <n> entrées (par défaut : 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Journaliser la priorité des transactions et les frais par ko lors du minage (par défaut : 0) </translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Maintenir un index complet des transactions (par défaut : 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Tampon maximal de réception par « -connection » <n>*1 000 octets (par défaut : 5 000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Tampon maximal d'envoi par « -connection », <n>*1 000 octets (par défaut : 1 000)</translation> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Garder au plus <n> transactions non connectables en mémoire (par défaut : %u)</translation> </message> <message> <source>Need to specify a port with -whitebind: '%s'</source> @@ -3255,22 +3183,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Options de relais du nœud :</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>N'accepter que la chaîne de blocs correspondant aux points de vérification internes (par défaut : 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Se connecter uniquement aux nœuds du réseau <net> (IPv4, IPv6 ou Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>Imprimer le bloc au démarrage s'il est trouvé dans l'index des blocs</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Imprimer l'arborescence des blocs au démarrage (par défaut : 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Options RPC SSL : (voir le wiki Bitcoin pour les instructions de configuration de SSL)</translation> </message> @@ -3287,28 +3203,12 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Tester aléatoirement 1 message du réseau sur <n></translation> </message> <message> - <source>Relay and mine data carrier transactions (default: 1)</source> - <translation>Relayer et miner les transactions du porteur de données (par défaut : 1)</translation> - </message> - <message> - <source>Relay non-P2SH multisig (default: 1)</source> - <translation>Relayer les multisig non-P2SH (par défaut : 1)</translation> - </message> - <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Exécuter un exétron pour purger le portefeuille périodiquement (par défaut : 1) </translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Définir la taille minimale de bloc en octets (par défaut : 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Définit le drapeau DB_PRIVATE dans l'environnement de la base de données du portefeuille (par défaut : 1)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Envoyer si possible les transactions comme étant sans frais (par défaut : %u)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> @@ -3323,14 +3223,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>La signature de la transaction a échoué</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Spécifier le délai d'expiration de la connexion en millisecondes (par défaut : 5 000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Erreur système :</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Ceci est un logiciel expérimental.</translation> </message> @@ -3351,12 +3243,8 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Impossible de se lier à %s sur cet ordinateur (bind a retourné l'erreur %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Utiliser l'UPnP pour rediriger le port d'écoute (par défaut : 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Utiliser l'UPnP pour rediriger le port d'écoute (par défaut : 1 lors de l'écoute)</translation> + <translation>Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 lors de l'écoute)</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3407,10 +3295,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Mettre à niveau le portefeuille vers le format le plus récent</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Régler la taille de la réserve de clefs sur <n> (par défaut : 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Réanalyser la chaîne de blocs pour les transactions de portefeuille manquantes</translation> </message> @@ -3419,14 +3303,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Utiliser OpenSSL (https) pour les connexions JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Fichier de certificat serveur (par défaut : server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Clef privée du serveur (par défaut : server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Ce message d'aide</translation> </message> @@ -3443,14 +3319,166 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Erreur lors du chargement de wallet.dat : portefeuille corrompu</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 = 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>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source> + <translation>Si paytxfee n'est pas défini, inclure des frais suffisants afin que les transactions soient confirmées en moyenne en n blocs (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> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Délai en secondes de refus de reconnexion pour les pairs présentant un mauvais comportement (par défaut : %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Extraire les informations de débogage (par défaut : %u, fournir <category> est optionnel)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Utiliser un serveur mandataire SOCKS5 séparé pour atteindre les pairs par les services cachés de Tor (par défaut : %s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(par défaut : %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Chiffrements acceptables (par défaut : %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <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> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Nombre de blocs à vérifier au démarrage (par défaut : %u, 0 = tous)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Inclure les adresses IP à la sortie de débogage (par défaut : %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <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> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Écouter les connexions sur <port> (par défaut : %u ou tesnet : %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Garder au plus <n> connexions avec les pairs (par défaut : %u)</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> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <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> + <message> + <source>Print block tree on startup (default: %u)</source> + <translation>Imprimer l'arborescence des blocs au démarrage (par défaut : %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Relayer et miner les transactions du porteur de données (par défaut : %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <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> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <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> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Spécifier le délai d'expiration de la connexion en millisecondes (minimum : 1, par défaut : %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Spécifier le fichier pid (par défaut : %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <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> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Réseau inconnu spécifié sur -onlynet : « %s »</translation> </message> diff --git a/src/qt/locale/bitcoin_fr_CA.ts b/src/qt/locale/bitcoin_fr_CA.ts index 56be717a8d..eae0b00b76 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> @@ -77,10 +77,6 @@ <context> <name>CoinControlDialog</name> <message> - <source>Address</source> - <translation>Addresse</translation> - </message> - <message> <source>(no label)</source> <translation>(pas de record)</translation> </message> diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts index b047bb5a4b..2252baec73 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> @@ -359,10 +359,6 @@ <translation>Barra de ferramentas</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Core de Bitcoin</translation> </message> @@ -394,10 +390,6 @@ <source>No block source available...</source> <translation>Non hai orixe de bloques dispoñible...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Procesados %1 bloques do historial de transacccións.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation> @@ -521,10 +513,6 @@ Dirección: %4 <translation>Cantidade</translation> </message> <message> - <source>Address</source> - <translation>Dirección</translation> - </message> - <message> <source>Date</source> <translation>Data</translation> </message> @@ -792,15 +780,7 @@ Dirección: %4 <source>Error</source> <translation>Erro</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB de espacio libre dispoñible</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(de %1 GB precisados)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -835,14 +815,6 @@ Dirección: %4 <translation>&Principal</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Tarifa por kB de transacción opcional que axuda a asegurar que as túas transaccións son procesadas rapidamente. A maioría das transaccións son 1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Pagar &tarifa da transacción</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> @@ -954,10 +926,6 @@ Dirección: %4 <translation>A información amosada por estar desactualizada. O teu moedeiro sincronízase automáticamente coa rede Bitcoin despois de que se estableza unha conexión, pero este proceso non está todavía rematado.</translation> </message> <message> - <source>Wallet</source> - <translation>Moedeiro</translation> - </message> - <message> <source>Your current spendable balance</source> <translation>O teu balance actualmente dispoñible</translation> </message> @@ -982,10 +950,6 @@ Dirección: %4 <translation>O teu balance actual total</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Transaccións recentes</b></translation> - </message> - <message> <source>out of sync</source> <translation>non sincronizado</translation> </message> @@ -2071,26 +2035,10 @@ Dirección: %4 <translation>Opcións:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Especificar arquivo de configuración (por defecto: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Especificar arquivo de pid (por defecto: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Especificar directorio de datos</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Escoitar conexións no <porto> (por defecto: 8333 ou testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Manter como moito <n> conexións con pares (por defecto: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Conectar a nodo para recuperar direccións de pares, e desconectar</translation> </message> @@ -2099,18 +2047,6 @@ Dirección: %4 <translation>Especificar a túa propia dirección pública</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Umbral para desconectar pares con mal comportamento (por defecto: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Número de segundos para manter sen reconectar aos pares con mal comportamento (por defecto: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Escoitar conexións JSON-RPC no <porto> (por defecto: 8332 ou testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Aceptar liña de comandos e comandos JSON-RPC</translation> </message> @@ -2151,10 +2087,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Cifradores aceptables (por defecto: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Enlazar a unha dirección dada e escoitar sempre nela. Emprega a notación [host]:post para IPv6</translation> </message> @@ -2247,62 +2179,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Erro: Moedeiro bloqueado, imposible crear transacción!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Erro: erro do sistema:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Fallou escoitar en calquera porto. Emprega -listen=0 se queres esto.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Fallou a lectura da información do bloque</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Fallou a lectura do bloque</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Fallou a sincronización do índice do bloque</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Fallou a escritura do índice do bloque</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Fallou a escritura da información do bloque</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Fallou a escritura do bloque</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Fallou a escritura da información do arquivo</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Fallou a escritura na base de datos de moedas</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Fallou a escritura do índice de transaccións</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Fallou a escritura dos datos para desfacer</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Xerar moedas (por defecto: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Cantos bloques para chequear ao arrancar (por defecto: 288, 0 = todos)</translation> - </message> - <message> <source>Incorrect or no genesis block found. Wrong datadir for network?</source> <translation>Bloque genesis incorrecto o no existente. Datadir erróneo para a rede?</translation> </message> @@ -2319,10 +2199,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Reconstruír índice de cadea de bloque dende os ficheiros actuais blk000??.dat</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Fixar o número de fíos para as chamadas aos servicios RPC (por defecto: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Especificar arquivo do moedeiro (dentro do directorio de datos)</translation> </message> @@ -2363,34 +2239,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Cantidade inválida para -mintxfee=<cantidade>: '%s'</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Manter un índice completo de transaccións (por defecto: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Máximo buffer por-conexión para recibir, <n>*1000 bytes (por defecto: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Máximo buffer por-conexión para enviar, <n>*1000 bytes (por defecto: 1000)</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Aceptar so cadeas de bloques coincidentes con check-points incorporados (por defecto: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Conectar so a nodos na rede <net> (IPv4, IPv6 ou Tor)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Enviar traza/información de depuración á consola en lugar de ao arquivo debug.log</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Fixar tamaño mínimo de bloque en bytes (por defecto: 0)</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> @@ -2399,14 +2251,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Fallou a sinatura da transacción</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Especificar tempo límite da conexión en milisegundos (por defecto: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Erro do sistema:</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>A cantidade da transacción é demasiado pequena</translation> </message> @@ -2419,10 +2263,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>A transacción é demasiado grande</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Usar UPnP para mapear o porto de escoita (por defecto: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Usar UPnP para mapear o porto de escoita (por defecto: 1 se á escoita)</translation> </message> @@ -2455,10 +2295,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Actualizar moedeiro ao formato máis recente</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Fixar tamaño do pool de claves a <n> (por defecto: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Rescanear transaccións ausentes na cadea de bloques</translation> </message> @@ -2467,14 +2303,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Empregar OpenSSL (https) para conexións JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Arquivo de certificado do servidor (por defecto: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Clave privada do servidor (por defecto: server.perm)</translation> - </message> - <message> <source>This help message</source> <translation>Esta mensaxe de axuda</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 ae96d9f570..b547058986 100644 --- a/src/qt/locale/bitcoin_he.ts +++ b/src/qt/locale/bitcoin_he.ts @@ -1,9 +1,9 @@ -<TS language="he" version="2.1"> +<TS language="he" version="2.0"> <context> <name>AddressBookPage</name> <message> <source>Double-click to edit address or label</source> - <translation>לחץ לחיצה כפולה לערוך כתובת או תוית</translation> + <translation>לחיצה כפולה לעריכת כתובת או תווית</translation> </message> <message> <source>Create a new address</source> @@ -11,15 +11,15 @@ </message> <message> <source>&New</source> - <translation>&חדש</translation> + <translation>&חדשה</translation> </message> <message> <source>Copy the currently selected address to the system clipboard</source> - <translation>העתק את הכתובת המסומנת ללוח העריכה</translation> + <translation>העתקת הכתובת המסומנת ללוח הגזירים</translation> </message> <message> <source>&Copy</source> - <translation>&העתק</translation> + <translation>ה&עתקה</translation> </message> <message> <source>C&lose</source> @@ -27,78 +27,82 @@ </message> <message> <source>&Copy Address</source> - <translation>העתק כתובת</translation> + <translation>העתקת כתובת</translation> </message> <message> <source>Delete the currently selected address from the list</source> - <translation>מחק את הכתובת שנבחרה מהרשימה</translation> + <translation>מחיקת הכתובת שנבחרה מהרשימה</translation> </message> <message> <source>Export the data in the current tab to a file</source> - <translation>יצוא הנתונים בטאב הנוכחי לקובץ</translation> + <translation>יצוא הנתונים מהלשונית הנוכחית לקובץ</translation> </message> <message> <source>&Export</source> - <translation>&ייצא</translation> + <translation>י&צוא</translation> </message> <message> <source>&Delete</source> - <translation>&מחק</translation> + <translation>מ&חיקה</translation> </message> <message> <source>Choose the address to send coins to</source> - <translation>בחר את הכתובת אליה תרצה לשלוח את המטבעות</translation> + <translation>נא לבחור את הכתובת המבוקשת לשליחת המטבעות</translation> </message> <message> <source>Choose the address to receive coins with</source> - <translation>בחר את הכתובת איתה תרצה לקבל את המטבעות</translation> + <translation>נא לבחור את הכתובת המבוקשת לקבלת המטבעות</translation> </message> <message> <source>C&hoose</source> - <translation>בחר</translation> + <translation>בחירה</translation> </message> <message> <source>Sending addresses</source> - <translation>כתובת לשליחה</translation> + <translation>כתובות לשליחה</translation> </message> <message> <source>Receiving addresses</source> - <translation>קבל כתובות</translation> + <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> + <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> + <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> + <translation>יצוא רשימת כתובות</translation> </message> <message> <source>Comma separated file (*.csv)</source> - <translation>קובץ מופרד בפסיקים (*.csv)</translation> + <translation>קובץ מופרד בפסיקים (*.csv)</translation> </message> <message> <source>Exporting Failed</source> - <translation>הייצוא נכשל</translation> + <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> @@ -106,34 +110,34 @@ </message> <message> <source>(no label)</source> - <translation>(ללא תוית)</translation> + <translation>(ללא תווית)</translation> </message> </context> <context> <name>AskPassphraseDialog</name> <message> <source>Passphrase Dialog</source> - <translation>שיח סיסמא</translation> + <translation>דו־שיח מילת צופן</translation> </message> <message> <source>Enter passphrase</source> - <translation>הכנס סיסמה</translation> + <translation>נא להזין מילת צופן</translation> </message> <message> <source>New passphrase</source> - <translation>סיסמה חדשה</translation> + <translation>מילת צופן חדשה</translation> </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> - <translation>הפעולה הזו דורשת את סיסמת הארנק שלך בשביל לפתוח את הארנק.</translation> + <translation>פעולה זו דורשת את מילת הצופן של הארנק שלך כדי לפתוח את הארנק.</translation> </message> <message> <source>Unlock wallet</source> @@ -141,7 +145,7 @@ </message> <message> <source>This operation needs your wallet passphrase to decrypt the wallet.</source> - <translation>הפעולה הזו דורשת את סיסמת הארנק שלך בשביל לפענח את הארנק.</translation> + <translation>פעולה זו דורשת את מילת הצופן של הארנק שלך כדי לפענח את הארנק.</translation> </message> <message> <source>Decrypt wallet</source> @@ -149,39 +153,43 @@ </message> <message> <source>Change passphrase</source> - <translation>שינוי סיסמה</translation> + <translation>שינוי מילת צופן</translation> </message> <message> <source>Enter the old and new passphrase to the wallet.</source> - <translation>הכנס את הסיסמות הישנה והחדשה לארנק.</translation> + <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> - <translation>זהירות: מקש Caps Lock מופעל!</translation> + <translation>זהירות: מקש Caps Lock פעיל!</translation> </message> <message> <source>Wallet encrypted</source> <translation>הארנק הוצפן</translation> </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> + </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> @@ -193,7 +201,7 @@ </message> <message> <source>The supplied passphrases do not match.</source> - <translation>הסיסמות שניתנו אינן תואמות.</translation> + <translation>מילות הצופן שסופקו אינן תואמות.</translation> </message> <message> <source>Wallet unlock failed</source> @@ -201,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> @@ -209,34 +217,38 @@ </message> <message> <source>Wallet passphrase was successfully changed.</source> - <translation>סיסמת הארנק שונתה בהצלחה.</translation> + <translation>מילת הצופן של הארנק שונתה בהצלחה.</translation> </message> </context> <context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> - <translation>חתום על הודעה</translation> + <translation>&חתימה על הודעה…</translation> </message> <message> <source>Synchronizing with network...</source> - <translation>מסתנכרן עם הרשת...</translation> + <translation>בסנכרון עם הרשת…</translation> </message> <message> <source>&Overview</source> <translation>&סקירה</translation> </message> <message> + <source>Node</source> + <translation>מפרק</translation> + </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> - <translation>דפדף בהיסטוריית הפעולות</translation> + <translation>עיון בהיסטוריית ההעברות</translation> </message> <message> <source>E&xit</source> @@ -244,67 +256,83 @@ </message> <message> <source>Quit application</source> - <translation>סגור תוכנה</translation> + <translation>יציאה מהתכנית</translation> </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> - <translation>&אפשרויות</translation> + <translation>&אפשרויות…</translation> </message> <message> <source>&Encrypt Wallet...</source> - <translation>הצפן ארנק</translation> + <translation>ה&צפנת הארנק…</translation> </message> <message> <source>&Backup Wallet...</source> - <translation>גיבוי ארנק</translation> + <translation>&גיבוי הארנק…</translation> </message> <message> <source>&Change Passphrase...</source> - <translation>שנה סיסמא</translation> + <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>Bitcoin Core client</source> + <translation>לקוח ליבה של ביטקוין</translation> </message> <message> <source>Importing blocks from disk...</source> - <translation>מייבא בלוקים מהדיסק...</translation> + <translation>מקטעים מיובאים מהכונן…</translation> </message> <message> <source>Reindexing blocks on disk...</source> - <translation>מחדש את אינדקס הבלוקים בדיסק...</translation> + <translation>המקטעים נוספים למפתח בכונן…</translation> </message> <message> <source>Send coins to a Bitcoin address</source> - <translation>שלח מטבעות לכתובת ביטקוין</translation> + <translation>שליחת מטבעות לכתובת ביטקוין</translation> </message> <message> <source>Modify configuration options for Bitcoin</source> - <translation>שנה אפשרויות תצורה עבור ביטקוין</translation> + <translation>שינוי התצורה של ביטקוין</translation> </message> <message> <source>Backup wallet to another location</source> - <translation>גיבוי הארנק למקום אחר</translation> + <translation>גיבוי הארנק למיקום אחר</translation> </message> <message> <source>Change the passphrase used for wallet encryption</source> - <translation>שנה את הסיסמה להצפנת הארנק</translation> + <translation>החלפת מילת הצופן להצפנת הארנק</translation> </message> <message> <source>&Debug window</source> - <translation>חלון ניפוי</translation> + <translation>חלון &ניפוי</translation> </message> <message> <source>Open debugging and diagnostic console</source> - <translation>פתח את לוח הבקרה לאבחון וניפוי</translation> + <translation>פתיחת לוח הבקרה לאבחון ולניפוי</translation> </message> <message> <source>&Verify message...</source> - <translation>אמת הודעה...</translation> + <translation>&אימות הודעה…</translation> </message> <message> <source>Bitcoin</source> @@ -316,23 +344,27 @@ </message> <message> <source>&Send</source> - <translation>&שלח</translation> + <translation>&שליחה</translation> </message> <message> <source>&Receive</source> - <translation>וקבל</translation> + <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> + <translation>הצגה או הסתרה של החלון הראשי</translation> </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> @@ -352,15 +384,11 @@ </message> <message> <source>&Help</source> - <translation>&עזרה</translation> + <translation>ע&זרה</translation> </message> <message> <source>Tabs toolbar</source> - <translation>סרגל כלים טאבים</translation> - </message> - <message> - <source>[testnet]</source> - <translation>[רשת-בדיקה]</translation> + <translation>סרגל כלים לשוניות</translation> </message> <message> <source>Bitcoin Core</source> @@ -368,11 +396,11 @@ </message> <message> <source>Request payments (generates QR codes and bitcoin: URIs)</source> - <translation>בקש תשלומים (מייצר קודיי QR וסכימות URI של :bitcoin)</translation> + <translation>בקשת תשלומים (יצירה של קודים מסוג QR וסכימות כתובות משאב של :bitcoin)</translation> </message> <message> <source>&About Bitcoin Core</source> - <translation>&אודות קליינט ביטקוין</translation> + <translation>על &אודות ליבת ביטקוין</translation> </message> <message> <source>Show the list of used sending addresses and labels</source> @@ -380,19 +408,23 @@ </message> <message> <source>Show the list of used receiving addresses and labels</source> - <translation>הצג את רשימת הכתובות והתויות המשומשות</translation> + <translation>הצגת רשימת הכתובות והתוויות הנמצאות בשימוש</translation> </message> <message> <source>Open a bitcoin: URI or payment request</source> - <translation>פתח ביטקוין: URI או בקשת תשלום</translation> + <translation>פתיחת ביטקוין: כתובת משאב או בקשת תשלום</translation> </message> <message> - <source>No block source available...</source> - <translation>אין קוד נתון</translation> + <source>&Command-line options</source> + <translation>אפשרויות &שורת הפקודה</translation> </message> <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>הושלם עיבוד של %1 בלוקים של היסטוריית פעולות.</translation> + <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> + <translation>הצגת הודעות העזרה של ליבת ביטקוין כדי לקבל רשימה עם אפשרויות שורת הפקודה האפשריות של ביטקוין</translation> + </message> + <message> + <source>No block source available...</source> + <translation>אין מקור מקטעים זמין…</translation> </message> <message numerus="yes"> <source>%n hour(s)</source> @@ -407,12 +439,16 @@ <translation><numerusform>%n שבוע</numerusform><numerusform>%n שבועות</numerusform></translation> </message> <message> + <source>%1 and %2</source> + <translation>%1 ו%2</translation> + </message> + <message> <source>Last received block was generated %1 ago.</source> - <translation>הבלוק האחרון שהתקבל נוצר לפני %1</translation> + <translation>המקטע האחרון שהתקבל נוצר לפני %1.</translation> </message> <message> <source>Transactions after this will not yet be visible.</source> - <translation>לאחר זאת פעולות נספות טרם יהיו גלויות</translation> + <translation>ההעברות שבוצעו לאחר העברה זו לא יופיעו.</translation> </message> <message> <source>Error</source> @@ -432,15 +468,15 @@ </message> <message> <source>Catching up...</source> - <translation>מתעדכן...</translation> + <translation>מתבצע עדכון…</translation> </message> <message> <source>Sent transaction</source> - <translation>פעולה שנשלחה</translation> + <translation>העברת שליחה</translation> </message> <message> <source>Incoming transaction</source> - <translation>פעולה שהתקבלה</translation> + <translation>העברת קבלה</translation> </message> <message> <source>Date: %1 @@ -455,11 +491,11 @@ Address: %4 </message> <message> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> - <translation>הארנק <b>מוצפן</b> וכרגע <b>פתוח</b></translation> + <translation>הארנק <b>מוצפן</b> ו<b>פתוח</b> כרגע</translation> </message> <message> <source>Wallet is <b>encrypted</b> and currently <b>locked</b></source> - <translation>הארנק <b>מוצפן</b> וכרגע <b>נעול</b></translation> + <translation>הארנק <b>מוצפן</b> ו<b>נעול</b> כרגע</translation> </message> </context> <context> @@ -472,16 +508,12 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>בחירת כתובת שליטת מטבעות</translation> - </message> - <message> <source>Quantity:</source> <translation>כמות:</translation> </message> <message> <source>Bytes:</source> - <translation>בייטים:</translation> + <translation>בתים:</translation> </message> <message> <source>Amount:</source> @@ -489,13 +521,17 @@ Address: %4 </message> <message> <source>Priority:</source> - <translation>קדימות:</translation> + <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> @@ -505,7 +541,7 @@ Address: %4 </message> <message> <source>(un)select all</source> - <translation>(מחק)(בחר) הכל</translation> + <translation>ביטול/אישור הבחירה</translation> </message> <message> <source>Tree mode</source> @@ -513,17 +549,13 @@ Address: %4 </message> <message> <source>List mode</source> - <translation>מצר רשימה</translation> + <translation>מצב רשימה</translation> </message> <message> <source>Amount</source> <translation>כמות</translation> </message> <message> - <source>Address</source> - <translation>כתובת</translation> - </message> - <message> <source>Date</source> <translation>תאריך</translation> </message> @@ -537,63 +569,67 @@ Address: %4 </message> <message> <source>Priority</source> - <translation>קדימות</translation> + <translation>עדיפות</translation> </message> <message> <source>Copy address</source> - <translation>העתק כתובת</translation> + <translation>העתקת כתובת</translation> </message> <message> <source>Copy label</source> - <translation>העתק תוית</translation> + <translation>העתקת תווית</translation> </message> <message> <source>Copy amount</source> - <translation>העתק כמות</translation> + <translation>העתקת כמות</translation> </message> <message> <source>Copy transaction ID</source> - <translation>העתק מזהה פעולה</translation> + <translation>העתקת מזהה העברה</translation> </message> <message> <source>Lock unspent</source> - <translation>נעל יתרה</translation> + <translation>נעילת יתרה</translation> </message> <message> <source>Unlock unspent</source> - <translation>פתח יתרה</translation> + <translation>פתיחת יתרה</translation> </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> </message> <message> <source>Copy change</source> - <translation>העתק עודף</translation> + <translation>העתקת עודף</translation> </message> <message> <source>highest</source> - <translation>הכי גבוה</translation> + <translation>הגבוה ביותר</translation> </message> <message> <source>higher</source> - <translation>גבוהה יותר</translation> + <translation>גבוה יותר</translation> </message> <message> <source>high</source> @@ -601,7 +637,7 @@ Address: %4 </message> <message> <source>medium-high</source> - <translation>בנוני גבוה</translation> + <translation>בינוני - גבוה</translation> </message> <message> <source>medium</source> @@ -621,7 +657,15 @@ Address: %4 </message> <message> <source>lowest</source> - <translation>הכי נמוך</translation> + <translation>הנמוך ביותר</translation> + </message> + <message> + <source>none</source> + <translation>ללא</translation> + </message> + <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>יכולה להשתנות ב+/- %1 סטושי לקלט.</translation> </message> <message> <source>yes</source> @@ -633,23 +677,27 @@ Address: %4 </message> <message> <source>This label turns red, if the transaction size is greater than 1000 bytes.</source> - <translation>תווית זו מאדימה במידה וגודל הפעולה עולה על 1000 בייט</translation> + <translation>תווית זו מאדימה אם גודל ההעברה עולה על 1000 בתים.</translation> </message> <message> <source>This means a fee of at least %1 per kB is required.</source> - <translation>זאת אומרת שנחוצה עמלה של לא פחות מ־%1 לכל קילו בייט.</translation> + <translation>זאת אומרת שנחוצה עמלה של לא פחות מ־%1 לכל קילו בית.</translation> </message> <message> <source>Can vary +/- 1 byte per input.</source> - <translation>הערך יכול להיות +/- בייט 1 פר כניסה</translation> + <translation>הערך יכול להיות +/- בית אחד לכל קלט.</translation> </message> <message> <source>Transactions with higher priority are more likely to get included into a block.</source> - <translation>העברות עם עדיפות גבוהה, יותר סיכוי שיכנסו לתוך הבלוק</translation> + <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> + <translation>(אין תווית)</translation> </message> <message> <source>change from %1 (%2)</source> @@ -664,15 +712,15 @@ Address: %4 <name>EditAddressDialog</name> <message> <source>Edit Address</source> - <translation>ערוך כתובת</translation> + <translation>עריכת כתובת</translation> </message> <message> <source>&Label</source> - <translation>ת&וית</translation> + <translation>ת&ווית</translation> </message> <message> <source>The label associated with this address list entry</source> - <translation>התוית המשויכת לרשומה הזו ברשימת הכתובות</translation> + <translation>התווית המשויכת לרשומה הזו ברשימת הכתובות</translation> </message> <message> <source>The address associated with this address list entry. This can only be modified for sending addresses.</source> @@ -692,19 +740,19 @@ 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> - <translation>הכתובת שהכנסת "%1" כבר נמצאת בפנקס הכתובות.</translation> + <translation>הכתובת שהוכנסה „%1“ כבר נמצאת בפנקס הכתובות.</translation> </message> <message> <source>The entered address "%1" is not a valid Bitcoin address.</source> - <translation>הכתובת שהוכנסה "%1" אינה כתובת ביטקוין תקינה.</translation> + <translation>הכתובת שהוכנסה „%1“ אינה כתובת ביטקוין תקנית.</translation> </message> <message> <source>Could not unlock wallet.</source> @@ -719,7 +767,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> @@ -727,15 +775,15 @@ Address: %4 </message> <message> <source>Directory already exists. Add %1 if you intend to create a new directory here.</source> - <translation>הספריה כבר קיימת. הוסף %1 אם ברצונך ליצור ספריה חדשה כאן.</translation> + <translation>התיקייה כבר קיימת. ניתן להוסיף %1 אם יש ליצור תיקייה חדשה כאן.</translation> </message> <message> <source>Path already exists, and is not a directory.</source> - <translation>הנתיב כבר קיים ואינו מצביע על ספרייה.</translation> + <translation>הנתיב כבר קיים ואינו מצביע על תיקייה.</translation> </message> <message> <source>Cannot create data directory here.</source> - <translation>לא ניתן ליצור ספריית מידע כאן.</translation> + <translation>לא ניתן ליצור כאן תיקיית נתונים.</translation> </message> </context> <context> @@ -749,6 +797,10 @@ Address: %4 <translation>גרסה</translation> </message> <message> + <source>(%1-bit)</source> + <translation>(%1-סיביות)</translation> + </message> + <message> <source>About Bitcoin Core</source> <translation>על אודות ליבת ביטקוין</translation> </message> @@ -766,21 +818,29 @@ Address: %4 </message> <message> <source>UI options</source> - <translation>אפשרויות ממשק</translation> + <translation>אפשרויות מנשק</translation> </message> <message> <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>קבע שפה, למשל "he_il" (ברירת מחדל: שפת המערכת)</translation> + <translation>הגדרת שפה, למשל „he_il“ (בררת מחדל: שפת המערכת)</translation> </message> <message> <source>Start minimized</source> - <translation>התחל ממוזער</translation> + <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> + <translation>הצגת מסך פתיחה בעת הפעלה (בררת מחדל: 1)</translation> </message> - </context> + <message> + <source>Choose data directory on startup (default: 0)</source> + <translation>בחירת תיקיית נתונים עם ההפעלה (בררת מחדל: 0)</translation> + </message> +</context> <context> <name>Intro</name> <message> @@ -789,54 +849,50 @@ Address: %4 </message> <message> <source>Welcome to Bitcoin Core.</source> - <translation>ברוך הבא לקליינט ביטקוין</translation> + <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> + <translation>מכיוון שזאת הפעם הראשונה שהתכנית פועלת ניתן לבחור איפה ליבת ביטקוין תאחסן את הנתונים שלה.</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>קליינט ביטקוין יוריד וישמור העתק של שרשרת הבלוקים של ביטקוין. לפחות %1GB מהנתונים יאוכסנו בתיקיה הזו, ויגדל עם הזמן. הארנק גם יאוחסן בתיקיה הזו.</translation> + <translation>לקוח ביטקוין יוריד וישמור העתק של שרשרת המקטעים של ביטקוין. לפחות %1 ג״ב מהנתונים יאוחסנו בתיקייה זו, והיא תגדל עם הזמן. הארנק גם יאוחסן בתיקייה הזו.</translation> </message> <message> <source>Use the default data directory</source> - <translation>השתמש בברירת המחדל עבור ספריית המידע.</translation> + <translation>שימוש בבררת המחדל של תיקיית הנתונים.</translation> </message> <message> <source>Use a custom data directory:</source> - <translation>השתמש בספריית מידע מותאמת אישית:</translation> + <translation>שימוש בתיקיית נתונים מותאמת אישית:</translation> </message> <message> <source>Bitcoin Core</source> <translation>ליבת ביטקוין</translation> </message> <message> - <source>Error</source> - <translation>שגיאה</translation> - </message> - <message> - <source>GB of free space available</source> - <translation>ג"ב של שטח אחסון פנוי</translation> + <source>Error: Specified data directory "%1" cannot be created.</source> + <translation>שגיאה: לא ניתן ליצור את תיקיית הנתונים שצוינה „%1“.</translation> </message> <message> - <source>(of %1GB needed)</source> - <translation>(מתוך %1 ג"ב נחוצים)</translation> + <source>Error</source> + <translation>שגיאה</translation> </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> <source>Open URI</source> - <translation>פתח URI</translation> + <translation>פתיחת כתובת משאב</translation> </message> <message> <source>Open payment request from URI or file</source> - <translation>פתח בקשת תשלום מ-URI או קובץ</translation> + <translation>פתיחת בקשת תשלום מכתובת משאב או מקובץ</translation> </message> <message> <source>URI:</source> - <translation>כתובת:</translation> + <translation>כתובת משאב:</translation> </message> <message> <source>Select payment request file</source> @@ -855,63 +911,111 @@ Address: %4 </message> <message> <source>&Main</source> - <translation>ראשי</translation> + <translation>&ראשי</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>עמלת פעולה אופציונלית לכל kB תבטיח שהפעולה שלך תעובד בזריזות. רוב הפעולות הן 1 kB.</translation> + <source>Automatically start Bitcoin after logging in to the system.</source> + <translation>הפעלת ביטקוין אוטומטית לאחר כניסה למערכת.</translation> </message> <message> - <source>Pay transaction &fee</source> - <translation>שלם &עמלת פעולה</translation> + <source>&Start Bitcoin on system login</source> + <translation>ה&פעלת ביטקוין בעת הכניסה למערכת</translation> </message> <message> - <source>Automatically start Bitcoin after logging in to the system.</source> - <translation>הפעל את ביטקוין באופן עצמאי לאחר התחברות למערכת.</translation> + <source>Size of &database cache</source> + <translation>גודל מ&טמון מסד הנתונים</translation> </message> <message> - <source>&Start Bitcoin on system login</source> - <translation>התחל את ביטקוין בעת התחברות למערכת</translation> + <source>MB</source> + <translation>מ״ב</translation> </message> <message> - <source>MB</source> - <translation>מגה בייט</translation> + <source>Number of script &verification threads</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 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> + <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>אפס כל אפשרויות התוכנה לברירת המחדל.</translation> + <translation>איפוס כל אפשרויות התכנית לבררת המחדל.</translation> </message> <message> <source>&Reset Options</source> - <translation>איפוס אפשרויות</translation> + <translation>&איפוס אפשרויות</translation> </message> <message> <source>&Network</source> - <translation>רשת</translation> + <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> + <message> + <source>Expert</source> + <translation>מומחה</translation> + </message> + <message> + <source>Enable coin &control features</source> + <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>פתח את פורט ביטקוין בנתב באופן אוטומטי. עובד רק אם UPnP מאופשר ונתמך ע"י הנתב.</translation> + <translation>פתיחת הפתחה של ביטקוין בנתב באופן אוטומטי. עובד רק אם UPnP מופעל ונתמך בנתב.</translation> </message> <message> <source>Map port using &UPnP</source> - <translation>מיפוי פורט באמצעות UPnP</translation> + <translation>מיפוי פתחה באמצעות UPnP</translation> </message> <message> <source>Proxy &IP:</source> - <translation>כתובת IP של פרוקסי:</translation> + <translation>כתובת ה־IP של המ&תווך:</translation> </message> <message> <source>&Port:</source> - <translation>פורט:</translation> + <translation>&פתחה:</translation> </message> <message> <source>Port of the proxy (e.g. 9050)</source> - <translation>הפורט של הפרוקסי (למשל 9050)</translation> + <translation>הפתחה של המתווך (למשל 9050)</translation> </message> <message> <source>&Window</source> - <translation>חלון</translation> + <translation>&חלון</translation> </message> <message> <source>Show only a tray icon after minimizing the window.</source> @@ -919,59 +1023,75 @@ Address: %4 </message> <message> <source>&Minimize to the tray instead of the taskbar</source> - <translation>מ&זער למגש במקום לשורת המשימות</translation> + <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> + <translation>מזעור התכנית במקום לצאת ממנה כשהחלון נסגר. כשאפשרות זו פעילה, התכנית תיסגר רק לאחר בחירת יציאה מהתפריט.</translation> </message> <message> <source>M&inimize on close</source> - <translation>מזער בעת סגירה</translation> + <translation>מ&זעור עם סגירה</translation> </message> <message> <source>&Display</source> - <translation>תצוגה</translation> + <translation>ת&צוגה</translation> </message> <message> <source>User Interface &language:</source> - <translation>שפת ממשק המשתמש:</translation> + <translation>&שפת מנשק המשתמש:</translation> </message> <message> <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> - <translation>ניתן לקבוע כאן את שפת ממשק המשתמש. הגדרה זו תחול לאחר הפעלה מחדש של ביטקוין.</translation> + <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> + <translation>ניתן לבחור את בררת המחדל ליחידת החלוקה שתוצג במנשק ובעת שליחת מטבעות.</translation> </message> <message> <source>Whether to show coin control features or not.</source> - <translation>הצג תכונות שליטת מטבע או לא.</translation> + <translation>האם להציג תכונות שליטת מטבע או לא.</translation> </message> <message> <source>&OK</source> - <translation>אישור</translation> + <translation>&אישור</translation> </message> <message> <source>&Cancel</source> - <translation>ביטול</translation> + <translation>&ביטול</translation> </message> <message> <source>default</source> - <translation>ברירת מחדל</translation> + <translation>בררת מחדל</translation> + </message> + <message> + <source>none</source> + <translation>ללא</translation> </message> <message> <source>Confirm options reset</source> - <translation>אשר את איפוס האפשרויות</translation> + <translation>אישור איפוס האפשרויות</translation> + </message> + <message> + <source>Client restart required to activate changes.</source> + <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> <message> <source>The supplied proxy address is invalid.</source> - <translation>כתובת הפרוקסי שסופקה אינה תקינה.</translation> + <translation>כתובת המתווך שסופקה אינה תקינה.</translation> </message> </context> <context> @@ -982,19 +1102,27 @@ Address: %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>המידע המוצג עשוי להיות מיושן. הארנק שלך מסתנכרן באופן אוטומטי עם רשת הביטקוין לאחר כינון חיבור, אך התהליך טרם הסתיים.</translation> + <translation>המידע המוצג עשוי להיות מיושן. הארנק שלך מסתנכרן באופן אוטומטי עם רשת הביטקוין לאחר יצירת החיבור, אך התהליך טרם הסתיים.</translation> </message> <message> - <source>Wallet</source> - <translation>ארנק</translation> + <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>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source> - <translation>הסכום הכולל של פעולות שטרם אושרו, ועוד אינן נספרות בחישוב היתרה הזמינה</translation> + <translation>הסכום הכולל של העברות שטרם אושרו ועדיין אינן נספרות בחישוב היתרה הזמינה</translation> </message> <message> <source>Immature:</source> @@ -1005,6 +1133,10 @@ Address: %4 <translation>מאזן שנכרה וטרם הבשיל</translation> </message> <message> + <source>Balances</source> + <translation>מאזנים</translation> + </message> + <message> <source>Total:</source> <translation>סך הכול:</translation> </message> @@ -1013,27 +1145,59 @@ Address: %4 <translation>סך כל היתרה הנוכחית שלך</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>פעולות אחרונות</b></translation> + <source>Your current balance in watch-only addresses</source> + <translation>המאזן הנוכחי שלך בכתובות לקריאה בלבד</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>העברות אחרונות</translation> + </message> + <message> + <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> <message> <source>out of sync</source> - <translation>לא מסונכרן</translation> + <translation>לא בסנכרון</translation> </message> </context> <context> <name>PaymentServer</name> <message> <source>URI handling</source> - <translation>תפעול URI</translation> + <translation>תפעול כתובות משאב</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>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> + <translation>הסכום על סך %1 הנדרש לתשלום קטן מדי (נחשב לאבק)</translation> </message> <message> <source>Payment request error</source> @@ -1041,11 +1205,27 @@ Address: %4 </message> <message> <source>Cannot start bitcoin: click-to-pay handler</source> - <translation>לא ניתן להתחיל את ביטקוין: מפעיל לחץ-לתשלום </translation> + <translation>לא ניתן להתחיל את ביטקוין: טיפול בלחיצה–לתשלום </translation> + </message> + <message> + <source>Payment request fetch URL is invalid: %1</source> + <translation>כתובת אחזור בקשת התשלום שגויה: %1</translation> + </message> + <message> + <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> + <translation>לא ניתן לנתח את כתובת המשאב! מצב זה יכול לקרות עקב כתובת ביטקוין שגויה או פרמטרים שגויים בכתובת המשאב.</translation> + </message> + <message> + <source>Payment request file handling</source> + <translation>טיפול בקובצי בקשות תשלום</translation> + </message> + <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>לא ניתן לקרוא את קובץ בקשת התשלום! מצב כזה יכול לקרות בעקבות קובץ בקשת תשלום פגום.</translation> </message> <message> <source>Unverified payment requests to custom payment scripts are unsupported.</source> - <translation>בקשות לתשלום לסקריפטיי תשלום מותאמים אישית אינן נתמכות.</translation> + <translation>בקשות תשלום בלתי מאומתות לסקריפטים לתשלום מותאמים אישית אינן נתמכות.</translation> </message> <message> <source>Refund from %1</source> @@ -1056,6 +1236,10 @@ Address: %4 <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> @@ -1070,7 +1254,19 @@ Address: %4 </context> <context> <name>PeerTableModel</name> - </context> + <message> + <source>User Agent</source> + <translation>סוכן משתמש</translation> + </message> + <message> + <source>Address/Hostname</source> + <translation>כתובת/שם מארח</translation> + </message> + <message> + <source>Ping Time</source> + <translation>זמן המענה</translation> + </message> +</context> <context> <name>QObject</name> <message> @@ -1078,54 +1274,86 @@ 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>NETWORK</source> + <translation>רשת</translation> + </message> + <message> + <source>UNKNOWN</source> + <translation>לא ידוע</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> <source>&Save Image...</source> - <translation>&שמור תמונה..</translation> + <translation>&שמירת תמונה…</translation> </message> <message> <source>&Copy Image</source> - <translation>&העתק תמונה</translation> + <translation>ה&עתקת תמונה</translation> </message> <message> <source>Save QR Code</source> - <translation>שמור קוד QR</translation> + <translation>שמירת קוד QR</translation> </message> <message> <source>PNG Image (*.png)</source> - <translation>תמונת PNG (*.png)</translation> + <translation>תמונת PNG (*.png)</translation> </message> </context> <context> <name>RPCConsole</name> <message> <source>Client name</source> - <translation>שם ממשק</translation> + <translation>שם לקוח</translation> </message> <message> <source>N/A</source> - <translation>N/A</translation> + <translation>לא זמין</translation> </message> <message> <source>Client version</source> - <translation>גרסת ממשק</translation> + <translation>גרסת מנשק</translation> </message> <message> <source>&Information</source> - <translation>מידע</translation> + <translation>מי&דע</translation> </message> <message> <source>Debug window</source> - <translation>חלון דיבאג</translation> + <translation>חלון ניפוי</translation> </message> <message> <source>General</source> @@ -1133,11 +1361,15 @@ Address: %4 </message> <message> <source>Using OpenSSL version</source> - <translation>משתמש ב-OpenSSL גרסה</translation> + <translation>שימוש ב־OpenSSL גרסה</translation> + </message> + <message> + <source>Using BerkeleyDB version</source> + <translation>שימוש ב־BerkeleyDB גרסה</translation> </message> <message> <source>Startup time</source> - <translation>זמן אתחול</translation> + <translation>זמן עלייה</translation> </message> <message> <source>Network</source> @@ -1153,23 +1385,91 @@ Address: %4 </message> <message> <source>Block chain</source> - <translation>שרשרת הבלוקים</translation> + <translation>שרשרת מקטעים</translation> </message> <message> <source>Current number of blocks</source> - <translation>מספר הבלוקים הנוכחי</translation> + <translation>מספר המקטעים הנוכחי</translation> + </message> + <message> + <source>Received</source> + <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>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>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>בתים שנשלחו</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> + <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> @@ -1177,7 +1477,7 @@ Address: %4 </message> <message> <source>&Clear</source> - <translation>& נקה</translation> + <translation>&ניקוי</translation> </message> <message> <source>Totals</source> @@ -1193,7 +1493,7 @@ Address: %4 </message> <message> <source>Build date</source> - <translation>תאריך בניה</translation> + <translation>תאריך בנייה</translation> </message> <message> <source>Debug log file</source> @@ -1201,41 +1501,65 @@ Address: %4 </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> + <translation>פתיחת קובץ יומן הניפוי מתיקיית הנתונים הנוכחית. פעולה זו עשויה להימשך מספר שניות עבור קובצי יומן גדולים.</translation> </message> <message> <source>Clear console</source> - <translation>נקה לוח בקרה</translation> + <translation>ניקוי מסוף הבקרה</translation> </message> <message> <source>Welcome to the Bitcoin RPC console.</source> - <translation>ברוכים הבאים ללוח בקרת RPC של ביטקוין</translation> + <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> + <translation>יש להשתמש בחצים למעלה ולמטה כדי לנווט בהיסטוריה, וב־<b>Ctrl-L</b> כדי לנקות את המסך.</translation> </message> <message> <source>Type <b>help</b> for an overview of available commands.</source> - <translation>הקלד <b>help</b> בשביל סקירה של הפקודות הזמינות.</translation> + <translation>ניתן להקליד <b>help</b> לקבלת סקירה של הפקודות הזמינות.</translation> </message> <message> <source>%1 B</source> - <translation>%1 בייט</translation> + <translation>%1 ב׳</translation> </message> <message> <source>%1 KB</source> - <translation>%1 קילו בייט</translation> + <translation>%1 ק״ב</translation> </message> <message> <source>%1 MB</source> - <translation>%1 מגה בייט</translation> + <translation>%1 מ״ב</translation> </message> <message> <source>%1 GB</source> - <translation>%1 ג'יגה בייט</translation> + <translation>%1 ג״ב</translation> </message> - </context> + <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> @@ -1244,55 +1568,79 @@ Address: %4 </message> <message> <source>&Label:</source> - <translation>ת&וית:</translation> + <translation>ת&ווית:</translation> </message> <message> <source>&Message:</source> - <translation>&הודעה:</translation> + <translation>הו&דעה:</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>השתמש שוב באחת מכתובות הקבלה שכבר נעשה בהן שימוש. לשימוש חוזר בכתובות ישהן השלכות אבטחה ופרטיות. השתמש בזה רק אם אתה מייצר מחדש בקשת תשלום שכבר נעשתה.</translation> + <translation>ניתן להשתמש שוב באחת מכתובות הקבלה שכבר נעשה בהן שימוש. לשימוש חוזר בכתובות ישנן השלכות אבטחה ופרטיות. מומלץ שלא להשתמש באפשרות זו למעט יצירה מחדש של בקשת תשלום שנוצרה בעבר.</translation> </message> <message> <source>R&euse an existing receiving address (not recommended)</source> - <translation>ש&ימוש חוזר בכתובת קבלה קיימת(לא מומלץ)</translation> + <translation>ש&ימוש &חוזר בכתובת קבלה קיימת (לא מומלץ)</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>הודעת רשות לצירוף לבקשת התשלום שתוצג בעת פתיחת הבקשה. לתשומת לבך: ההודעה לא תישלח עם התשלום ברשת ביטקוין.</translation> + </message> + <message> + <source>An optional label to associate with the new receiving address.</source> + <translation>תווית רשות לשיוך עם כתובת הקבלה החדשה.</translation> + </message> + <message> + <source>Use this form to request payments. All fields are <b>optional</b>.</source> + <translation>יש להשתמש בטופס זה כדי לבקש תשלומים. כל השדות הם בגדר <b>רשות</b>.</translation> + </message> + <message> + <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source> + <translation>סכום כרשות לבקשה. ניתן להשאיר זאת ריק כדי לא לבקש סכום מסוים.</translation> </message> <message> <source>Clear all fields of the form.</source> - <translation>נקה את כל השדות</translation> + <translation>ניקוי כל השדות של הטופס.</translation> </message> <message> <source>Clear</source> - <translation>נקה</translation> + <translation>ניקוי</translation> + </message> + <message> + <source>Requested payments history</source> + <translation>היסטוריית בקשות תשלום</translation> </message> <message> <source>&Request payment</source> - <translation>&בקש תשלום</translation> + <translation>&בקשת תשלום</translation> </message> <message> <source>Show the selected request (does the same as double clicking an entry)</source> - <translation>הצג בקשות נבחרות (דומה ללחיצה כפולה על רשומה)</translation> + <translation>הצגת בקשות נבחרות (דומה ללחיצה כפולה על רשומה)</translation> </message> <message> <source>Show</source> - <translation>הצג</translation> + <translation>הצגה</translation> </message> <message> <source>Remove the selected entries from the list</source> - <translation>הסר הרשומות הנבחרות מהרשימה</translation> + <translation>הסרת הרשומות הנבחרות מהרשימה</translation> </message> <message> <source>Remove</source> - <translation>הסר</translation> + <translation>הסרה</translation> </message> <message> <source>Copy label</source> - <translation>העתק תוית</translation> + <translation>העתקת תווית</translation> + </message> + <message> + <source>Copy message</source> + <translation>העתקת הודעה</translation> </message> <message> <source>Copy amount</source> - <translation>העתק כמות</translation> + <translation>העתקת כמות</translation> </message> </context> <context> @@ -1303,27 +1651,27 @@ Address: %4 </message> <message> <source>Copy &URI</source> - <translation>העתק &URI</translation> + <translation>העתקת &כתובת משאב</translation> </message> <message> <source>Copy &Address</source> - <translation>התעק &כתובת</translation> + <translation>העתקת &כתובת</translation> </message> <message> <source>&Save Image...</source> - <translation>&שמור תמונה..</translation> + <translation>&שמירת תמונה…</translation> </message> <message> <source>Request payment to %1</source> - <translation>בקש תשלום ל %1</translation> + <translation>בקשת תשלום לטובת %1</translation> </message> <message> <source>Payment information</source> - <translation>אנפרומצייה על התשלום</translation> + <translation>מידע על תשלום</translation> </message> <message> <source>URI</source> - <translation>כתובת (אתר או משאב)</translation> + <translation>כתובת משאב</translation> </message> <message> <source>Address</source> @@ -1335,7 +1683,7 @@ Address: %4 </message> <message> <source>Label</source> - <translation>תוית</translation> + <translation>תווית</translation> </message> <message> <source>Message</source> @@ -1343,11 +1691,11 @@ Address: %4 </message> <message> <source>Resulting URI too long, try to reduce the text for label / message.</source> - <translation>המזהה המתקבל ארוך מדי, נסה להפחית את הטקסט בתוית / הודעה.</translation> + <translation>כתובת המשאב המתקבלת ארוכה מדי, כדאי לנסות לצמצם את הטקסט בתווית / הודעה.</translation> </message> <message> <source>Error encoding URI into QR Code.</source> - <translation>שגיאה בקידוד URI לקוד QR</translation> + <translation>שגיאה בקידוד כתובת משאב לקוד QR</translation> </message> </context> <context> @@ -1358,7 +1706,7 @@ Address: %4 </message> <message> <source>Label</source> - <translation>תוית</translation> + <translation>תווית</translation> </message> <message> <source>Message</source> @@ -1370,30 +1718,34 @@ Address: %4 </message> <message> <source>(no label)</source> - <translation>(ללא תוית)</translation> + <translation>(אין תווית)</translation> </message> <message> <source>(no message)</source> - <translation>(אין הודעות)</translation> + <translation>(אין הודעה)</translation> </message> - </context> + <message> + <source>(no amount)</source> + <translation>(אין סכום)</translation> + </message> +</context> <context> <name>SendCoinsDialog</name> <message> <source>Send Coins</source> - <translation>שלח מטבעות</translation> + <translation>שליחת מטבעות</translation> </message> <message> <source>Coin Control Features</source> - <translation>ה</translation> + <translation>תכונות בקרת מטבעות</translation> </message> <message> <source>Inputs...</source> - <translation>כניסות...</translation> + <translation>קלטים…</translation> </message> <message> <source>automatically selected</source> - <translation>נבחר אוטומאטית</translation> + <translation>בבחירה אוטומטית</translation> </message> <message> <source>Insufficient funds!</source> @@ -1405,19 +1757,19 @@ Address: %4 </message> <message> <source>Bytes:</source> - <translation>בייטים:</translation> + <translation>בתים:</translation> </message> <message> <source>Amount:</source> - <translation>כמות:</translation> + <translation>סכום:</translation> </message> <message> <source>Priority:</source> - <translation>קדימות:</translation> + <translation>עדיפות:</translation> </message> <message> <source>Fee:</source> - <translation>תשלום:</translation> + <translation>עמלה:</translation> </message> <message> <source>After Fee:</source> @@ -1425,7 +1777,11 @@ Address: %4 </message> <message> <source>Change:</source> - <translation>שינוי:</translation> + <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> @@ -1433,35 +1789,39 @@ Address: %4 </message> <message> <source>Send to multiple recipients at once</source> - <translation>שלח למספר מקבלים בו-זמנית</translation> + <translation>שליחה למספר מוטבים בו־זמנית</translation> </message> <message> <source>Add &Recipient</source> - <translation>הוסף מקבל</translation> + <translation>הוספת &מוטב</translation> </message> <message> <source>Clear all fields of the form.</source> - <translation>נקה את כל השדות</translation> + <translation>ניקוי של כל השדות בטופס.</translation> + </message> + <message> + <source>Dust:</source> + <translation>אבק:</translation> </message> <message> <source>Clear &All</source> - <translation>נקה הכל</translation> + <translation>ניקוי ה&כול</translation> </message> <message> <source>Balance:</source> - <translation>יתרה:</translation> + <translation>מאזן:</translation> </message> <message> <source>Confirm the send action</source> - <translation>אשר את פעולת השליחה</translation> + <translation>אישור פעולת השליחה</translation> </message> <message> <source>S&end</source> - <translation>שלח</translation> + <translation>&שליחה</translation> </message> <message> <source>Confirm send coins</source> - <translation>אשר שליחת מטבעות</translation> + <translation>אישור שליחת מטבעות</translation> </message> <message> <source>%1 to %2</source> @@ -1469,31 +1829,35 @@ Address: %4 </message> <message> <source>Copy quantity</source> - <translation>העתק כמות</translation> + <translation>העתקת כמות</translation> </message> <message> <source>Copy amount</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 change</source> - <translation>העתק עודף</translation> + <translation>העתקת עודף</translation> + </message> + <message> + <source>Total Amount %1 (= %2)</source> + <translation>הסכום הכולל %1 (= %2)</translation> </message> <message> <source>or</source> @@ -1501,11 +1865,11 @@ Address: %4 </message> <message> <source>The recipient address is not valid, please recheck.</source> - <translation>כתובת המקבל אינה תקינה, אנא בדוק שנית.</translation> + <translation>כתובת המוטב אינה תקינה, נא לבדוק שוב.</translation> </message> <message> <source>The amount to pay must be larger than 0.</source> - <translation>הכמות לשלם חייבת להיות גדולה מ-0.</translation> + <translation>הכמות לתשלום חייבת להיות גדולה מ־0.</translation> </message> <message> <source>The amount exceeds your balance.</source> @@ -1513,7 +1877,7 @@ Address: %4 </message> <message> <source>The total exceeds your balance when the %1 transaction fee is included.</source> - <translation>הכמות הכוללת, ובכללה עמלת פעולה בסך %1, עולה על המאזן שלך.</translation> + <translation>הכמות הכוללת, ובכללה עמלת העברה בסך %1, עולה על המאזן שלך.</translation> </message> <message> <source>Duplicate address found, can only send to each address once per send operation.</source> @@ -1521,11 +1885,27 @@ Address: %4 </message> <message> <source>Transaction creation failed!</source> - <translation>יצירת הפעולה נכשלה!</translation> + <translation>יצירת ההעברה נכשלה!</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>ההעברה נדחתה! מצב כזה עשוי לקרות אם חלק מהמטבעות בארנק שלך כבר הושקעו, כמו למשל עקב שימוש בעותק של wallet.dat והמטבעות הושקעו בעותק אבל לא סומנו כאילו הושקעו דרך כאן.</translation> + </message> + <message> + <source>Warning: Invalid Bitcoin address</source> + <translation>אזהרה: כתובת ביטקוין שגויה</translation> </message> <message> <source>(no label)</source> - <translation>(ללא תוית)</translation> + <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> @@ -1533,48 +1913,56 @@ Address: %4 </message> <message> <source>added as transaction fee</source> - <translation>הוסף מחיר טיפול</translation> + <translation>נוסף כעמלת העברה</translation> </message> </context> <context> <name>SendCoinsEntry</name> <message> <source>A&mount:</source> - <translation>כ&מות:</translation> + <translation>&כמות:</translation> </message> <message> <source>Pay &To:</source> - <translation>שלם &ל:</translation> + <translation>לשלם ל&טובת:</translation> </message> <message> <source>Enter a label for this address to add it to your address book</source> - <translation>הכנס תוית לכתובת הזאת כדי להכניס לפנקס הכתובות</translation> + <translation>נא להכניס תווית לכתובת הזאת כדי להוסיף לפנקס הכתובות</translation> </message> <message> <source>&Label:</source> - <translation>ת&וית:</translation> + <translation>ת&ווית:</translation> </message> <message> <source>Choose previously used address</source> - <translation>בחר כתובת שהייתה בשימוש</translation> + <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> <message> <source>Paste address from clipboard</source> - <translation>הדבר כתובת מהלוח</translation> + <translation>הדבקת כתובת מלוח הגזירים</translation> </message> <message> <source>Alt+P</source> <translation>Alt+P</translation> </message> <message> + <source>Remove this entry</source> + <translation>הסרת רשומה זו</translation> + </message> + <message> <source>Message:</source> <translation>הודעה:</translation> </message> @@ -1584,7 +1972,11 @@ Address: %4 </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> - <translation>הקלד תווית עבור כתובת זו בכדי להוסיף אותה לרשימת הכתובות בשימוש</translation> + <translation>יש להזין תווית עבור כתובת זו כדי להוסיף אותה לרשימת הכתובות בשימוש</translation> + </message> + <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>הודעה שצורפה לביטקוין: כתובת שתאוחסן בהעברה לצורך מעקב מצדך. לתשומת לבך: הודעה זו לא תישלח ברשת הביטקוין.</translation> </message> <message> <source>This is an unverified payment request.</source> @@ -1592,7 +1984,7 @@ Address: %4 </message> <message> <source>Pay To:</source> - <translation>תשלום ל:</translation> + <translation>תשלום לטובת:</translation> </message> <message> <source>Memo:</source> @@ -1602,6 +1994,10 @@ Address: %4 <context> <name>ShutdownWindow</name> <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> @@ -1610,19 +2006,23 @@ Address: %4 <name>SignVerifyMessageDialog</name> <message> <source>Signatures - Sign / Verify a Message</source> - <translation>חתימות - חתום או אמת הודעה</translation> + <translation>חתימות - חתימה או אימות של הודעה</translation> </message> <message> <source>&Sign Message</source> - <translation>חתום על הו&דעה</translation> + <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> + <translation>ניתן לחתום על הודעות עם הכתובות שלך כדי להוכיח שהן בבעלותך. מומלץ להיזהר לא לחתום על משהו מפוקפק, שכן התקפות דיוג עשויות לגרום לך בעורמה למסור את זהותך. רצוי לחתום רק על הצהרות מפורטות לחלוטין שהסכמת עמן.</translation> + </message> + <message> + <source>The Bitcoin address to sign the message with</source> + <translation>כתובת הביטקוין אתה לחתום אתה את ההודעה</translation> </message> <message> <source>Choose previously used address</source> - <translation>בחר כתובת שהייתה בשימוש</translation> + <translation>בחירת כתובת שהייתה בשימוש</translation> </message> <message> <source>Alt+A</source> @@ -1630,7 +2030,7 @@ Address: %4 </message> <message> <source>Paste address from clipboard</source> - <translation>הדבק כתובת מהלוח</translation> + <translation>הדבקת כתובת מלוח הגזירים</translation> </message> <message> <source>Alt+P</source> @@ -1638,7 +2038,7 @@ Address: %4 </message> <message> <source>Enter the message you want to sign here</source> - <translation>הכנס כאן את ההודעה שעליך ברצונך לחתום</translation> + <translation>יש להוסיף כאן את ההודעה עליה לחתום</translation> </message> <message> <source>Signature</source> @@ -1646,47 +2046,51 @@ Address: %4 </message> <message> <source>Copy the current signature to the system clipboard</source> - <translation>העתק את החתימה הנוכחית ללוח המערכת</translation> + <translation>העתקת החתימה הנוכחית ללוח הגזירים</translation> </message> <message> <source>Sign the message to prove you own this Bitcoin address</source> - <translation>חתום על ההודעה כדי להוכיח שכתובת הביטקוין הזו בבעלותך.</translation> + <translation>ניתן לחתום על ההודעה כדי להוכיח שכתובת הביטקוין הזו בבעלותך.</translation> </message> <message> <source>Sign &Message</source> - <translation>חתום על הודעה</translation> + <translation>&חתימה על הודעה</translation> </message> <message> <source>Reset all sign message fields</source> - <translation>אפס את כל שדות החתימה על הודעה</translation> + <translation>איפוס כל שדות החתימה על הודעה</translation> </message> <message> <source>Clear &All</source> - <translation>נקה הכל</translation> + <translation>&ניקוי הכול</translation> </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> </message> <message> + <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> - <translation>אמת את ההודעה כדי להבטיח שהיא נחתמה עם כתובת הביטקוין הנתונה</translation> + <translation>ניתן לאמת את ההודעה כדי להבטיח שהיא נחתמה עם כתובת הביטקוין הנתונה</translation> </message> <message> <source>Verify &Message</source> - <translation>אימות הודעה</translation> + <translation>&אימות הודעה</translation> </message> <message> <source>Reset all verify message fields</source> - <translation>אפס את כל שדות אימות הודעה</translation> + <translation>איפוס כל שדות אימות ההודעה</translation> </message> <message> <source>Click "Sign Message" to generate signature</source> - <translation>לחץ "חתום על ההודעה" כדי לחולל חתימה</translation> + <translation>יש ללחוץ על „חתימה על ההודעה“ כדי לחולל חתימה</translation> </message> <message> <source>The entered address is invalid.</source> @@ -1694,7 +2098,7 @@ Address: %4 </message> <message> <source>Please check the address and try again.</source> - <translation>אנא בדוק את הכתובת ונסה שנית.</translation> + <translation>נא לבדוק את הכתובת לנסות שנית.</translation> </message> <message> <source>The entered address does not refer to a key.</source> @@ -1722,7 +2126,7 @@ Address: %4 </message> <message> <source>Please check the signature and try again.</source> - <translation>אנא בדוק את החתימה ונסה שנית.</translation> + <translation>נא לבדוק את החתימה ולנסות שנית.</translation> </message> <message> <source>The signature did not match the message digest.</source> @@ -1744,6 +2148,10 @@ Address: %4 <translation>ליבת ביטקוין</translation> </message> <message> + <source>The Bitcoin Core developers</source> + <translation>מתכנתי ליבת ביטקוין</translation> + </message> + <message> <source>[testnet]</source> <translation>[רשת-בדיקה]</translation> </message> @@ -1752,14 +2160,18 @@ Address: %4 <name>TrafficGraphWidget</name> <message> <source>KB/s</source> - <translation>קילו בייט לשניה</translation> + <translation>ק״ב/ש׳</translation> </message> </context> <context> <name>TransactionDesc</name> <message> <source>Open until %1</source> - <translation>פתוח עד %1</translation> + <translation>פתוחה עד %1</translation> + </message> + <message> + <source>conflicted</source> + <translation>מתנגש</translation> </message> <message> <source>%1/offline</source> @@ -1767,7 +2179,7 @@ Address: %4 </message> <message> <source>%1/unconfirmed</source> - <translation>%1/ממתין לאישור</translation> + <translation>%1/המתנה לאישור</translation> </message> <message> <source>%1 confirmations</source> @@ -1802,8 +2214,12 @@ Address: %4 <translation>כתובת עצמית</translation> </message> <message> + <source>watch-only</source> + <translation>צפייה בלבד</translation> + </message> + <message> <source>label</source> - <translation>תוית</translation> + <translation>תווית</translation> </message> <message> <source>Credit</source> @@ -1818,12 +2234,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> + <translation>עמלת העברה</translation> </message> <message> <source>Net amount</source> - <translation>כמות נקיה</translation> + <translation>כמות נקייה</translation> </message> <message> <source>Message</source> @@ -1835,7 +2259,7 @@ Address: %4 </message> <message> <source>Transaction ID</source> - <translation>זיהוי פעולה</translation> + <translation>מזהה העברה</translation> </message> <message> <source>Merchant</source> @@ -1843,7 +2267,7 @@ Address: %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>מטבעות חדשים שנוצרו חייבים להבשיל במשך %1 בלוקים לפני שניתן לנצל אותם. כשבלוק זה נוצר הוא שודר ברשת על מנת שייכנס לשרשרת הבלוקים. במקרה והוא לא ייכנס לשרשרת, מצבו ישתנה ל"לא התקבל" ולא ניתן יהיה לנצלו. זה יכול לקרות מדי פעם אם במקרה צומת אחרת ייצרה בלוק בהבדל של שניות בודדות ממך.</translation> + <translation>מטבעות חדשים שנוצרו חייבים להבשיל במשך %1 מקטעים לפני שניתן לנצל אותם. כשמקטע זה נוצר הוא משודר ברשת על מנת שייכנס לשרשרת המקטעים. אם הוא לא ייכנס לשרשרת, מצבו ישתנה ל„לא התקבל“ ולא ניתן יהיה לנצלו. מצב כזה יכול לקרות מדי פעם אם במקרה מפרק אחר יצר מקטע בהבדל של שניות בודדות ממך.</translation> </message> <message> <source>Debug information</source> @@ -1851,7 +2275,7 @@ Address: %4 </message> <message> <source>Transaction</source> - <translation>פעולה</translation> + <translation>העברה</translation> </message> <message> <source>Inputs</source> @@ -1875,7 +2299,7 @@ Address: %4 </message> <message numerus="yes"> <source>Open for %n more block(s)</source> - <translation><numerusform>פתח למשך בלוק %n יותר</numerusform><numerusform>פתח למשך %n בלוקים נוספים</numerusform></translation> + <translation><numerusform>פתיחה למשך מקטע %n נוסף</numerusform><numerusform>פתיחה למשך %n מקטעים נוספים</numerusform></translation> </message> <message> <source>unknown</source> @@ -1886,11 +2310,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> @@ -1907,13 +2331,17 @@ Address: %4 <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> + <translation><numerusform>פתח למשך בלוק %n יותר</numerusform><numerusform>פתיחה למשך %n מקטעים נוספים</numerusform></translation> </message> <message> <source>Open until %1</source> - <translation>פתוח עד %1</translation> + <translation>פתוחה עד %1</translation> </message> <message> <source>Confirmed (%1 confirmations)</source> @@ -1921,13 +2349,29 @@ Address: %4 </message> <message> <source>This block was not received by any other nodes and will probably not be accepted!</source> - <translation>הבלוק הזה לא נקלט על ידי אף צומת אחר, וכנראה לא יתקבל!</translation> + <translation>המקטע הזה לא נקלט על ידי אף מפרק אחר, וכנראה לא יתקבל!</translation> </message> <message> <source>Generated but not accepted</source> <translation>נוצר אך לא התקבל</translation> </message> <message> + <source>Offline</source> + <translation>מנותק</translation> + </message> + <message> + <source>Unconfirmed</source> + <translation>ללא אישור</translation> + </message> + <message> + <source>Confirming (%1 of %2 recommended confirmations)</source> + <translation>מתקבל אישור (%1 מתוך %2 אישורים מומלצים)</translation> + </message> + <message> + <source>Conflicted</source> + <translation>מתנגש</translation> + </message> + <message> <source>Received with</source> <translation>התקבל עם</translation> </message> @@ -1937,7 +2381,7 @@ Address: %4 </message> <message> <source>Sent to</source> - <translation>נשלח ל</translation> + <translation>נשלח אל</translation> </message> <message> <source>Payment to yourself</source> @@ -1948,24 +2392,32 @@ Address: %4 <translation>נכרה</translation> </message> <message> + <source>watch-only</source> + <translation>צפייה בלבד</translation> + </message> + <message> <source>(n/a)</source> - <translation>(n/a)</translation> + <translation>(לא זמין)</translation> </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> + <translation>סוג ההעברה.</translation> + </message> + <message> + <source>Whether or not a watch-only address is involved in this 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> @@ -1976,7 +2428,7 @@ Address: %4 <name>TransactionView</name> <message> <source>All</source> - <translation>הכל</translation> + <translation>הכול</translation> </message> <message> <source>Today</source> @@ -2000,7 +2452,7 @@ Address: %4 </message> <message> <source>Range...</source> - <translation>טווח...</translation> + <translation>טווח…</translation> </message> <message> <source>Received with</source> @@ -2008,7 +2460,7 @@ Address: %4 </message> <message> <source>Sent to</source> - <translation>נשלח ל</translation> + <translation>נשלח אל</translation> </message> <message> <source>To yourself</source> @@ -2024,7 +2476,7 @@ Address: %4 </message> <message> <source>Enter address or label to search</source> - <translation>הכנס כתובת או תוית לחפש</translation> + <translation>נא להכניס כתובת או תווית לחיפוש</translation> </message> <message> <source>Min amount</source> @@ -2032,47 +2484,55 @@ Address: %4 </message> <message> <source>Copy address</source> - <translation>העתק כתובת</translation> + <translation>העתקת כתובת</translation> </message> <message> <source>Copy label</source> - <translation>העתק תוית</translation> + <translation>העתקת תווית</translation> </message> <message> <source>Copy amount</source> - <translation>העתק כמות</translation> + <translation>העתקת כמות</translation> </message> <message> <source>Copy transaction ID</source> - <translation>העתק מזהה פעולה</translation> + <translation>העתקת מזהה העברה</translation> </message> <message> <source>Edit label</source> - <translation>ערוך תוית</translation> + <translation>עריכת תווית</translation> </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>Watch-only</source> + <translation>צפייה בלבד</translation> </message> <message> <source>Exporting Failed</source> - <translation>הייצוא נכשל</translation> + <translation>היצוא נכשל</translation> + </message> + <message> + <source>There was an error trying to save the transaction history to %1.</source> + <translation>אירעה שגיאה בעת ניסיון לשמור את היסטוריית ההעברות אל %1.</translation> </message> <message> <source>Exporting Successful</source> - <translation>הייצוא בוצע בהצלחה</translation> + <translation>היצוא בוצע בהצלחה</translation> </message> <message> <source>The transaction history was successfully saved to %1.</source> - <translation>היסטוריית הפעולות נשמרה ל־%1 בהצלחה.</translation> + <translation>היסטוריית ההעברות נשמרה ל־%1 בהצלחה.</translation> </message> <message> <source>Comma separated file (*.csv)</source> - <translation>קובץ מופרד בפסיקים (*.csv)</translation> + <translation>קובץ מופרד בפסיקים (*.csv)</translation> </message> <message> <source>Confirmed</source> @@ -2088,7 +2548,7 @@ Address: %4 </message> <message> <source>Label</source> - <translation>תוית</translation> + <translation>תווית</translation> </message> <message> <source>Address</source> @@ -2109,7 +2569,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> @@ -2121,34 +2585,42 @@ Address: %4 <name>WalletModel</name> <message> <source>Send Coins</source> - <translation>שלח מטבעות</translation> + <translation>שליחת מטבעות</translation> </message> </context> <context> <name>WalletView</name> <message> <source>&Export</source> - <translation>&ייצא</translation> + <translation>י&צוא</translation> </message> <message> <source>Export the data in the current tab to a file</source> - <translation>יצוא הנתונים בטאב הנוכחי לקובץ</translation> + <translation>יצוא הנתונים מהלשונית הנוכחית לקובץ</translation> </message> <message> <source>Backup Wallet</source> - <translation>גבה ארנק</translation> + <translation>גיבוי ארנק</translation> </message> <message> <source>Wallet Data (*.dat)</source> - <translation>נתוני ארנק (*.dat)</translation> + <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> + <translation>הגיבוי הושלם בהצלחה</translation> </message> </context> <context> @@ -2158,60 +2630,32 @@ Address: %4 <translation>אפשרויות:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>ציין קובץ הגדרות (ברירת מחדל: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>ציין קובץ pid (ברירת מחדל: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> - <translation>ציין תיקיית נתונים</translation> - </message> - <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>האזן לחיבורים ב<פורט> (ברירת מחדל: 8333 או ברשת הבדיקה: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>החזק לכל היותר <n> חיבורים לעמיתים (ברירת מחדל: 125)</translation> + <translation>ציון תיקיית נתונים</translation> </message> <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> - <translation>התחבר לצומת כדי לדלות כתובות עמיתים, ואז התנתק</translation> + <translation>יש להתחבר למפרק כדי לדלות כתובות עמיתים ואז להתנתק</translation> </message> <message> <source>Specify your own public address</source> - <translation>ציין את הכתובת הפומבית שלך</translation> - </message> - <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>סף להתנתקות מעמיתים הנוהגים שלא כהלכה (ברירת מחדל: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>מספר שניות למנוע מעמיתים הנוהגים שלא כהלכה מלהתחבר מחדש (ברירת מחדל: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>האזן לחיבורי JSON-RPC ב- <port> (ברירת מחדל: 8332 או רשת בדיקה: 18332)</translation> + <translation>נא לציין את הכתובת הפומבית שלך</translation> </message> <message> <source>Accept command line and JSON-RPC commands</source> - <translation>קבל פקודות משורת הפקודה ו- JSON-RPC</translation> + <translation>קבלת פקודות משורת הפקודה ומ־JSON-RPC</translation> </message> <message> <source>Run in the background as a daemon and accept commands</source> - <translation>רוץ ברקע כדימון וקבל פקודות</translation> + <translation>ריצה כסוכן ברקע וקבלת פקודות</translation> </message> <message> <source>Use the test network</source> - <translation>השתמש ברשת הבדיקה</translation> + <translation>שימוש ברשת הבדיקה</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> - <translation>קבל חיבורים מבחוץ (ברירת מחדל: 1 ללא -proxy או -connect)</translation> + <translation>קבלת חיבורים מבחוץ (בררת מחדל: 1 ללא -proxy או -connect)</translation> </message> <message> <source>%s, you must set a rpcpassword in the configuration file: @@ -2225,61 +2669,77 @@ 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>%s, עליך לקבוע סיסמת RPC בקובץ הקונפיגורציה: + <translation>%s, עליך להגדיר את ססמת ה־RPC בקובץ התצורה: %s -מומלץ להשתמש בסיסמא האקראית הבאה: +מומלץ להשתמש בססמה האקראית הבאה: rpcuser=bitcoinrpc rpcpassword=%s -(אין צורך לזכור את הסיסמה) -אסור ששם המשתמש והסיסמא יהיו זהים. -אם הקובץ אינו קיים, צור אותו עם הרשאות קריאה לבעלים בלבד. -זה מומלץ לסמן alertnotify כדי לקבל דיווח על תקלות; +(אין צורך לזכור את הססמה) +אסור ששם המשתמש והססמה יהיו זהים. +אם הקובץ אינו קיים, יש ליצור אותו עם הרשאות קריאה לבעלים בלבד. +כמו כן, מומלץ להגדיר את alertnotify כדי לקבל דיווח על תקלות; למשל: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>צפנים קבילים (ברירת מחדל: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> + <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> + <translation>להתאגד לכתובת נתונה להאזין לה תמיד. יש להשתמש בצורה [host]:port עבור IPv6.</translation> </message> <message> - <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> - <translation>קשור עם כתובת נתונה והאזן לה תמיד. השתמש בסימון [host]:port עבוד IPv6.</translation> + <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> + <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>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.</source> - <translation>שגיאה: הפעולה נדחתה! זה עלול לקרות אם כמה מהמטבעות בארנק שלך כבר נוצלו, למשל אם השתמשת בעותק של wallet.dat ומטבעות נשלחו בעותק אך לא סומנו כמנוצלות כאן.</translation> + <translation>שגיאה: ההעברה נדחתה! מצב כזה עלול לקרות אם כמה מהמטבעות בארנק שלך כבר נוצלו, למשל אם השתמשת בעותק של wallet.dat ומטבעות נשלחו בעותק אך לא סומנו כמושקעות כאן.</translation> </message> <message> <source>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</source> - <translation>שגיאה: הפעולה הזאת דורשת עמלת פעולה של לפחות %s עקב הכמות, המורכבות, או השימוש בכספים שהתקבלו לאחרונה!</translation> + <translation>שגיאה: ההעברה הזאת דורשת עמלת פעולה של לפחות %s עקב הכמות, המורכבות או השימוש בכספים שהתקבלו לאחרונה!</translation> </message> <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> - <translation>בצע פקודה כאשר פעולת ארנק משתנה (%s ב cmd יוחלף ב TxID)</translation> + <translation>ביצוע פקודה כאשר העברה בארנק משתנה (%s ב־cmd יוחלף ב־TxID)</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>זוהי בניית ניסיון טרום-שחרור - השימוש בה על אחריותך - אין להשתמש לצורך כריה או יישומי מסחר</translation> </message> <message> + <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source> + <translation>לא ניתן להתאגד אל %s במחשב זה. כנראה שליבת ביטקוין כבר פועלת.</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>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> - <translation>אזהרה: נראה שלא כל הרשת מסכימה! נראה שישנם כורים אשר נתקלים בבעיות.</translation> + <translation>אזהרה: נראה שלא כל הרשת מסכימה! נראה שישנם כורים שנתקלים בבעיות.</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>אזהרה: נראה שאנחנו לא מסכימים לחלוטין עם העמיתים שלנו! ייתכן ואנחנו צריכים לשדרג, או שצמתים אחרות צריכות לשדרג.</translation> + <translation>אזהרה: נראה שישנה אי־הסכמה בינינו לבין שאר העמיתים שלנו! יתכן שעדיף לשדרג או שכל שאר העמיתים צריכים לשדרג.</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>אזהרה: שגיאה בקריאת wallet.dat! כל המתפחות נקראו באופן תקין, אך נתוני הפעולות או ספר הכתובות עלולים להיות חסרים או שגויים.</translation> + <translation>אזהרה: שגיאה בקריאת wallet.dat! כל המפתחות נקראו באופן תקין, אך נתוני ההעברות או ספר הכתובות עלולים להיות חסרים או שגויים.</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>אזהרה: קובץ wallet.dat מושחת, המידע חולץ! קובץ wallet.dat המקורח נשמר כ - wallet.{timestamp}.bak ב - %s; אם המאזן או הפעולות שגויים עליך לשחזר גיבוי.</translation> + <translation>אזהרה: הקובץ wallet.dat הושחת, המידע חולץ! קובץ ה־wallet.dat המקורי נשמר בשם wallet.{timestamp}.bak במיקום %s; אם המאזן או ההעברות שגויים עליך לשחזר גיבוי.</translation> + </message> + <message> + <source>(default: 1)</source> + <translation>(בררת מחדל: 1)</translation> + </message> + <message> + <source><category> can be:</source> + <translation><קטגוריה> יכולה להיות:</translation> </message> <message> <source>Attempt to recover private keys from a corrupt wallet.dat</source> @@ -2287,7 +2747,7 @@ rpcpassword=%s </message> <message> <source>Block creation options:</source> - <translation>אפשרויות יצירת בלוק:</translation> + <translation>אפשרויות יצירת מקטע:</translation> </message> <message> <source>Connect only to the specified node(s)</source> @@ -2299,19 +2759,27 @@ rpcpassword=%s </message> <message> <source>Corrupted block database detected</source> - <translation>התגלה מסד נתוני בלוקים לא תקין</translation> + <translation>התגלה מסד נתוני מקטעים לא תקין</translation> + </message> + <message> + <source>Debugging/Testing options:</source> + <translation>אפשרויות ניפוי/בדיקה:</translation> </message> <message> <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>גלה את כתובת ה-IP העצמית (ברירת מחדל: 1 כשמאזינים וללא -externalip)</translation> + <translation>לגלות את כתובת ה־IP העצמית (בררת מחדל: 1 בעת האזנה וללא -externalip)</translation> + </message> + <message> + <source>Do not load the wallet and disable wallet RPC calls</source> + <translation>לא לטעון את הארנק ולנטרל קריאות RPC</translation> </message> <message> <source>Do you want to rebuild the block database now?</source> - <translation>האם תרצה כעט לבנות מחדש את מסד נתוני הבלוקים?</translation> + <translation>האם לבנות מחדש את מסד נתוני המקטעים?</translation> </message> <message> <source>Error initializing block database</source> - <translation>שגיאה באתחול מסד נתוני הבלוקים</translation> + <translation>שגיאה באתחול מסד נתוני המקטעים</translation> </message> <message> <source>Error initializing wallet database environment %s!</source> @@ -2319,209 +2787,229 @@ rpcpassword=%s </message> <message> <source>Error loading block database</source> - <translation>שגיאה בטעינת מסד נתוני הבלוקים</translation> + <translation>שגיאה בטעינת מסד נתוני המקטעים</translation> </message> <message> <source>Error opening block database</source> - <translation>שגיאה בטעינת מסד נתוני הבלוקים</translation> + <translation>שגיאה בטעינת מסד נתוני המקטעים</translation> </message> <message> <source>Error: Disk space is low!</source> - <translation>שגיאה: מעט מקום פנוי בדיסק!</translation> + <translation>שגיאה: מעט מקום פנוי בכונן!</translation> </message> <message> <source>Error: Wallet locked, unable to create transaction!</source> - <translation>שגיאה: הארנק נעול, אין אפשרות ליצור פעולה!</translation> - </message> - <message> - <source>Error: system error: </source> - <translation>שגיאה: שגיאת מערכת:</translation> + <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>Failed to read block info</source> - <translation>קריאת מידע הבלוקים נכשלה</translation> + <source>If <category> is not supplied, output all debugging information.</source> + <translation>אם לא סופקה <קטגוריה> יש לייצא את כל פרטי הניפוי.</translation> + </message> + <message> + <source>Importing...</source> + <translation>מתבצע יבוא…</translation> + </message> + <message> + <source>Incorrect or no genesis block found. Wrong datadir for network?</source> + <translation>מקטע הפתיח הוא שגוי או לא נמצא. תיקיית נתונים שגויה עבור הרשת?</translation> + </message> + <message> + <source>Invalid -onion address: '%s'</source> + <translation>כתובת onion- שגויה: '%s'</translation> </message> <message> - <source>Failed to read block</source> - <translation>קריאת הבלוק נכשלה</translation> + <source>Not enough file descriptors available.</source> + <translation>אין מספיק מידע על הקובץ</translation> </message> <message> - <source>Failed to sync block index</source> - <translation>סנכרון אינדקס הבלוקים נכשל</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>תמיד להתחבר למפרקים ברשת <net> (ipv4, ipv6 או onion)</translation> </message> <message> - <source>Failed to write block index</source> - <translation>כתיבת אינדקס הבלוקים נכשל</translation> + <source>Rebuild block chain index from current blk000??.dat files</source> + <translation>בנייה מחדש של מפתח שרשרת המקטעים מקובצי ה־blk000??.dat הנוכחיים.</translation> </message> <message> - <source>Failed to write block info</source> - <translation>כתיבת מידע הבלוקים נכשל</translation> + <source>Set database cache size in megabytes (%d to %d, default: %d)</source> + <translation>הגדרת גודל מטמון מסדי הנתונים במגה בתים (%d עד %d, בררת מחדל: %d)</translation> </message> <message> - <source>Failed to write block</source> - <translation>כתיבת הבלוק נכשלה</translation> + <source>Set maximum block size in bytes (default: %d)</source> + <translation>הגדרת קובץ מקטע מרבי בבתים (בררת מחדל: %d)</translation> </message> <message> - <source>Failed to write file info</source> - <translation>כתיבת מידע הקבצים נכשלה</translation> + <source>Specify wallet file (within data directory)</source> + <translation>ציון קובץ ארנק (בתוך תיקיית הנתונים)</translation> </message> <message> - <source>Failed to write to coin database</source> - <translation>כתיבת מסד נתוני המטבעות נכשלה</translation> + <source>This is intended for regression testing tools and app development.</source> + <translation>תכונה זו מיועדת לכלי בדיקות נסיגה ופיתוח יישומים.</translation> </message> <message> - <source>Failed to write transaction index</source> - <translation>כתיבת אינדקס הפעולות נכשלה</translation> + <source>Verifying blocks...</source> + <translation>המקטעים מאומתים…</translation> </message> <message> - <source>Failed to write undo data</source> - <translation>כתיבת נתוני ביטול נכשלה</translation> + <source>Verifying wallet...</source> + <translation>הארנק מאומת…</translation> </message> <message> - <source>Generate coins (default: 0)</source> - <translation>ייצר מטבעות (ברגיל: 0)</translation> + <source>Wallet %s resides outside data directory %s</source> + <translation>הארנק %s יושב מחוץ לתיקיית הנתונים %s</translation> </message> <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>מספר הבלוקים לבדוק בעת אתחול (ברירת מחדל: 288, 0 = כולם)</translation> + <source>Wallet options:</source> + <translation>אפשרויות הארנק:</translation> </message> <message> - <source>Incorrect or no genesis block found. Wrong datadir for network?</source> - <translation>בלוק בראשית הינו שגוי או לא נמצא. ספריית מידע לא נכונה עבור הרשת?</translation> + <source>You need to rebuild the database using -reindex to change -txindex</source> + <translation>עליך לבנות מחדש את מסד הנתונים תוך שימוש ב־-reindex על מנת לשנות את -txindex</translation> </message> <message> - <source>Invalid -onion address: '%s'</source> - <translation>כתובת onion- שגויה: '%s'</translation> + <source>Imports blocks from external blk000??.dat file</source> + <translation>מיובאים מקטעים מקובצי blk000??.dat חיצוניים</translation> </message> <message> - <source>Not enough file descriptors available.</source> - <translation>אין מספיק מידע על הקובץ</translation> + <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>הרץ פקודה כאשר ההתראה הרלוונטית מתקבלת או כשאנחנו עדים לפיצול ארוך מאוד (%s בשורת הפקודה יוחלף ע"י ההודעה)</translation> </message> <message> - <source>Rebuild block chain index from current blk000??.dat files</source> - <translation>בנה מחדש את אינדק שרשרת הבלוקים מקבצי ה-blk000??.dat הנוכחיים.</translation> + <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>Set the number of threads to service RPC calls (default: 4)</source> - <translation>קבע את מספר תהליכוני לשירות קריאות RPC (ברירת מחדל: 4)</translation> + <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>Specify wallet file (within data directory)</source> - <translation>ציין קובץ ארנק (בתוך ספריית המידע)</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>לא ניתן לפתור את הכתובת -whitebind: '%s'</translation> </message> <message> - <source>Verifying blocks...</source> - <translation>מאמת את שלמות מסד הנתונים...</translation> + <source>Connect through SOCKS5 proxy</source> + <translation>התחברות דרך מתווך SOCKS5</translation> </message> <message> - <source>Verifying wallet...</source> - <translation>מאמת את יושרת הארנק...</translation> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>כל הזכויות שמורות (C) 2009-%i מתכנתי ליבת ביטקוין</translation> </message> <message> - <source>Wallet %s resides outside data directory %s</source> - <translation>הארנק %s יושב מחוץ לספריית המידע %s</translation> + <source>Could not parse -rpcbind value %s as network address</source> + <translation>לא ניתן לנתח את הערך של -rpcbind שצוין בתור %s ככתובת רשת</translation> </message> <message> - <source>You need to rebuild the database using -reindex to change -txindex</source> - <translation>עליך לבנות מחדש את מסד הנתונים תוך שימוש ב- -reindex על מנת לשנות את -txindex</translation> + <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> + <translation>אירעה שגיאה בטעינת wallet.dat: הארנק דורש גרסה חדשה יותר של ליבת ביטקוין</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>מייבא בלוקים מקובצי blk000??.dat חיצוניים</translation> + <source>Error: Unsupported argument -tor found, use -onion.</source> + <translation>שגיאה: נמצא ארגומנט בלתי נתמך -tor, יש להשתמש ב־-onion.</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>הרץ פקודה כאשר ההתראה הרלוונטית מתקבלת או כשאנחנו עדים לפיצול ארוך מאוד (%s בשורת הפקודה יוחלף ע"י ההודעה)</translation> + <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> + <translation>עמלה (ב־BTC/ק״ב) להוספה להעברות שנשלחות ממך (בררת מחדל: %s)</translation> </message> <message> <source>Information</source> <translation>מידע</translation> </message> <message> + <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source> + <translation>בדיקת התקינות ההתחלתית נכשלה. ליבת ביטקוין תיסגר כעת.</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>כמות לא תקינה עבור -paytxfee=<amount>: '%s'</translation> </message> <message> <source>Invalid amount for -mintxfee=<amount>: '%s'</source> - <translation>כמות לא תקינה עבור -paytxfee=<amount>: '%s'</translation> + <translation>כמות לא תקינה עבור -mintxfee=<amount>: '%s'</translation> + </message> + <message> + <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> + <translation>כמות לא תקינה עבור -paytxfee=<amount>: '%s' (חייבת להיות לפחות %s)</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>תחזק אינדקס פעולות מלא (ברירת מחדל: 0)</translation> + <source>Invalid netmask specified in -whitelist: '%s'</source> + <translation>מסכת הרשת שצוינה עם -whitelist שגויה: '%s'</translation> </message> <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>חוצץ קבלה מירבי לכל חיבור, <n>*1000 בתים (ברירת מחדל: 5000)</translation> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>עליך לציין פתחה עם -whitebind: '%s'</translation> </message> <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>חוצץ שליחה מירבי לכל חיבור, <n>*1000 בתים (ברירת מחדל: 1000)</translation> + <source>Node relay options:</source> + <translation>אפשרויות ממסר מפרק:</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>קבל רק שרשרת בלוקים התואמת נקודות ביקורת מובנות (ברירת מחדל: 1)</translation> + <source>Print block on startup, if found in block index</source> + <translation>הצגת מקטע בהפעלה, אם נמצא במפתח המקטעים</translation> </message> <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>התחבר רק לצמתים ברשת <net> (IPv4, IPv6 או Tor)</translation> + <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> + <translation>אפשרויות RPC SSL: (נא לעיין בוויקי של ביטקוין לקבלת הנחיות על הגדרת SSL)</translation> </message> <message> <source>RPC server options:</source> <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 minimum block size in bytes (default: 0)</source> - <translation>קבע את גודל הבלוק המינימלי בבתים (ברירת מחדל: 0)</translation> + <source>Show all debugging options (usage: --help -help-debug)</source> + <translation>הצגת כל אפשרויות הניפוי (שימוש: --help -help-debug)</translation> </message> <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> - <translation>כווץ את קובץ debug.log בהפעלת הקליינט (ברירת מחדל: 1 ללא -debug)</translation> + <translation>כיווץ הקובץ debug.log בהפעלת הלקוח (בררת מחדל: 1 ללא -debug)</translation> </message> <message> <source>Signing transaction failed</source> - <translation>פעולה העברה נכשלה</translation> + <translation>החתימה על ההעברה נכשלה</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>ציין הגבלת זמן לחיבור במילישניות (ברירת מחדל: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>שגיאת מערכת:</translation> + <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>Use UPnP to map the listening port (default: 0)</source> - <translation>השתמש ב-UPnP כדי למפות את הפורט להאזנה (ברירת מחדל: 0)</translation> + <source>Unable to bind to %s on this computer (bind returned error %s)</source> + <translation>לא ניתן להתאגד עם הפתחה %s במחשב זה (פעולת האיגוד החזירה את השגיאה %s)</translation> </message> <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>השתמש ב-UPnP כדי למפות את הפורט להאזנה (ברירת מחדל: 1 בעת האזנה)</translation> + <translation>יש להשתמש ב־UPnP כדי למפות את הפתחה להאזנה (בררת מחדל: 1 בעת האזנה)</translation> </message> <message> <source>Username for JSON-RPC connections</source> <translation>שם משתמש לחיבורי JSON-RPC</translation> </message> <message> + <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source> + <translation>יש לכתוב את הארנק מחדש: נא להפעיל את ליבת ביטקוין מחדש כדי להשלים את הפעולה</translation> + </message> + <message> <source>Warning</source> <translation>אזהרה</translation> </message> @@ -2530,8 +3018,16 @@ rpcpassword=%s <translation>אזהרה: הגרסה הזאת מיושנת, יש צורך בשדרוג!</translation> </message> <message> + <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>אזהרה: הארגומנט שאינו נתמך עוד -benchmark לא הופעל, נא להשתמש ב־-debug=bench.</translation> + </message> + <message> + <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>אזהרה: הארגומנט שאינו נתמך עוד -debugnet לא הופעל, נא להשתמש ב־-debug=net.</translation> + </message> + <message> <source>on startup</source> - <translation>בפתיחה</translation> + <translation>עם ההפעלה</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -2539,35 +3035,23 @@ rpcpassword=%s </message> <message> <source>Password for JSON-RPC connections</source> - <translation>סיסמה לחיבורי JSON-RPC</translation> + <translation>ססמה לחיבורי JSON-RPC</translation> </message> <message> <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source> - <translation>בצע פקודה זו כשהבלוק הטוב ביותר משתנה (%s בפקודה יוחלף בגיבוב הבלוק)</translation> + <translation>יש לבצע פקודה זו כשהמקטע הטוב ביותר משתנה (%s בפקודה יוחלף בגיבוב המקטע)</translation> </message> <message> <source>Upgrade wallet to latest format</source> - <translation>שדרג את הארנק לפורמט העדכני</translation> - </message> - <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>קבע את גודל המאגר ל -<n> (ברירת מחדל: 100)</translation> + <translation>שדרוג הארנק למבנה העדכני</translation> </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> - <translation>השתמש ב-OpenSSL (https( עבור חיבורי JSON-RPC</translation> - </message> - <message> - <source>Server certificate file (default: server.cert)</source> - <translation>קובץ תעודת שרת (ברירת מחדל: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>מפתח פרטי של השרת (ברירת מחדל: server.pem)</translation> + <translation>שימוש ב־OpenSSL (https) עבור חיבורי JSON-RPC</translation> </message> <message> <source>This help message</source> @@ -2575,11 +3059,11 @@ rpcpassword=%s </message> <message> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> - <translation>אפשר בדיקת DNS עבור -addnode, -seednode ו- -connect</translation> + <translation>הפעלת בדיקת DNS עבור -addnode, -seednode ו־-connect</translation> </message> <message> <source>Loading addresses...</source> - <translation>טוען כתובות...</translation> + <translation>הכתובות בטעינה…</translation> </message> <message> <source>Error loading wallet.dat: Wallet corrupted</source> @@ -2591,23 +3075,23 @@ rpcpassword=%s </message> <message> <source>Invalid -proxy address: '%s'</source> - <translation>כתובת -proxy לא תקינה: '%s'</translation> + <translation>כתובת -proxy לא תקינה: '%s'</translation> </message> <message> <source>Unknown network specified in -onlynet: '%s'</source> - <translation>רשת לא ידועה צוינה ב- -onlynet: '%s'</translation> + <translation>רשת לא ידועה צוינה דרך -onlynet: '%s'</translation> </message> <message> <source>Cannot resolve -bind address: '%s'</source> - <translation>לא מסוגל לפתור כתובת -bind: '%s'</translation> + <translation>לא ניתן לפתור את הכתובת -bind: '%s'</translation> </message> <message> <source>Cannot resolve -externalip address: '%s'</source> - <translation>לא מסוגל לפתור כתובת -externalip: '%s'</translation> + <translation>לא ניתן לפתור את הכתובת -externalip: '%s'</translation> </message> <message> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> - <translation>כמות לא תקינה עבור -paytxfee=<amount>: '%s'</translation> + <translation>כמות לא תקינה עבור -paytxfee=<amount>: '%s'</translation> </message> <message> <source>Invalid amount</source> @@ -2619,27 +3103,27 @@ rpcpassword=%s </message> <message> <source>Loading block index...</source> - <translation>טוען את אינדקס הבלוקים...</translation> + <translation>מפתח המקטעים נטען…</translation> </message> <message> <source>Add a node to connect to and attempt to keep the connection open</source> - <translation>הוסף צומת להתחברות ונסה לשמור את החיבור פתוח</translation> + <translation>הוספת מפרק להתחברות ולנסות לשמור על החיבור פתוח</translation> </message> <message> <source>Loading wallet...</source> - <translation>טוען ארנק...</translation> + <translation>הארנק בטעינה…</translation> </message> <message> <source>Cannot downgrade wallet</source> - <translation>לא יכול להוריד דרגת הארנק</translation> + <translation>לא ניתן להחזיר את גרסת הארנק</translation> </message> <message> <source>Cannot write default address</source> - <translation>לא יכול לכתוב את כתובת ברירת המחדל</translation> + <translation>לא ניתן לכתוב את כתובת בררת המחדל</translation> </message> <message> <source>Rescanning...</source> - <translation>סורק מחדש...</translation> + <translation>סריקה מחדש…</translation> </message> <message> <source>Done loading</source> @@ -2647,7 +3131,7 @@ rpcpassword=%s </message> <message> <source>To use the %s option</source> - <translation>להשתמש באפשרות %s</translation> + <translation>שימוש באפשרות %s</translation> </message> <message> <source>Error</source> diff --git a/src/qt/locale/bitcoin_hi_IN.ts b/src/qt/locale/bitcoin_hi_IN.ts index 28778a0258..09a8392c27 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> @@ -191,10 +191,6 @@ <source>Tabs toolbar</source> <translation>टैबस टूलबार</translation> </message> - <message> - <source>[testnet]</source> - <translation>[टेस्टनेट]</translation> - </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n सक्रिया संपर्क बीटकोइन नेटवर्क से</numerusform><numerusform>%n सक्रिया संपर्क बीटकोइन नेटवर्क से</numerusform></translation> @@ -273,10 +269,6 @@ Address: %4 <translation>राशि</translation> </message> <message> - <source>Address</source> - <translation>पता</translation> - </message> - <message> <source>Date</source> <translation>taareek</translation> </message> @@ -389,14 +381,6 @@ Address: %4 <source>Form</source> <translation>फार्म</translation> </message> - <message> - <source>Wallet</source> - <translation>वॉलेट</translation> - </message> - <message> - <source><b>Recent transactions</b></source> - <translation><b>हाल का लेन-देन</b></translation> - </message> </context> <context> <name>PaymentServer</name> @@ -861,14 +845,6 @@ Address: %4 <translation>विकल्प:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>configuraion की फाइल का विवरण दें (default: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>pid फाइल का विवरण दें (default: bitcoin.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>डेटा डायरेक्टरी बताएं </translation> </message> diff --git a/src/qt/locale/bitcoin_hr.ts b/src/qt/locale/bitcoin_hr.ts index bf365bb57e..22831a0fd5 100644 --- a/src/qt/locale/bitcoin_hr.ts +++ b/src/qt/locale/bitcoin_hr.ts @@ -1,4 +1,4 @@ -<TS language="hr" version="2.1"> +<TS language="hr" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -10,14 +10,30 @@ <translation>Dodajte novu adresu</translation> </message> <message> + <source>&New</source> + <translation>&Nova</translation> + </message> + <message> <source>Copy the currently selected address to the system clipboard</source> <translation>Kopiraj trenutno odabranu adresu u međuspremnik</translation> </message> <message> + <source>&Copy</source> + <translation>&Kopiraj</translation> + </message> + <message> + <source>C&lose</source> + <translation>&Zatvori</translation> + </message> + <message> <source>&Copy Address</source> <translation>&Kopirati adresu</translation> </message> <message> + <source>Delete the currently selected address from the list</source> + <translation>Brisanje trenutno odabrane adrese s popisa.</translation> + </message> + <message> <source>Export the data in the current tab to a file</source> <translation>Izvoz podataka iz trenutnog taba u datoteku</translation> </message> @@ -30,6 +46,34 @@ <translation>&Brisanje</translation> </message> <message> + <source>Choose the address to send coins to</source> + <translation>Odaberi adresu na koju šalješ novac</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>Odaberi adresu na koju primaš novac</translation> + </message> + <message> + <source>C&hoose</source> + <translation>&Odaberi</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Adresa za slanje</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Adresa za primanje</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>Ovo su vaše Bitcoin adrese za slanje uplate. 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> + </message> + <message> <source>Copy &Label</source> <translation>Kopirati &oznaku</translation> </message> @@ -38,10 +82,22 @@ <translation>&Izmjeniti</translation> </message> <message> + <source>Export Address List</source> + <translation>Izvezi listu adresa</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Datoteka vrijednosti odvojenih zarezom (*. csv)</translation> </message> - </context> + <message> + <source>Exporting Failed</source> + <translation>Izvoz neuspješan</translation> + </message> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Došlo je do pogreške kod spremanja liste adresa na %1. Molimo pokušajte ponovno.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -60,6 +116,10 @@ <context> <name>AskPassphraseDialog</name> <message> + <source>Passphrase Dialog</source> + <translation>Dijalog lozinke</translation> + </message> + <message> <source>Enter passphrase</source> <translation>Unesite lozinku</translation> </message> @@ -112,6 +172,10 @@ <translation>Jeste li sigurni da želite šifrirati svoj novčanik?</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>VAŽNO: Sve prethodne pričuve vašeg novčanika trebale bi biti zamijenjene novo stvorenom, šifriranom datotekom novčanika. Zbog sigurnosnih razloga, prethodne pričuve nešifriranog novčanika će postati beskorisne čim počnete koristiti novi, šifrirani novčanik.</translation> + </message> + <message> <source>Warning: The Caps Lock key is on!</source> <translation>Upozorenje: Tipka Caps Lock je uključena!</translation> </message> @@ -120,6 +184,10 @@ <translation>Novčanik šifriran</translation> </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>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> </message> @@ -156,7 +224,7 @@ <name>BitcoinGUI</name> <message> <source>Sign &message...</source> - <translation>&Potpišite poruku...</translation> + <translation>P&otpišite poruku...</translation> </message> <message> <source>Synchronizing with network...</source> @@ -167,6 +235,10 @@ <translation>&Pregled</translation> </message> <message> + <source>Node</source> + <translation>Čvor</translation> + </message> + <message> <source>Show general overview of wallet</source> <translation>Prikaži opći pregled novčanika</translation> </message> @@ -196,19 +268,35 @@ </message> <message> <source>&Options...</source> - <translation>&Postavke</translation> + <translation>Pos&tavke</translation> </message> <message> <source>&Encrypt Wallet...</source> - <translation>&Šifriraj novčanik...</translation> + <translation>Ši&friraj novčanik...</translation> </message> <message> <source>&Backup Wallet...</source> - <translation>&Backup novčanika...</translation> + <translation>Si&gurnosno kopiraj novčanik...</translation> </message> <message> <source>&Change Passphrase...</source> - <translation>&Promijena lozinke...</translation> + <translation>&Promjena lozinke...</translation> + </message> + <message> + <source>&Sending addresses...</source> + <translation>Adrese za s&lanje</translation> + </message> + <message> + <source>&Receiving addresses...</source> + <translation>Adrese za p&rimanje</translation> + </message> + <message> + <source>Open &URI...</source> + <translation>Otvori &URI...</translation> + </message> + <message> + <source>Bitcoin Core client</source> + <translation>Bitcoin Core klijent</translation> </message> <message> <source>Importing blocks from disk...</source> @@ -235,6 +323,14 @@ <translation>Promijenite lozinku za šifriranje novčanika</translation> </message> <message> + <source>&Debug window</source> + <translation>&Ispravljanje programerskih pogrešaka</translation> + </message> + <message> + <source>Open debugging and diagnostic console</source> + <translation>Otvori konzolu za dijagnostiku i otklanjanje programskih pogrešaka.</translation> + </message> + <message> <source>&Verify message...</source> <translation>&Potvrdite poruku...</translation> </message> @@ -251,12 +347,40 @@ <translation>&Pošalji</translation> </message> <message> + <source>&Receive</source> + <translation>Pri&miti</translation> + </message> + <message> + <source>Show information about Bitcoin Core</source> + <translation>Prikaži informacije o Bitcoin Coreu</translation> + </message> + <message> + <source>&Show / Hide</source> + <translation>Po&kaži / Sakrij</translation> + </message> + <message> + <source>Show or hide the main Window</source> + <translation>Prikaži ili sakrij glavni prozor</translation> + </message> + <message> + <source>Encrypt the private keys that belong to your wallet</source> + <translation>Šifriraj privatne ključeve koji pripadaju tvom 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> + </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> + </message> + <message> <source>&File</source> <translation>&Datoteka</translation> </message> <message> <source>&Settings</source> - <translation>&Konfiguracija</translation> + <translation>&Postavke</translation> </message> <message> <source>&Help</source> @@ -267,22 +391,30 @@ <translation>Traka kartica</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Jezgra</translation> </message> + <message> + <source>Request payments (generates QR codes and bitcoin: URIs)</source> + <translation>Zatraži uplate (Stvara QR kodove i bitcoin: URIje)</translation> + </message> + <message> + <source>&About Bitcoin Core</source> + <translation>&O Bitcoin Jezgri</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> + </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> + </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> </message> <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Obrađeno %1 blokova povijesti transakcije.</translation> - </message> - <message> <source>Error</source> <translation>Greška</translation> </message> @@ -345,10 +477,6 @@ Adresa:%4 <translation>Iznos</translation> </message> <message> - <source>Address</source> - <translation>Adresa</translation> - </message> - <message> <source>Date</source> <translation>Datum</translation> </message> @@ -468,11 +596,7 @@ Adresa:%4 <source>Error</source> <translation>Pogreška</translation> </message> - <message> - <source>(of %1GB needed)</source> - <translation>(od potrebnog %1GB)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> </context> @@ -487,10 +611,6 @@ Adresa:%4 <translation>&Glavno</translation> </message> <message> - <source>Pay transaction &fee</source> - <translation>Plati &naknadu za transakciju</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> </message> @@ -578,17 +698,9 @@ Adresa:%4 <translation>Prikazani podatci mogu biti zastarjeli. Vaš novčanik se automatski sinkronizira s Bitcoin mrežom kada je veza uspostavljena, ali taj proces još nije završen.</translation> </message> <message> - <source>Wallet</source> - <translation>Novčanik</translation> - </message> - <message> <source>Total:</source> <translation>Ukupno:</translation> </message> - <message> - <source><b>Recent transactions</b></source> - <translation><b>Nedavne transakcije</b></translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1200,6 +1312,10 @@ Adresa:%4 <translation>Prikaži detalje transakcije</translation> </message> <message> + <source>Exporting Failed</source> + <translation>Izvoz neuspješan</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Datoteka podataka odvojenih zarezima (*.csv)</translation> </message> @@ -1279,42 +1395,14 @@ Adresa:%4 <translation>Postavke:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Odredi konfiguracijsku datoteku (ugrađeni izbor: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Odredi proces ID datoteku (ugrađeni izbor: bitcoin.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Odredi direktorij za datoteke</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Slušaj na <port>u (default: 8333 ili testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Održavaj najviše <n> veza sa članovima (default: 125)</translation> - </message> - <message> <source>Specify your own public address</source> <translation>Odaberi vlastitu javnu adresu</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Prag za odspajanje članova koji se čudno ponašaju (default: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Broj sekundi koliko se članovima koji se čudno ponašaju neće dopustiti da se opet spoje (default: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Prihvaćaj JSON-RPC povezivanje na portu broj <port> (ugrađeni izbor: 8332 or testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Prihvati komande iz tekst moda i JSON-RPC</translation> </message> @@ -1343,10 +1431,6 @@ Adresa:%4 <translation>Pogreška: Nema prostora na disku!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Pogreška: sistemska pogreška:</translation> - </message> - <message> <source>Imports blocks from external blk000??.dat file</source> <translation>Importiraj blokove sa vanjskog blk000??.dat fajla</translation> </message> @@ -1355,30 +1439,10 @@ Adresa:%4 <translation>Informacija</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Prihvati samo lance blokova koji se podudaraju sa ugrađenim checkpoint-ovima (default: 1)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Šalji trace/debug informacije na konzolu umjesto u debug.log datoteku</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Podesite minimalnu veličinu bloka u bajtovima (default: 0)</translation> - </message> - <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Odredi vremenski prozor za spajanje na mrežu u milisekundama (ugrađeni izbor: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Pogreška sistema:</translation> - </message> - <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Pokušaj koristiti UPnP da otvoriš port za uslugu (default: 0)</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> @@ -1403,10 +1467,6 @@ Adresa:%4 <translation>Nadogradite novčanik u posljednji format.</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Podesi memorijski prostor za ključeve na <n> (ugrađeni izbor: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Ponovno pretraži lanac blokova za transakcije koje nedostaju</translation> </message> @@ -1415,14 +1475,6 @@ Adresa:%4 <translation>Koristi OpenSSL (https) za JSON-RPC povezivanje</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Uslužnikov SSL certifikat (ugrađeni izbor: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Uslužnikov privatni ključ (ugrađeni izbor: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Ova poruka za pomoć</translation> </message> diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index b5eb262442..8109542405 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> @@ -391,10 +391,6 @@ <translation>Fül eszköztár</translation> </message> <message> - <source>[testnet]</source> - <translation>[teszthálózat]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -434,10 +430,6 @@ <source>No block source available...</source> <translation>Blokk forrása ismeretlen...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>A tranzakció-történet %1 blokkja feldolgozva.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n óra</numerusform><numerusform>%n óra</numerusform></translation> @@ -529,10 +521,6 @@ Cím: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Ellenőrző cím kiválasztása</translation> - </message> - <message> <source>Quantity:</source> <translation>Mennyiség:</translation> </message> @@ -581,10 +569,6 @@ Cím: %4 <translation>Összeg</translation> </message> <message> - <source>Address</source> - <translation>Cím</translation> - </message> - <message> <source>Date</source> <translation>Dátum</translation> </message> @@ -893,15 +877,7 @@ Cím: %4 <source>Error</source> <translation>Hiba</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB hely érhető el</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>( ebből %1GB szükséges)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -932,14 +908,6 @@ Cím: %4 <translation>&Fő</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Opcionális, kB-onkénti tranzakciós díj a tranzakcióid minél gyorsabb feldolgozásának elősegítésére. A legtöbb tranzakció 1 kB-os.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Tranzakciós &díj fizetése</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> @@ -952,10 +920,6 @@ Cím: %4 <translation>MB</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>SOCKS proxyn keresztüli csatlakozás a Bitcoin hálózatához.</translation> - </message> - <message> <source>Reset all client options to default.</source> <translation>Minden kliensbeállítás alapértelmezettre állítása.</translation> </message> @@ -1063,10 +1027,6 @@ Cím: %4 <translation>A kijelzett információ lehet, hogy elavult. A pénztárcája automatikusan szinkronizálja magát a Bitcoin hálózattal miután a kapcsolat létrejön, de ez e folyamat még nem fejeződött be.</translation> </message> <message> - <source>Wallet</source> - <translation>Tárca</translation> - </message> - <message> <source>Available:</source> <translation>Elérhető:</translation> </message> @@ -1099,10 +1059,6 @@ Cím: %4 <translation>Aktuális egyenleged</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Legutóbbi tranzakciók</b></translation> - </message> - <message> <source>out of sync</source> <translation>Nincs szinkronban.</translation> </message> @@ -1289,14 +1245,6 @@ Cím: %4 <source>never</source> <translation>soha</translation> </message> - <message> - <source>Yes</source> - <translation>Igen</translation> - </message> - <message> - <source>No</source> - <translation>Nem</translation> - </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -2078,29 +2026,11 @@ Cím: %4 </translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Konfigurációs fájl (alapértelmezett: bitcoin.conf) -</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>pid-fájl (alapértelmezett: bitcoind.pid) -</translation> - </message> - <message> <source>Specify data directory</source> <translation>Adatkönyvtár </translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Csatlakozásokhoz figyelendő <port> (alapértelmezett: 8333 or testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Maximálisan <n> számú kapcsolat fenntartása a peerekkel (alapértelmezés: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Kapcsolódás egy csomóponthoz a peerek címeinek megszerzése miatt, majd szétkapcsolás</translation> </message> @@ -2109,18 +2039,6 @@ Cím: %4 <translation>Adja meg az Ön saját nyilvános címét</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Helytelenül viselkedő peerek leválasztási határértéke (alapértelmezés: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Helytelenül viselkedő peerek kizárási ideje másodpercben (alapértelmezés: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>JSON-RPC csatlakozásokhoz figyelendő <port> (alapértelmezett: 8332 or testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Parancssoros és JSON-RPC parancsok elfogadása </translation> @@ -2188,62 +2106,10 @@ Cím: %4 <translation>Hiba: kevés a hely a lemezen!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Hiba: rendszerhiba:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Egyik hálózati porton sem sikerül hallgatni. Használja a -listen=0 kapcsolót, ha ezt szeretné.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>A blokkinformáció olvasása nem sikerült</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>A blokk olvasása nem sikerült</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>A blokkindex szinkronizálása nem sikerült</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>A blokkindex írása nem sikerült</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>A blokkinformáció írása nem sikerült</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>A blokk írása nem sikerült</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>A fájlinformáció írása nem sikerült</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Az érme-adatbázis írása nem sikerült</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>A tranzakcióindex írása nem sikerült</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>A stornóadatok írása nem sikerült</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Érmék generálása (alapértelmezett: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Hány blokkot ellenőrizzen induláskor (alapértelmezett: 288, 0 = mindet)</translation> - </message> - <message> <source>Importing...</source> <translation>Importálás</translation> </message> @@ -2284,18 +2150,6 @@ Cím: %4 <translation>Érvénytelen -mintxfee=<amount>: '%s' összeg</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Teljes tranzakcióindex megőrzése (alapértelmezett: 0)</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Csak blokklánccal egyező beépített ellenőrző pontok elfogadása (alapértelmezés: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Csak a <net> hálózat csomópontjaihoz kapcsolódjon (IPv4, IPv6 vagy Tor)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>trace/debug információ küldése a konzolra a debog.log fájl helyett</translation> </message> @@ -2304,14 +2158,6 @@ Cím: %4 <translation>Tranzakció aláírása sikertelen</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Csatlakozás időkerete milliszekundumban (alapértelmezett: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Rendszerhiba:</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Ez egy kísérleti szoftver.</translation> </message> @@ -2328,10 +2174,6 @@ Cím: %4 <translation>Túl nagy tranzakció</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>UPnP-használat engedélyezése a figyelő port feltérképezésénél (default: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>UPnP-használat engedélyezése a figyelő port feltérképezésénél (default: 1 when listening)</translation> </message> @@ -2358,11 +2200,6 @@ Cím: %4 <translation>A Tárca frissítése a legfrissebb formátumra</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Kulcskarika mérete <n> (alapértelmezett: 100) -</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Blokklánc újraszkennelése hiányzó tárca-tranzakciók után </translation> @@ -2373,16 +2210,6 @@ Cím: %4 </translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Szervertanúsítvány-fájl (alapértelmezett: server.cert) -</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Szerver titkos kulcsa (alapértelmezett: server.pem) -</translation> - </message> - <message> <source>This help message</source> <translation>Ez a súgó-üzenet </translation> diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts index 80d4141beb..ea2750ed08 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> @@ -279,6 +279,10 @@ <translation>Buka &URI</translation> </message> <message> + <source>Bitcoin Core client</source> + <translation>Client Bitcoin Inti</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>Blok-blok sedang di-impor dari disk</translation> </message> @@ -331,6 +335,10 @@ <translation>&Menerima</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>Tampilkan informasi tentang Bitcoin Inti</translation> + </message> + <message> <source>&Show / Hide</source> <translation>&Sunjukkan / Menyembungi</translation> </message> @@ -367,10 +375,6 @@ <translation>Baris tab</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -410,10 +414,6 @@ <source>No block source available...</source> <translation>Sumber blok tidak tersedia...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>%1 blok-blok riwayat transaksi telah diproses</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n jam</numerusform></translation> @@ -505,10 +505,6 @@ Alamat: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Pilihan alamat pengaturan koin</translation> - </message> - <message> <source>Quantity:</source> <translation>Kuantitas:</translation> </message> @@ -553,10 +549,6 @@ Alamat: %4 <translation>Nilai</translation> </message> <message> - <source>Address</source> - <translation>Alamat</translation> - </message> - <message> <source>Date</source> <translation>Tanggal</translation> </message> @@ -852,15 +844,11 @@ Alamat: %4 <source>Error</source> <translation>Gagal</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB di hard disk yang masih tersedia</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(dari %1GB yang diperlu)</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB dari ruang yang tersedia</numerusform></translation> </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -895,14 +883,6 @@ Alamat: %4 <translation>&Utama</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Biaya transaksi untuk setiap kB yang membantu transaksi Andi diproses cepat (biayanya opsional). Ukuran transaksi biasanya 1kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Bayar &biaya transaksi</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> @@ -915,14 +895,6 @@ Alamat: %4 <translation>MB</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Menghubungkan jaringan Bitcoin lewat proxy SOCKS.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Hubungkan melalui proxy SOCKS (proxy biasa):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>Alamat IP proxy (cth. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1078,10 +1050,6 @@ Alamat: %4 <translation>Informasi terlampir mungkin sudah kedaluwarsa. Dompet Anda secara otomatis mensinkronisasi dengan jaringan Bitcoin ketika sebuah hubungan terbentuk, namun proses ini belum selesai.</translation> </message> <message> - <source>Wallet</source> - <translation>Dompet</translation> - </message> - <message> <source>Available:</source> <translation>Tersedia:</translation> </message> @@ -1114,10 +1082,6 @@ Alamat: %4 <translation>Jumlah saldo Anda sekarang</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Transaksi sebelumnya</b></translation> - </message> - <message> <source>out of sync</source> <translation>tidak tersinkron</translation> </message> @@ -2315,26 +2279,10 @@ Alamat: %4 <translation>Pilihan:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Tentukan berkas konfigurasi (standar: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Tentukan berkas pid (standar: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Tentukan direktori data</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Menerima hubungan pada <port> (standar: 8333 atau testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Mengatur hubungan paling banyak <n> ke peer (standar: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Hubungkan ke node untuk menerima alamat peer, dan putuskan</translation> </message> @@ -2343,14 +2291,6 @@ Alamat: %4 <translation>Tentukan alamat publik Anda sendiri</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Batas untuk memutuskan peer buruk (standar: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Jumlah kedua untuk menjaga peer buruk dari hubung-ulang (standar: 86400)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Menerima perintah baris perintah dan JSON-RPC</translation> </message> @@ -2367,10 +2307,6 @@ Alamat: %4 <translation>Terima hubungan dari luar (standar: 1 kalau -proxy atau -connect tidak dipilih)</translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Sandi yang diterima (biasanya: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>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.</source> <translation>Gagal: Transaksi ditolak. Ini mungkin terjadi jika beberapa dari koin dalam dompet Anda telah digunakan, seperti ketika Anda menggunakan salinan wallet.dat dan beberapa koin telah dibelanjakan dalam salinan tersebut tetapi disini tidak tertandai sebagai terpakai.</translation> </message> @@ -2383,10 +2319,6 @@ Alamat: %4 <translation>Tidak bisa mengikat dengan %s di computer ini. Kemungkinan Bitcoin Core sudah mulai.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Gunakanlah proxy SOCKS5 yang tersendiri supaya menghubungkan peer dengan layanan tersembunyi Tor (biasanya: -proxy)</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>Peringatan: -paytxfee sangat besar! Ini adalah biaya pengiriman yang akan dibayar oleh Anda jika transaksi terkirim.</translation> </message> @@ -2407,10 +2339,6 @@ Alamat: %4 <translation>(pengaturan awal: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(pengaturan awal: wallet.dat)</translation> - </message> - <message> <source>Attempt to recover private keys from a corrupt wallet.dat</source> <translation>Coba memulihkan kunci-kunci pribadi dari wallet.dat yang rusak</translation> </message> @@ -2467,58 +2395,6 @@ Alamat: %4 <translation>Gagal: Dompet terkunci, transaksi tidak bisa dibuat!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Error: system error:</translation> - </message> - <message> - <source>Failed to read block info</source> - <translation>Gagal membaca informasi dari blok</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Gagal membaca blok</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Gagal menyamakan daftar isi blok</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Gagal menulis daftar isi blok</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Gagal menulis info blok</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Gagal menulis blok</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Gagal menulis info arsip</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Gagal menuliskan ke dalam database koin</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Gagal menulis daftar isi transaksi</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Gagal menulis ulang data</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Buatlah koin (biasanya: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Periksakan berapa blok waktu mulai (biasanya: 288, 0 = setiapnya)</translation> - </message> - <message> <source>Importing...</source> <translation>mengimpor...</translation> </message> @@ -2539,18 +2415,10 @@ Alamat: %4 <translation>Atur ukuran maksimal untuk blok dalam byte (biasanya: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Mengatur jumlah urutan untuk layanan panggilan RPC (pengaturan awal: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Tentukan arsip dompet (dalam direktori data)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Perubahan saldo untuk transaksi yang belum dikonfirmasi setelah transaksi terkirim (default: 1)</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>Blok-blok sedang diverifikasi...</translation> </message> @@ -2591,14 +2459,6 @@ Alamat: %4 <translation>Nilai yang salah untuk -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Jaga daftar transaksi yang lengkap (biasanya: 0)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Dilarang menghubungkan node-node selain <net> (IPv4, IPv6 atau Tor)</translation> - </message> - <message> <source>RPC server options:</source> <translation>Opsi server RPC:</translation> </message> @@ -2607,10 +2467,6 @@ Alamat: %4 <translation>Kirim info jejak/debug ke konsol bukan berkas debug.log</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Atur ukuran minimal untuk blok dalam byte (standar: 0)</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> @@ -2619,14 +2475,6 @@ Alamat: %4 <translation>Tandatangani transaksi tergagal</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Menetapkan waktu berakhir koneksi di milidetik (biasanya: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Kesalahan sistem:</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Nilai transaksi terlalu kecil</translation> </message> @@ -2671,10 +2519,6 @@ Alamat: %4 <translation>Perbarui dompet ke format terbaru</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Kirim ukuran kolam kunci ke <n> (standar: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Pindai ulang rantai-blok untuk transaksi dompet yang hilang</translation> </message> @@ -2683,14 +2527,6 @@ Alamat: %4 <translation>Gunakan OpenSSL (https) untuk hubungan JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Berkas sertifikat server (standar: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Kunci pribadi server (standar: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Pesan bantuan ini</translation> </message> diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index a803241d10..06cf0e0162 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> @@ -35,7 +35,7 @@ </message> <message> <source>Export the data in the current tab to a file</source> - <translation>Esporta su file i dati della tabella corrente </translation> + <translation>Esporta i dati nella tabella corrente in un file</translation> </message> <message> <source>&Export</source> @@ -93,7 +93,11 @@ <source>Exporting Failed</source> <translation>Esportazione Fallita.</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Si è verificato un errore tentando di salvare la lista degli indirizzi. %1. Riprova</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -113,19 +117,19 @@ <name>AskPassphraseDialog</name> <message> <source>Passphrase Dialog</source> - <translation>Finestra passphrase</translation> + <translation>Finestra parola d'ordine</translation> </message> <message> <source>Enter passphrase</source> - <translation>Inserisci la passphrase</translation> + <translation>Inserisci la parola d'ordine</translation> </message> <message> <source>New passphrase</source> - <translation>Nuova passphrase</translation> + <translation>Nuova parola d'ordine</translation> </message> <message> <source>Repeat new passphrase</source> - <translation>Ripeti la nuova passphrase</translation> + <translation>Ripeti la nuova parola d'ordine</translation> </message> <message> <source>Encrypt wallet</source> @@ -180,6 +184,10 @@ <translation>Portamonete cifrato</translation> </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>Inserisci una nuona password per il postafoglio.<br/>Perfavore usa una password di<b>dieci o più caratteri</b>, o <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> </message> @@ -287,6 +295,10 @@ <translation>Apri &URI...</translation> </message> <message> + <source>Bitcoin Core client</source> + <translation>Bitcoin Core client</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>Importazione blocchi dal disco...</translation> </message> @@ -339,6 +351,10 @@ <translation>&Ricevi</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>Mostra le informazioni riguardo a Bitcoin core</translation> + </message> + <message> <source>&Show / Hide</source> <translation>&Mostra / Nascondi</translation> </message> @@ -375,10 +391,6 @@ <translation>Barra degli strumenti "Tabs"</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -418,10 +430,6 @@ <source>No block source available...</source> <translation>Nessuna fonte di blocchi disponibile</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Processati %1 blocchi della cronologia transazioni.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n ora</numerusform><numerusform>%n ore</numerusform></translation> @@ -470,6 +478,10 @@ <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> @@ -514,8 +526,9 @@ Indirizzo: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Selezione Indirizzo Coin Control</translation> + <source>Coin Selection</source> + <translation>Seleziona Moneta +</translation> </message> <message> <source>Quantity:</source> @@ -538,6 +551,10 @@ Indirizzo: %4 <translation>Commissione:</translation> </message> <message> + <source>Dust:</source> + <translation>Importo</translation> + </message> + <message> <source>After Fee:</source> <translation>Dopo Commissione:</translation> </message> @@ -562,8 +579,12 @@ Indirizzo: %4 <translation>Importo</translation> </message> <message> - <source>Address</source> - <translation>Indirizzo</translation> + <source>Received with label</source> + <translation>Ricevuto con etichetta</translation> + </message> + <message> + <source>Received with address</source> + <translation>Ricevuto con l'indirizzo</translation> </message> <message> <source>Date</source> @@ -626,6 +647,10 @@ Indirizzo: %4 <translation>Copia priorità</translation> </message> <message> + <source>Copy dust</source> + <translation>Copia l'importo</translation> + </message> + <message> <source>Copy change</source> <translation>Copia resto</translation> </message> @@ -674,6 +699,10 @@ Indirizzo: %4 <translation>nessuno</translation> </message> <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>Può variare +/- %1 satoshi(s) per input.</translation> + </message> + <message> <source>yes</source> <translation>sì</translation> </message> @@ -882,18 +911,14 @@ Indirizzo: %4 <translation>Bitcoin Core</translation> </message> <message> - <source>Error</source> - <translation>Errore</translation> - </message> - <message> - <source>GB of free space available</source> - <translation>GB di spazio libero disponibile</translation> + <source>Error: Specified data directory "%1" cannot be created.</source> + <translation>Errore: La cartella dati "%1" specificata non può essere creata.</translation> </message> <message> - <source>(of %1GB needed)</source> - <translation>(di %1GB richiesti)</translation> + <source>Error</source> + <translation>Errore</translation> </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -928,14 +953,6 @@ Indirizzo: %4 <translation>&Principale</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Commissione di transazione per kB: è opzionale e contribuisce ad assicurare che le transazioni siano elaborate velocemente. La maggior parte della transazioni ha dimensioni pari a 1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Paga la &commissione</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> @@ -956,12 +973,12 @@ Indirizzo: %4 <translation>Numero di thread di &verifica degli script </translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Connessione alla rete Bitcoin attraverso un proxy SOCKS.</translation> + <source>Accept connections from outside</source> + <translation>Accetta connessioni da fuori</translation> </message> <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Connessione attraverso proxy SOCKS (proxy predefinito):</translation> + <source>Allow incoming connections</source> + <translation>Permetti connessioni in entrata</translation> </message> <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> @@ -1025,6 +1042,14 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Mappa le porte tramite &UPnP</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Connessione alla rete Bitcoin attraverso un proxy SOCKS5.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Connessione attraverso proxy SOCKS5 (proxy predefinito):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>&IP del proxy:</translation> </message> @@ -1128,8 +1153,8 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Le informazioni visualizzate potrebbero non essere aggiornate. Il portamonete si sincronizza automaticamente con la rete Bitcoin una volta stabilita una connessione, ma questo processo non è ancora stato completato.</translation> </message> <message> - <source>Wallet</source> - <translation>Portamonete</translation> + <source>Watch-only:</source> + <translation>Guarda solo</translation> </message> <message> <source>Available:</source> @@ -1156,6 +1181,10 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Importo generato dal mining e non ancora maturato</translation> </message> <message> + <source>Balances</source> + <translation>Saldo</translation> + </message> + <message> <source>Total:</source> <translation>Totale:</translation> </message> @@ -1164,8 +1193,28 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Saldo totale attuale</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Transazioni recenti</b></translation> + <source>Your current balance in watch-only addresses</source> + <translation>Il tuo saldo attuale negli indirizzi watch-only</translation> + </message> + <message> + <source>Spendable:</source> + <translation>Saldo Spendibile:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Transazioni recenti</translation> + </message> + <message> + <source>Unconfirmed transactions to watch-only addresses</source> + <translation>Transazioni non confermate su indirizzi di sola lettura</translation> + </message> + <message> + <source>Mined balance in watch-only addresses that has not yet matured</source> + <translation>l'equilibrio estratto solo nello sguardo degli indirizzi non è ancora maturo </translation> + </message> + <message> + <source>Current total balance in watch-only addresses</source> + <translation>Saldo corrente totale negli indirizzi watch-only</translation> </message> <message> <source>out of sync</source> @@ -1183,6 +1232,22 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Indirizzo di pagamento non valido %1</translation> </message> <message> + <source>Payment request rejected</source> + <translation>Richiesta di pagamento rifiutata</translation> + </message> + <message> + <source>Payment request network doesn't match client network.</source> + <translation>Il network della richiesta di pagamento non corrisponde al network del client.</translation> + </message> + <message> + <source>Payment request has expired.</source> + <translation>Richieda di pagamento scaduta</translation> + </message> + <message> + <source>Payment request is not initialized.</source> + <translation>La richiesta di pagamento non è stata inizializzata.</translation> + </message> + <message> <source>Requested payment amount of %1 is too small (considered dust).</source> <translation>L'importo di pagamento richiesto di %1 è troppo basso (considerato come trascurabile).</translation> </message> @@ -1199,10 +1264,18 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>URL di recupero della Richiesta di pagamento non valido: %1</translation> </message> <message> + <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> + <translation>Impossibile interpretare l'URI! Ciò può essere causato da un indirizzo Bitcoin invalido o da parametri URI non corretti.</translation> + </message> + <message> <source>Payment request file handling</source> <translation>Gestione del file di richiesta del pagamento</translation> </message> <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>Il file di richiesta del pagamento non può essere letto o elaborato! Questo può essere causato da una richiesta di pagamento non valida.</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> @@ -1215,6 +1288,10 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Errore di comunicazione con %1: %2</translation> </message> <message> + <source>Payment request cannot be parsed!</source> + <translation>La richiesta di pagamento non può essere analizzata.</translation> + </message> + <message> <source>Bad response from server %1</source> <translation>Risposta errata da parte del server %1</translation> </message> @@ -1229,7 +1306,19 @@ Più URL vengono separati da una barra verticale |.</translation> </context> <context> <name>PeerTableModel</name> - </context> + <message> + <source>User Agent</source> + <translation>User Agent</translation> + </message> + <message> + <source>Address/Hostname</source> + <translation>Indirizzo/Hostname</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Tempo di ping</translation> + </message> +</context> <context> <name>QObject</name> <message> @@ -1237,6 +1326,10 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Importo</translation> </message> <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>Inserisci un indirizzo Bitcoin (e.g. %1)</translation> + </message> + <message> <source>%1 d</source> <translation>%1 d</translation> </message> @@ -1253,10 +1346,26 @@ Più URL vengono separati da 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> + <message> <source>N/A</source> <translation>N/D</translation> </message> - </context> + <message> + <source>%1 ms</source> + <translation>%1 ms</translation> + </message> +</context> <context> <name>QRImageWidget</name> <message> @@ -1307,6 +1416,10 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Versione OpenSSL in uso</translation> </message> <message> + <source>Using BerkeleyDB version</source> + <translation>Versione BerkeleyDB in uso</translation> + </message> + <message> <source>Startup time</source> <translation>Tempo di avvio</translation> </message> @@ -1331,6 +1444,74 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Numero attuale di blocchi</translation> </message> <message> + <source>Received</source> + <translation>Ricevuto</translation> + </message> + <message> + <source>Sent</source> + <translation>Inviato</translation> + </message> + <message> + <source>&Peers</source> + <translation>&Peers</translation> + </message> + <message> + <source>Select a peer to view detailed information.</source> + <translation>Seleziona un peer per visualizzare informazioni più dettagliate.</translation> + </message> + <message> + <source>Direction</source> + <translation>Direzione</translation> + </message> + <message> + <source>Version</source> + <translation>Versione</translation> + </message> + <message> + <source>User Agent</source> + <translation>User Agent</translation> + </message> + <message> + <source>Services</source> + <translation>Servizi</translation> + </message> + <message> + <source>Starting Height</source> + <translation>Blocco di partenza</translation> + </message> + <message> + <source>Sync Height</source> + <translation>valore di sincronizzazione</translation> + </message> + <message> + <source>Ban Score</source> + <translation>divieto di segnalazione </translation> + </message> + <message> + <source>Connection Time</source> + <translation>Tempo di connessione</translation> + </message> + <message> + <source>Last Send</source> + <translation>Ultimo invio</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Ultima ricevuta</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Bytes Inviati</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Bytes Ricevuti</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Tempo di Ping</translation> + </message> + <message> <source>Last block time</source> <translation>Ora del blocco più recente</translation> </message> @@ -1407,18 +1588,30 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>%1 GB</translation> </message> <message> + <source>via %1</source> + <translation>via %1</translation> + </message> + <message> <source>never</source> <translation>mai</translation> </message> <message> - <source>Yes</source> - <translation>Si</translation> + <source>Inbound</source> + <translation>In entrata</translation> </message> <message> - <source>No</source> - <translation>No</translation> + <source>Outbound</source> + <translation>In uscita</translation> </message> - </context> + <message> + <source>Unknown</source> + <translation>Sconosciuto</translation> + </message> + <message> + <source>Fetching...</source> + <translation>attraente</translation> + </message> +</context> <context> <name>ReceiveCoinsDialog</name> <message> @@ -1647,6 +1840,50 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Personalizza indirizzo di resto</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Tasse di Transazione</translation> + </message> + <message> + <source>Choose...</source> + <translation>Scegli...</translation> + </message> + <message> + <source>Minimize</source> + <translation>Minimizza</translation> + </message> + <message> + <source>per kilobyte</source> + <translation>per kilobyte</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>Pagando solo la tariffa minima è bene finché c'è meno volume di transazioni di spazio nei blocchi. Ma essere consapevoli che questo può finire in una transazione non confermando ancora una volta non vi è più richiesta per le transazioni Bitcoin di rete in grado di elaborare.</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Raccomandati:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Personalizza:</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Tempo di conferma:</translation> + </message> + <message> + <source>normal</source> + <translation>normale</translation> + </message> + <message> + <source>fast</source> + <translation>veloce</translation> + </message> + <message> + <source>Send as zero-fee transaction if possible</source> + <translation>Invia una transazione a zero commissioni se possibile</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Invia a diversi beneficiari in una volta sola</translation> </message> @@ -1659,6 +1896,10 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Cancellare tutti i campi del modulo.</translation> </message> <message> + <source>Dust:</source> + <translation>Trascurabile</translation> + </message> + <message> <source>Clear &All</source> <translation>Cancella &tutto</translation> </message> @@ -1759,6 +2000,10 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Attenzione: Indirizzo per il resto sconosciuto</translation> </message> <message> + <source>Copy dust</source> + <translation>Copia l'importo</translation> + </message> + <message> <source>Are you sure you want to send?</source> <translation>Sei sicuro di voler inviare?</translation> </message> @@ -1794,6 +2039,10 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Questo è un normale pagamento.</translation> </message> <message> + <source>The Bitcoin address to send the payment to</source> + <translation>L'indirizzo Bitcoin a cui vuoi inviare il pagamento</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1864,6 +2113,10 @@ Più URL vengono separati da una barra verticale |.</translation> <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> </message> <message> + <source>The Bitcoin address to sign the message with</source> + <translation>L'indirizzo Bitcoin con cui vuoi contrassegnare il messaggio</translation> + </message> + <message> <source>Choose previously used address</source> <translation>Scegli un indirizzo usato precedentemente</translation> </message> @@ -1916,6 +2169,10 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Inserisci l'indirizzo del firmatario, il messaggio (assicurati 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 firma più di quanto non sia riportato nel messaggio stesso, per evitare di cadere vittima di attacchi di tipo man-in-the-middle.</translation> </message> <message> + <source>The Bitcoin address the message was signed with</source> + <translation>L'indirizzo Bitcoin con cui è stato contrassegnato il messaggio</translation> + </message> + <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>Verifica il messaggio per accertare che sia stato firmato con l'indirizzo specificato</translation> </message> @@ -2057,6 +2314,10 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>proprio indirizzo</translation> </message> <message> + <source>watch-only</source> + <translation>Guarda solo</translation> + </message> + <message> <source>label</source> <translation>etichetta</translation> </message> @@ -2077,6 +2338,14 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Debito</translation> </message> <message> + <source>Total debit</source> + <translation>Credito Totale</translation> + </message> + <message> + <source>Total credit</source> + <translation>Credito totale</translation> + </message> + <message> <source>Transaction fee</source> <translation>Commissione transazione</translation> </message> @@ -2227,6 +2496,10 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Ottenuto dal mining</translation> </message> <message> + <source>watch-only</source> + <translation>Guarda solo</translation> + </message> + <message> <source>(n/a)</source> <translation>(N / a)</translation> </message> @@ -2338,6 +2611,10 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Esporta lo storico delle transazioni</translation> </message> <message> + <source>Watch-only</source> + <translation>Sola lettura</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Esportazione Fallita.</translation> </message> @@ -2392,7 +2669,11 @@ Più URL vengono separati da una barra verticale |.</translation> </context> <context> <name>UnitDisplayStatusBarControl</name> - </context> + <message> + <source>Unit to show amounts in. Click to select another unit.</source> + <translation>Tipo di unità visualizzata. Clicca per selezionare un altra unità</translation> + </message> +</context> <context> <name>WalletFrame</name> <message> @@ -2449,26 +2730,10 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Opzioni:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Specifica il file di configurazione (predefinito: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Specifica il file pid (predefinito: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Specifica la cartella dati</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Attendi le connessioni su <porta> (predefinita: 8333 o testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Mantieni al massimo <n> connessioni ai peer (predefinite: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Connettiti ad un nodo per recuperare gli indirizzi dei peer e scollegati</translation> </message> @@ -2477,18 +2742,6 @@ Più URL vengono separati da una barra verticale |.</translation> <translation>Specifica il tuo indirizzo pubblico</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Soglia di disconnessione dei peer di cattiva qualità (predefinita: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Numero di secondi di sospensione che i peer di cattiva qualità devono attendere prima di potersi riconnettere (predefiniti: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Attendi le connessioni JSON-RPC su <porta> (predefinita: 8332 or testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Accetta comandi da riga di comando e JSON-RPC</translation> </message> @@ -2529,16 +2782,12 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Cifrature accettabili (predefinito: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Associa all'indirizzo indicato e resta permanentemente in ascolto su questo. Usa la notazione [host]:porta per l'IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Limita la quantità di transazioni gratuite ad <n>*1000 byte al minuto (predefinito: 15)</translation> + <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> + <translation>Elimina tutte le transazioni dal wallet e recupera solo le parti della blockchain con il comando -rescan all'avvio.</translation> </message> <message> <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> @@ -2557,14 +2806,6 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Esegui comando quando una transazione del portamonete cambia (%s in cmd è sostituito da TxID)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Scarica l'attività del database dalla memoria al log su disco ogni <n> megabytes (predefinito: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Determina quanto sarà approfondita la verifica da parte di -checkblocks (0-4, predefinito: 3)</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> </message> @@ -2573,10 +2814,6 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Imposta il numero di thread per la verifica degli script (da %u a %d, 0 = automatico, <0 = lascia questo numero di core liberi, predefinito: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Imposta il limite della cpu quando la generazione è abilitata (-1 = non limitato, predefinito: -1)</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>Questa versione è una compilazione pre-rilascio - usala a tuo rischio - non utilizzarla per la generazione o per applicazioni di commercio</translation> </message> @@ -2585,10 +2822,6 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Impossibile associarsi a %s su questo computer. Probabilmente Bitcoin Core è già in esecuzione.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Usa un SOCKS5 proxy separato per raggiungere servizi nascosti di Tor (predefinito: -proxy)</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 è molto alta. Questa è la commissione che si paga quando si invia una transazione.</translation> </message> @@ -2613,10 +2846,6 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>(predefinito: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(predefinito: wallet.dat)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> può essere:</translation> </message> @@ -2645,10 +2874,6 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Opzioni di Debug/Test:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Disabilita la modalità sicura, escludi effettivamente gli eventi di modalità sicura (predefinito: 0)</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 e no -externalip)</translation> </message> @@ -2677,6 +2902,10 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Errore caricamento database blocchi</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Errore: si è verificato un errore fatale, consulta il file debug.log for maggiori dettagli.</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Errore: la spazio libero sul disco è insufficiente!</translation> </message> @@ -2685,66 +2914,10 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Errore: portamonete bloccato, impossibile creare la transazione!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Errore: errore di sistema:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Nessuna porta disponibile per l'ascolto. Usa -listen=0 se vuoi procedere comunque.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Lettura informazioni blocco fallita</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Lettura blocco fallita</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Sincronizzazione dell'indice del blocco fallita</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Scrittura dell'indice del blocco fallita</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Scrittura informazioni blocco fallita</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Scrittura blocco fallita</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Scrittura informazioni file fallita</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Scrittura nel database dei bitcoin fallita</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Scrittura dell'indice di transazione fallita</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Scrittura dei dati di ripristino fallita</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Forza modalità provvisoria (predefinito: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Genera Bitcoin (predefinito: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Numero di blocchi da controllare all'avvio (predefinito: 288, 0 = tutti)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Se <category> non è specificata, mostra tutte le informazioni di debug.</translation> </message> @@ -2765,8 +2938,8 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Non ci sono abbastanza descrittori di file disponibili.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Preponi timestamp all'output di debug (predefinito: 1)</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>Connetti solo ai nodi nella rete <net> (ipv4, ipv6 o Tor)</translation> </message> <message> <source>Rebuild block chain index from current blk000??.dat files</source> @@ -2781,18 +2954,10 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Imposta la dimensione massima del blocco in byte (predefinita: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Specifica il numero massimo di richieste RPC in parallelo (predefinito: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Specifica il file portamonete (all'interno della cartella dati)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Spendi il resto non confermato quando si inviano transazioni (predefinito: 1)</translation> - </message> - <message> <source>This is intended for regression testing tools and app development.</source> <translation>Questo è previsto per l'uso con test di regressione e per lo sviluppo di applicazioni.</translation> </message> @@ -2821,70 +2986,70 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Importa blocchi da un file blk000??.dat esterno</translation> </message> <message> + <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> + <translation>Si è verificato un errore durante l'impostazione della %s porta %u RPC per l'ascolto su: %s</translation> + </message> + <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Non è possibile ottenere un lock sulla cartella %s. Probabilmente Bitcoin Core è già in esecuzione.</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>Esegue un comando quando viene ricevuto un allarme rilevante o quando vediamo un fork veramente lungo (%s in cmd è sostituito dal messaggio)</translation> + <source>Error: Listening for incoming connections failed (listen returned error %s)</source> + <translation>Errore: l'ascolto per per connessioni in arrivo fallito (errore riportato %s)</translation> </message> <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Emette informazioni di debug in output (predefinito: 0, fornire <category> è opzionale)</translation> + <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>Esegue un comando quando viene ricevuto un allarme rilevante o quando vediamo un fork veramente lungo (%s in cmd è sostituito dal messaggio)</translation> </message> <message> - <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> - <translation>Imposta la dimensione massima in byte delle transazioni ad alta-priorità/basse-commissioni (predefinita: %d)</translation> + <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> + <translation>Le commissioni (in BTC/kb) minori di questa saranno considerate nulle per la trasmissione (predefinito: %s)</translation> </message> <message> - <source>Information</source> - <translation>Informazioni</translation> + <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>Le commissioni inferiori a questo valore saranno considerate nulle per la creazione della transazione (predefinito: %s)</translation> </message> <message> - <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> - <translation>Importo non valido per -minrelaytxfee=<amount>: '%s'</translation> + <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> + <translation>Imposta la dimensione massima in byte delle transazioni ad alta-priorità/basse-commissioni (predefinita: %d)</translation> </message> <message> - <source>Invalid amount for -mintxfee=<amount>: '%s'</source> - <translation>Importo non valido per -mintxfee=<amount>: '%s'</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Impossibile risolvere -whitebind address: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Limita la dimensione della cache delle firme a <n> voci (predefinito: 50000)</translation> + <source>Connect through SOCKS5 proxy</source> + <translation>Connetti attraverso SOCKS5 proxy</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Abilita il log della priorità di transazione e della commissione per kB quando si generano blocchi (default: 0)</translation> + <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> + <translation>Errore caricamento wallet.dat: il wallet richiede una versione nuova di Bitcoin Core</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Mantieni un indice di transazione completo (predefinito: 0)</translation> + <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> + <translation>Commissione (in BTC/kB) da aggiungere alla transazione che invii (default: %s)</translation> </message> <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Buffer di ricezione massimo per connessione, <n>*1000 byte (predefinito: 5000)</translation> + <source>Information</source> + <translation>Informazioni</translation> </message> <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Buffer di invio massimo per connessione, <n>*1000 byte (predefinito: 1000)</translation> + <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> + <translation>Importo non valido per -minrelaytxfee=<amount>: '%s'</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Accetta solo una catena di blocchi che corrisponde ai checkpoint predefiniti (predefinito: 1)</translation> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>Importo non valido per -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Connetti solo a nodi nella rete <net> (IPv4, IPv6 o Tor)</translation> + <source>Node relay options:</source> + <translation>Opzioni relay nodo:</translation> </message> <message> <source>Print block on startup, if found in block index</source> <translation>Stampa il blocco all'avvio, se presente nell'indice dei blocchi</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Stampa l'albero dei blocchi all'avvio (default: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Opzioni RPC SSL: (consulta la Bitcoin Wiki per le istruzioni relative alla configurazione SSL)</translation> </message> @@ -2901,20 +3066,12 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Altera casualmente 1 ogni <n> messaggi di rete</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Mantieni in esecuzione un thread per scaricare periodicamente il portafoglio (predefinito: 1)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Invia le informazioni di trace/debug alla console invece che al file debug.log</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Imposta dimensione minima del blocco in bytes (predefinita: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Imposta il flag DB_PRIVATE nell'ambiente di database del portamonete (predefinito: 1)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Invia transazioni a zero commissioni se possibile (default: %u)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> @@ -2929,14 +3086,6 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Transazione di firma fallita</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Specifica il timeout di connessione in millisecondi (predefinito: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Errore di sistema:</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Questo è un software sperimentale.</translation> </message> @@ -2953,10 +3102,6 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Transazione troppo grande</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Usa UPnP per mappare la porta in ascolto (predefinito: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Usa UPnP per mappare la porta in ascolto (predefinito: 1 when listening)</translation> </message> @@ -2966,6 +3111,10 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com </translation> </message> <message> + <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source> + <translation>Il wallet ha bisogno di essere reiscritto : riavvia Bitcoin Core per completare l'operazione</translation> + </message> + <message> <source>Warning</source> <translation>Attenzione</translation> </message> @@ -2999,10 +3148,6 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Aggiorna il wallet all'ultimo formato</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Impostare la quantità di chiavi nel key pool a <n> (predefinita: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Ripeti analisi della catena dei blocchi per cercare le transazioni mancanti dal portamonete </translation> @@ -3013,14 +3158,6 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com </translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>File certificato del server (predefinito: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Chiave privata del server (predefinito: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Questo messaggio di aiuto </translation> @@ -3042,10 +3179,62 @@ ad esempio: alertnotify=echo %%s | mail -s "Allarme Bitcoin" admin@foo.com <translation>Errore caricamento wallet.dat</translation> </message> <message> + <source>Force safe mode (default: %u)</source> + <translation>Forza modalità provvisoria (dafault: %u)</translation> + </message> + <message> + <source>Generate coins (default: %u)</source> + <translation>Genera coins (default: %u)</translation> + </message> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Quanti blocchi da controllare all'avvio (dafault: %u, 0 = tutti)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <translation>Indirizzo -proxy non valido: '%s'</translation> </message> <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Mantieni al massimo <n> connessioni ai peers (default: %u)</translation> + </message> + <message> + <source>Prepend debug output with timestamp (default: %u)</source> + <translation>Pretendi output di debug con timestamp (default: %u)</translation> + </message> + <message> + <source>Print block tree on startup (default: %u)</source> + <translation>Stampa l'albero dei blocchi all'avvio (default: %u)</translation> + </message> + <message> + <source>Server certificate file (default: %s)</source> + <translation>File certificato del server (default: %s)</translation> + </message> + <message> + <source>Server private key (default: %s)</source> + <translation>Chiave privata del server (default: %s)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>Specifica il file di configurazione (default: %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Specifica il timeout di connessione in millisecondi (minimo:1, default: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Specifica il file pid (default: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <translation>Spendi il resto non confermato quando si inviano transazioni (default: %u)</translation> + </message> + <message> + <source>Stop running after importing blocks from disk (default: %u)</source> + <translation>Interrompi dopo aver importato i blocchi dal disco (default: %u)</translation> + </message> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Rete sconosciuta specificata in -onlynet: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index f056dd401e..0c9805de8f 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> @@ -70,6 +70,10 @@ <translation>これらは支払いを送信するためのあなたの Bitcoin アドレスです。コインを送信する前に、常に額と受信アドレスを確認してください。</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>ラベルをコピー (&L)</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> @@ -176,6 +184,10 @@ <translation>ウォレットは暗号化されました</translation> </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>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> </message> @@ -283,6 +295,10 @@ <translation>URI を開く (&U)...</translation> </message> <message> + <source>Bitcoin Core client</source> + <translation>Bitcoinコア クライアント</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>ディスクからブロックをインポートしています...</translation> </message> @@ -335,6 +351,10 @@ <translation>受信 (&R)</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>Bitcoinコアに関する情報を表示</translation> + </message> + <message> <source>&Show / Hide</source> <translation>見る/隠す (&S)</translation> </message> @@ -371,18 +391,22 @@ <translation>タブツールバー</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin のコア</translation> </message> <message> + <source>Request payments (generates QR codes and bitcoin: URIs)</source> + <translation>支払いを要求する (QRコードとbitcoin:ではじまるURIを生成する)</translation> + </message> + <message> <source>&About Bitcoin Core</source> <translation>ビットコインコアについて (&A)</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> @@ -398,10 +422,6 @@ <source>No block source available...</source> <translation>利用可能なブロックがありません...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>取引履歴の %1 ブロックを処理しました。</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n 時間</numerusform></translation> @@ -492,6 +512,10 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>コイン選択</translation> + </message> + <message> <source>Quantity:</source> <translation>数量:</translation> </message> @@ -532,10 +556,6 @@ Address: %4 <translation>総額</translation> </message> <message> - <source>Address</source> - <translation>アドレス</translation> - </message> - <message> <source>Date</source> <translation>日付</translation> </message> @@ -568,6 +588,14 @@ 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> @@ -689,6 +717,10 @@ Address: %4 <translation>バージョン</translation> </message> <message> + <source>About Bitcoin Core</source> + <translation>Bitcoinコアについて</translation> + </message> + <message> <source>Command-line options</source> <translation>コマンドライン オプション</translation> </message> @@ -728,6 +760,10 @@ Address: %4 <translation>ようこそ</translation> </message> <message> + <source>Welcome to Bitcoin Core.</source> + <translation>ようこそ!</translation> + </message> + <message> <source>Use the default data directory</source> <translation>初期値のデータ ディレクトリを使用</translation> </message> @@ -743,13 +779,13 @@ Address: %4 <source>Error</source> <translation>エラー</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GBの利用可能な空き領域</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GBの空き容量が利用可能</numerusform></translation> </message> - <message> - <source>(of %1GB needed)</source> - <translation>(%1GB が必要)</translation> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(%n GB必要)</numerusform></translation> </message> </context> <context> @@ -786,14 +822,6 @@ Address: %4 <translation>メイン (&M)</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>あたなの取引が早く処理されるように任意で kB 毎の取引手数料を設定します。ほとんどの取引は 1 kB です。</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>支払う取引手数料 (&f)</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>システムにログインした時に自動的に Bitcoin を起動します。</translation> </message> @@ -810,6 +838,14 @@ Address: %4 <translation>MB</translation> </message> <message> + <source>Number of script &verification threads</source> + <translation>スクリプト検証用スレッド数 (&V)</translation> + </message> + <message> + <source>Accept connections from outside</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> @@ -933,10 +969,6 @@ Address: %4 <translation>表示された情報は古いかもしれません。接続が確立されると、あなたのウォレットは Bitcoin ネットワークと自動的に同期しますが、このプロセスはまだ完了していません。</translation> </message> <message> - <source>Wallet</source> - <translation>ウォレット</translation> - </message> - <message> <source>Your current spendable balance</source> <translation>あなたの利用可能残高</translation> </message> @@ -961,8 +993,12 @@ Address: %4 <translation>あなたの現在の残高</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>最近の取引</b></translation> + <source>Recent transactions</source> + <translation>最近のトランザクション</translation> + </message> + <message> + <source>Mined balance in watch-only addresses that has not yet matured</source> + <translation>ウォッチオンリーアドレスの採掘された残高のうち、成熟していないもの</translation> </message> <message> <source>out of sync</source> @@ -980,6 +1016,14 @@ Address: %4 <translation>支払いのアドレス「%1」は無効です</translation> </message> <message> + <source>Payment request rejected</source> + <translation>支払い要求は拒否されました</translation> + </message> + <message> + <source>Payment request has expired.</source> + <translation>支払いのリクエストは期限切れです</translation> + </message> + <message> <source>Payment request error</source> <translation>支払いのリクエストのエラーです</translation> </message> @@ -1006,6 +1050,10 @@ Address: %4 </context> <context> <name>PeerTableModel</name> + <message> + <source>User Agent</source> + <translation>ユーザエージェント</translation> + </message> </context> <context> <name>QObject</name> @@ -1096,6 +1144,10 @@ Address: %4 <translation>現在のブロック数</translation> </message> <message> + <source>User Agent</source> + <translation>ユーザエージェント</translation> + </message> + <message> <source>Last block time</source> <translation>最終ブロックの日時</translation> </message> @@ -1187,6 +1239,10 @@ Address: %4 <translation>メッセージ (&M):</translation> </message> <message> + <source>Clear all fields of the form.</source> + <translation>全ての入力項目をクリア</translation> + </message> + <message> <source>Clear</source> <translation>クリア</translation> </message> @@ -1195,6 +1251,10 @@ Address: %4 <translation>表示</translation> </message> <message> + <source>Remove the selected entries from the list</source> + <translation>リストから選択項目を削除</translation> + </message> + <message> <source>Copy label</source> <translation>ラベルをコピーする</translation> </message> @@ -1340,6 +1400,10 @@ Address: %4 <translation>受取人を追加 (&R)</translation> </message> <message> + <source>Clear all fields of the form.</source> + <translation>全ての入力項目をクリア</translation> + </message> + <message> <source>Clear &All</source> <translation>すべてクリア (&A)</translation> </message> @@ -1465,7 +1529,15 @@ Address: %4 </context> <context> <name>ShutdownWindow</name> - </context> + <message> + <source>Bitcoin Core is shutting down...</source> + <translation>Bitcoin Coreをシャットダウンしています。</translation> + </message> + <message> + <source>Do not shut down the computer until this window disappears.</source> + <translation>このウィンドウが消えるまでコンピュータをシャットダウンしないで下さい。</translation> + </message> +</context> <context> <name>SignVerifyMessageDialog</name> <message> @@ -1988,7 +2060,11 @@ Address: %4 </context> <context> <name>WalletFrame</name> - </context> + <message> + <source>No wallet has been loaded.</source> + <translation>ウォレットがロードされていません</translation> + </message> +</context> <context> <name>WalletModel</name> <message> @@ -2030,26 +2106,10 @@ Address: %4 <translation>オプション:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>設定ファイルの指定 (初期値: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>pid ファイルの指定 (初期値: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>データ ディレクトリの指定</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>接続のポート番号 (初期値: 8333、testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>ピアの最大接続数 (初期値: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>ピア アドレスを取得するためにノードに接続し、そして切断します</translation> </message> @@ -2058,18 +2118,6 @@ Address: %4 <translation>あなた自身のパブリックなアドレスを指定</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>不正なピアを切断するためのしきい値 (初期値: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>不正なピアを再接続するまでの秒数 (初期値: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation><port> で JSON-RPC 接続をリスン (初期値: 8332、testnet は 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>コマンドラインと JSON-RPC コマンドを許可</translation> </message> @@ -2153,10 +2201,6 @@ rpcpassword=%s <translation>(デフォルト: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(デフォルト: wallet.dat)</translation> - </message> - <message> <source>Attempt to recover private keys from a corrupt wallet.dat</source> <translation>壊れた wallet.dat から秘密鍵を復旧することを試す</translation> </message> @@ -2210,66 +2254,10 @@ rpcpassword=%s <translation>エラー: ウォレットはロックされ、取引を作成できません!</translation> </message> <message> - <source>Error: system error: </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>Failed to read block info</source> - <translation>ブロック情報の読み取りに失敗しました</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>ブロックの読み取りに失敗しました</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>ブロック インデックスの同期に失敗しました</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>ブロック インデックスの書き込みに失敗しました</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>ブロック情報の書き込みに失敗しました</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>ブロックの書き込みに失敗しました</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>ファイル情報の書き込みに失敗しました</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>コインデータベースへの書き込みに失敗しました</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>取引インデックスの書き込みに失敗しました</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>元へ戻すデータの書き込みに失敗しました</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>セーフモードを矯正する (デフォルト: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>コインを生成 (初期値: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>起動時に点検するブロック数 (初期値: 288, 0=すべて)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation><category> が与えられなかった場合には、すべてのデバッグ情報が出力されます。</translation> </message> @@ -2286,10 +2274,6 @@ rpcpassword=%s <translation>現在の blk000??.dat ファイルからブロック チェーンのインデックスを再構築</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>RPC サービスのスレッド数を設定 (初期値: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>ウォレットのファイルを指定 (データ・ディレクトリの中に)</translation> </message> @@ -2330,34 +2314,6 @@ rpcpassword=%s <translation>不正な額 -minrelaytxfee=<amount>: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>署名キャッシュのサイズを <n> エントリーに制限する (デフォルト: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>ブロックの採掘時にトランザクションの優先度と1kBあたりの手数料をログに残す (デフォルト: 0)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>完全な取引インデックスを維持する (初期値: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>接続毎の最大受信バッファ <n>*1000 バイト (初期値: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>接続毎の最大送信バッファ <n>*1000 バイト (初期値: 1000)</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>内蔵のチェックポイントと一致するブロック チェーンのみを許可 (初期値: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation><net> (IPv4, IPv6, Tor) ネットワーク内のノードだけに接続する</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>RPC SSL オプション: (SSLのセットアップ手順はビットコインWikiを参照してください)</translation> </message> @@ -2370,10 +2326,6 @@ rpcpassword=%s <translation>トレース/デバッグ情報を debug.log ファイルの代わりにコンソールへ送る</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>最小ブロックサイズをバイトで設定 (初期値: 0)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>クライアント起動時に debug.log ファイルを縮小 (初期値: -debug オプションを指定しない場合は1)</translation> </message> @@ -2382,14 +2334,6 @@ rpcpassword=%s <translation>取引の署名に失敗しました</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>接続のタイムアウトをミリセコンドで指定 (初期値: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>システム エラー:</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>取引の額が小さ過ぎます</translation> </message> @@ -2402,10 +2346,6 @@ rpcpassword=%s <translation>取引が大き過ぎます</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>リスン ポートの割当に UPnP を使用 (初期値: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>リスン ポートの割当に UPnP を使用 (初期値: リスン中は1)</translation> </message> @@ -2438,10 +2378,6 @@ rpcpassword=%s <translation>ウォレットを最新のフォーマットにアップグレード</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>key pool のサイズを <n> (初期値: 100) にセット</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>失ったウォレットの取引のブロック チェーンを再スキャン</translation> </message> @@ -2450,14 +2386,6 @@ rpcpassword=%s <translation>JSON-RPC 接続に OpenSSL (https) を使用</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>サーバ証明書ファイル (初期値: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>サーバの秘密鍵 (初期値: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>このヘルプ メッセージ</translation> </message> diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts index c23367171d..3faad159ad 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> @@ -375,10 +375,6 @@ <translation>ბარათების პანელი</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -415,10 +411,6 @@ <translation>ბლოკების წყარო მიუწვდომელია...</translation> </message> <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>დამუშავებულია ტრანსაქციების ისტორიის %1 ბლოკი.</translation> - </message> - <message> <source>%1 and %2</source> <translation>%1 და %2</translation> </message> @@ -493,10 +485,6 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>მონეტების კონტროლის მისამართის არჩევა</translation> - </message> - <message> <source>Quantity:</source> <translation>რაოდენობა:</translation> </message> @@ -541,10 +529,6 @@ Address: %4 <translation>თანხა</translation> </message> <message> - <source>Address</source> - <translation>მისამართი</translation> - </message> - <message> <source>Date</source> <translation>თარიღი</translation> </message> @@ -852,15 +836,7 @@ Address: %4 <source>Error</source> <translation>შეცდომა</translation> </message> - <message> - <source>GB of free space available</source> - <translation>გიგაბაიტია თავისუფალი</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(საჭიროა %1GB)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -895,14 +871,6 @@ Address: %4 <translation>&მთავარი</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>დამატებითი საკომისიო თითო კილობაიტზე; აჩქარებს ტრანსაქციის შესრულებას. ტრანსაქციების უმეტესობა არის 1 კბ.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>ტრანსაქციის სა&ფასურის გადახდა</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>სისტემაში შესვლის შემდეგ Bitcoin-ის ავტომატური გაშვება.</translation> </message> @@ -923,14 +891,6 @@ Address: %4 <translation>სკრიპტის &ვერიფიცირების ნაკადების რაოდენობა</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Bitcoin-ქსელზე მიერთება SOCKS-პროქსით.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>SO&CKS (ნაგულისხმევი) პროქსი მიერთებისათვის:</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> @@ -1070,10 +1030,6 @@ Address: %4 <translation>ნაჩვენები ინფორმაცია შეიძლება მოძველებული იყოს. თქვენი საფულე ავტომატურად სინქრონიზდება Bitcoin-ის ქსელთან კავშირის დამყარების შემდეგ, ეს პროცესი ჯერ არ არის დასრულებული.</translation> </message> <message> - <source>Wallet</source> - <translation>საფულე</translation> - </message> - <message> <source>Available:</source> <translation>ხელმისაწვდომია:</translation> </message> @@ -1106,10 +1062,6 @@ Address: %4 <translation>თქვენი სრული მიმდინარე ბალანსი</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>ბოლო ტრანსაქციები</b></translation> - </message> - <message> <source>out of sync</source> <translation>არ არის სინქრონიზებული</translation> </message> @@ -2351,26 +2303,10 @@ Address: %4 <translation>ოპციები:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>მიუთითეთ საკონფიგურაციო ფაილი (ნაგულისხმევია: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>მიუთითეთ pid ფაილი (ნაგულისხმევია: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>მიუთითეთ მონაცემთა კატალოგი</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>მიყურადება პორტზე <port> (ნაგულისხმევი: 8333 ან სატესტო ქსელში: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>არაუმეტეს <n> შეერთებისა პირებზე (ნაგულისხმევი: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>მიერთება კვანძთან, პირების მისამართების მიღება და გათიშვა</translation> </message> @@ -2379,18 +2315,6 @@ Address: %4 <translation>მიუთითეთ თქვენი საჯარო მისამართი</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>არასწორად მოქმედი პირების გათიშვის ზღვარი (ნაგულისხმევი:100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>არასწორად მოქმედი პირების ბლოკირების დრო წამებში (ნაგულისხმევი: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation> JSON-RPC-შეერთებების მიყურადება პორტზე <port> (ნაგულისხმევი: 8332 ან სატესტო ქსელში: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>საკომანდო სტრიქონისა და JSON-RPC-კომამდების ნებართვა</translation> </message> @@ -2431,10 +2355,6 @@ rpcpassword=%s </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>დაშვებული ალგორითმები (ნაგულისხმევი: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>მოცემულ მისამართზე მიჯაჭვა მუდმივად მასზე მიყურადებით. გამოიყენეთ [host]:port ფორმა IPv6-სათვის</translation> </message> @@ -2459,10 +2379,6 @@ rpcpassword=%s <translation>ეს არის წინასწარი სატესტო ვერსია - გამოიყენეთ საკუთარი რისკით - არ გამოიყენოთ მოპოვებისა ან კომერციული მიზნებისათვის</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>ფარული Tor-სერვისებით პირების წვდომისათვის სხვა SOCKS5 პროქსის გამოყენება (ნაგულისხმევია: -proxy)</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> @@ -2539,62 +2455,10 @@ rpcpassword=%s <translation>შეცდომა: საფულე დაბლოკილია, ტრანსაქცია ვერ შეიქმნება!</translation> </message> <message> - <source>Error: system error: </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>Failed to read block info</source> - <translation>ბლოკის ინფორმაცია არ იკითხება</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>ბლოკი არ იკითხება</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>ბლოკების ინდექსის სინქრონიზება ვერ მოხერხდა</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>ბლოკების ინდექსის ჩაწერა ვერ მოხერხდა</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>ბლოკის ინფორმაციის ჩაწერა ვერ მოხერხდა</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>ბლოკის ჩაწერა ვერ მოხერხდა</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>ფაილის ინფორმაციის ჩაწერა ვერ მოხერხდა</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>მონეტების ბაზის ჩაწერა ვერ მოხერხდა</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>ტრანსაქციების ინდექსის ჩაწერა ვერ მოხერხდა</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>ცვლილებების გაუქმების მონაცემთა ჩაწერა ვერ მოხერხდა</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>მონეტების გენერირება (ნაგულისხმევი: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>რამდენი ბლოკი შემოწმდეს გაშვებისას (ნაგულისხმევი: 288, 0 - ყველა)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>თუ <category> არ არის მითითებული, ნაჩვენები იქნება სრული დახვეწის ინფორმაცია.</translation> </message> @@ -2611,10 +2475,6 @@ rpcpassword=%s <translation>არ არის საკმარისი ფაილ-დესკრიპტორები.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>დაემატოს დახვეწის ინფორმაციას დროის ჭდეები (ნაგულისხმევი: 1)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files</source> <translation>ბლოკთა ჯაჭვის ინდექსის ხელახლა აგება blk000??.dat ფაილიდან</translation> </message> @@ -2623,18 +2483,10 @@ rpcpassword=%s <translation>ბლოკის მაქსიმალური ზომის განსაზღვრა ბაიტებში (ნადულისხმევი: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>RPC-ნაკადების რაოდენობა (ნაგულისხმევი: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>მიუთითეთ საფულის ფაილი (კატალოგში)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>დაუდასტურებელი ხურდის გამოყენება ტრანსაქციის გაგზავნისას (ნაგულისხმევი: 1)</translation> - </message> - <message> <source>This is intended for regression testing tools and app development.</source> <translation>გამოიყენება რეგრესული ტესტირების ინსტრუმენტებისა და პროგრამების შემუშავებისას.</translation> </message> @@ -2667,10 +2519,6 @@ rpcpassword=%s <translation>ბრძანების შესრულება შესაბამისი უწყების მიღებისას ან როცა შეინიშნება საგრძნობი გახლეჩა (cmd-ში %s შეიცვლება მესიჯით)</translation> </message> <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>დახვეწის ინფორმაციის გამოყვანა (ნაგულისხმევი: 0, <category> - არააუცილებელი არგუმენტია)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>მაღალპრიორიტეტული/დაბალსაკომისიოიანი ტრანსაქციების მაქსიმალური ზომა ბაიტებში (ნაგულისხმევი: %d)</translation> </message> @@ -2687,34 +2535,10 @@ rpcpassword=%s <translation>დაუშვებელი მნიშვნელობა -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>ტრანსაქციის სრული ინდექსი (ნაგულისხმევი: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>მიღების ბუფერის მაქსიმალური ზომა შეერთებაზე, <n>*1000 ბაიტი (ნაგულისხმევი: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>გაგზავნის ბუფერის მაქსიმალური ზომა შეერთებაზე, <n>*1000 ბაიტი (ნაგულისხმევი: 5000)</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>ბლოკთა ჯაჭვი მიიღეთ მხოლოდ მაშინ, თუ ემთხვევა შიდა ჩეკპოინტები (ნაგულისხმევი: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>შეერთება მხოლოდ <net> ქსელის კვანძებთან (IPv4, IPv6 ან Tor)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>ტრასირების/დახვეწის ინფოს გაგზავნა კონსოლზე debug.log ფაილის ნაცვლად</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>დააყენეთ ბლოკის მინიმალური ზომა ბაიტებში (ნაგულისხმევი: 0)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>debug.log ფაილის შეკუმშვა გაშვებისას (ნაგულისხმევია: 1 როცა არ აყენია -debug)</translation> </message> @@ -2723,14 +2547,6 @@ rpcpassword=%s <translation>ტრანსაქციების ხელმოწერა ვერ მოხერხდა</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>მიუთითეთ შეერთების ტაიმაუტი მილიწამებში (ნაგულისხმევი: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>სისტემური შეცდომა:</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>ტრანსაქციების რაოდენობა ძალიან ცოტაა</translation> </message> @@ -2743,10 +2559,6 @@ rpcpassword=%s <translation>ტრანსაქცია ძალიან დიდია</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>გამოიყენეთ UPnP მისაყურადებელი პორტის გადასამისამართებლად (ნაგულისხმევი: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>გამოიყენეთ UPnP მისაყურადებელი პორტის გადასამისამართებლად (ნაგულისხმევი: 1 როცა ჩართულია მიყურადება)</translation> </message> @@ -2783,10 +2595,6 @@ rpcpassword=%s <translation>საფულის ფორმატის განახლება</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>გასაღების პულის ზომა იქნება <n> (ნაგულისხმევი: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>ბლოკების ჯაჭვის გადამოწმება საფულეში გამორჩენილ ტრანსაქციებზე</translation> </message> @@ -2795,14 +2603,6 @@ rpcpassword=%s <translation>OpenSSL-ის (https) გამოყენება JSON-RPC-შეერთებებისათვის</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>სერვერის სერტიფიკატის ფაილი (ნაგულისხმევი: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>სერვერის პირადი გასაღები (ნაგულისხმევი: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>ეს ტექსტი</translation> </message> diff --git a/src/qt/locale/bitcoin_kk_KZ.ts b/src/qt/locale/bitcoin_kk_KZ.ts index e9eddd503c..5a39417a7a 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> @@ -10,10 +10,22 @@ <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>C&lose</source> + <translation>Жабу</translation> + </message> + <message> + <source>&Export</source> + <translation>Экспорт</translation> + </message> + <message> <source>&Delete</source> <translation>Жою</translation> </message> @@ -78,6 +90,90 @@ </context> <context> <name>BitcoinGUI</name> + <message> + <source>&Transactions</source> + <translation>&Транзакциялар</translation> + </message> + <message> + <source>E&xit</source> + <translation>Шығу</translation> + </message> + <message> + <source>&Options...</source> + <translation>Параметрлері</translation> + </message> + <message> + <source>&Backup Wallet...</source> + <translation>Әмиянды жасыру</translation> + </message> + <message> + <source>&Change Passphrase...</source> + <translation>Құпия сөзді өзгерту</translation> + </message> + <message> + <source>Bitcoin</source> + <translation>Биткоин</translation> + </message> + <message> + <source>Wallet</source> + <translation>Әмиян</translation> + </message> + <message> + <source>&Send</source> + <translation>Жіберу</translation> + </message> + <message> + <source>&Receive</source> + <translation>Алу</translation> + </message> + <message> + <source>&File</source> + <translation>Файл</translation> + </message> + <message> + <source>&Help</source> + <translation>Көмек</translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n сағат</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n күн</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><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></translation> + </message> + <message> + <source>%1 behind</source> + <translation>%1 қалмады</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> </context> <context> <name>ClientModel</name> @@ -85,8 +181,48 @@ <context> <name>CoinControlDialog</name> <message> - <source>Address</source> - <translation>Адрес</translation> + <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>Amount</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>no</source> + <translation>жоқ</translation> </message> <message> <source>(no label)</source> @@ -95,6 +231,10 @@ </context> <context> <name>EditAddressDialog</name> + <message> + <source>&Address</source> + <translation>Адрес</translation> + </message> </context> <context> <name>FreespaceChecker</name> @@ -104,6 +244,10 @@ </context> <context> <name>Intro</name> + <message> + <source>Error</source> + <translation>қате</translation> + </message> </context> <context> <name>OpenURIDialog</name> @@ -122,6 +266,10 @@ </context> <context> <name>QObject</name> + <message> + <source>Amount</source> + <translation>Саны</translation> + </message> </context> <context> <name>QRImageWidget</name> @@ -139,6 +287,10 @@ <translation>Адрес</translation> </message> <message> + <source>Amount</source> + <translation>Саны</translation> + </message> + <message> <source>Label</source> <translation>таңба</translation> </message> @@ -146,10 +298,18 @@ <context> <name>RecentRequestsTableModel</name> <message> + <source>Date</source> + <translation>Күні</translation> + </message> + <message> <source>Label</source> <translation>таңба</translation> </message> <message> + <source>Amount</source> + <translation>Саны</translation> + </message> + <message> <source>(no label)</source> <translation>(таңбасыз)</translation> </message> @@ -157,6 +317,26 @@ <context> <name>SendCoinsDialog</name> <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>Dust:</source> + <translation>Шаң</translation> + </message> + <message> <source>(no label)</source> <translation>(таңбасыз)</translation> </message> @@ -178,6 +358,14 @@ </context> <context> <name>TransactionDesc</name> + <message> + <source>Date</source> + <translation>Күні</translation> + </message> + <message> + <source>Amount</source> + <translation>Саны</translation> + </message> </context> <context> <name>TransactionDescDialog</name> @@ -185,6 +373,10 @@ <context> <name>TransactionTableModel</name> <message> + <source>Date</source> + <translation>Күні</translation> + </message> + <message> <source>Address</source> <translation>Адрес</translation> </message> @@ -196,6 +388,14 @@ <translation>Үтірмен бөлінген файл (*.csv)</translation> </message> <message> + <source>Confirmed</source> + <translation>Растық</translation> + </message> + <message> + <source>Date</source> + <translation>Күні</translation> + </message> + <message> <source>Label</source> <translation>таңба</translation> </message> @@ -215,10 +415,18 @@ </context> <context> <name>WalletView</name> + <message> + <source>&Export</source> + <translation>Экспорт</translation> + </message> </context> <context> <name>bitcoin-core</name> <message> + <source>Information</source> + <translation>Информация</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Транзакция өте кішкентай</translation> </message> @@ -226,5 +434,13 @@ <source>Transaction too large</source> <translation>Транзакция өте үлкен</translation> </message> - </context> + <message> + <source>Warning</source> + <translation>Ескерту</translation> + </message> + <message> + <source>Error</source> + <translation>қате</translation> + </message> +</context> </TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 9fe31b4330..efc41ec6b7 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -1,4 +1,4 @@ -<TS language="ko_KR" version="2.1"> +<TS language="ko_KR" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -287,6 +287,10 @@ <translation>URI&열기...</translation> </message> <message> + <source>Bitcoin Core client</source> + <translation>비트코인 코어 클라이언트</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>디스크에서 블록 가져오는 중...</translation> </message> @@ -339,6 +343,10 @@ <translation>받기(&R)</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>비트코인 코어에 관한 정보입니다.</translation> + </message> + <message> <source>&Show / Hide</source> <translation>보이기/숨기기(&S)</translation> </message> @@ -375,10 +383,6 @@ <translation>툴바 색인표</translation> </message> <message> - <source>[testnet]</source> - <translation>[테스트넷]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>비트코인 코어</translation> </message> @@ -414,10 +418,6 @@ <source>No block source available...</source> <translation>사용 가능한 블록이 없습니다...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>%1 블록의 거래 기록들이 처리됨.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n시간</numerusform></translation> @@ -505,10 +505,6 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>코인 컨트롤 주소 선택</translation> - </message> - <message> <source>Quantity:</source> <translation>수량:</translation> </message> @@ -529,10 +525,18 @@ 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> @@ -549,10 +553,6 @@ Address: %4 <translation>거래량</translation> </message> <message> - <source>Address</source> - <translation>주소</translation> - </message> - <message> <source>Date</source> <translation>날짜</translation> </message> @@ -852,15 +852,7 @@ Address: %4 <source>Error</source> <translation>오류</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB가 사용가능</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(%1GB가 필요)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -895,14 +887,6 @@ Address: %4 <translation>메인(&M)</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>당신의 거래가 더욱 빠르게 처리될 수 있도록 선택적으로 kBd당 거래 수수료를 지정합니다. 참고로 대부분의 거래들은 1kB입니다.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>송금 수수료(&F)</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>시스템 로그인후에 비트코인을 자동으로 시작합니다.</translation> </message> @@ -923,12 +907,12 @@ Address: %4 <translation>스크립트 인증 쓰레드의 개수</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>SOCKS 프록시를 통해 비트코인 네트워크 연결</translation> + <source>Accept connections from outside</source> + <translation>외부로부터의 연결을 승인합니다.</translation> </message> <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>SOCKS 프록시를 거쳐 연결합니다 (기본값 프록시):</translation> + <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> @@ -1082,8 +1066,8 @@ Address: %4 <translation>표시한 정보가 오래된 것 같습니다. 비트코인 네트워크에 연결하고 난 다음에 지갑을 자동으로 동기화 하지만, 아직 과정이 끝나지는 않았습니다.</translation> </message> <message> - <source>Wallet</source> - <translation>지갑</translation> + <source>Watch-only:</source> + <translation>모니터링 지갑:</translation> </message> <message> <source>Available:</source> @@ -1118,8 +1102,8 @@ Address: %4 <translation>당신의 현재 총액</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>최근 거래내역</b></translation> + <source>Your current balance in watch-only addresses</source> + <translation>모니터링 지갑의 현재 잔액</translation> </message> <message> <source>out of sync</source> @@ -1537,6 +1521,10 @@ Address: %4 <translation>수수료 이후:</translation> </message> <message> + <source>Change:</source> + <translation>체인지:</translation> + </message> + <message> <source>Custom change address</source> <translation>주소변경</translation> </message> @@ -1553,6 +1541,10 @@ Address: %4 <translation>양식의 모든 필드를 지웁니다</translation> </message> <message> + <source>Dust:</source> + <translation>더스트:</translation> + </message> + <message> <source>Clear &All</source> <translation>모두 지우기(&A)</translation> </message> @@ -1712,6 +1704,10 @@ Address: %4 <translation>사용된 주소 목록에 새 주소를 추가하기 위해 제목을 입력합니다. </translation> </message> <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>비트코인에 첨부된 메시지: 참고용으로 거래와 함께 저장될 URI. 메모: 이 메시지는 비트코인 네트워크로 전송되지 않습니다.</translation> + </message> + <message> <source>This is an unverified payment request.</source> <translation>지급요청 미확인입니다</translation> </message> @@ -2319,26 +2315,10 @@ Address: %4 <translation>옵션:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>설정파일 지정 (기본값: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>pid 파일 지정 (기본값: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>데이터 폴더 지정</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation><port>로 연결을 허용한다 (기본값: 8333 또는 테스트넷: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>가장 잘 연결되는 사용자를 유지합니다(기본값: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>피어 주소를 받기 위해 노드에 연결하고, 받은 후에 연결을 끊습니다</translation> </message> @@ -2347,18 +2327,6 @@ Address: %4 <translation>공인 주소를 지정하십시오</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>이상행동 네트워크 참여자의 연결을 차단시키기 위한 한계치 (기본값: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>이상행동을 하는 네트워크 참여자들을 다시 연결시키는데 걸리는 시간 (기본값: 86400초)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>포트 <port>을 통해 JSON-RPC 연결 (기본값: 8332 또는 testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>명령줄과 JSON-RPC 명령 수락</translation> </message> @@ -2375,10 +2343,6 @@ Address: %4 <translation>외부 접속을 승인합니다</translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>암호 허용(기본값: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>선택된 주소로 고정하며 항상 리슨(Listen)합니다. IPv6 프로토콜인 경우 [host]:port 방식의 명령어 표기법을 사용합니다.</translation> </message> @@ -2401,10 +2365,6 @@ Address: %4 <translation>이 빌드 버전은 정식 출시 전 테스트의 목적이며, 예기치 않은 위험과 오류가 발생할 수 있습니다. 채굴과 상점용 소프트웨어로 사용하는 것을 권하지 않습니다.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Tor 서비스를 이용하여 네트워크에 참여하기 위해서 SOCKS5 프록시를 따로 사용함 (기본값: -proxy)</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> @@ -2429,10 +2389,6 @@ Address: %4 <translation>(기본값: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(기본값: wallet.dat)</translation> - </message> - <message> <source>Attempt to recover private keys from a corrupt wallet.dat</source> <translation>손상된 wallet.dat에서 개인키 복원을 시도합니다</translation> </message> @@ -2457,10 +2413,6 @@ Address: %4 <translation>디버그 및 테스트 설정</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>안전 모드를 비활성화하고 안전 모드의 이벤트가 발생하더라도 무시합니다. (기본값: 0, 비활성화)</translation> - </message> - <message> <source>Discover own IP address (default: 1 when listening and no -externalip)</source> <translation>자신의 아이피 주소를 발견합니다 (기본값: 1 반응이 없거나 외부 아이피가 없을 때)</translation> </message> @@ -2493,64 +2445,12 @@ Address: %4 <translation>오류: 지갑이 잠금상태여서 거래를 생성할 수 없습니다!</translation> </message> <message> - <source>Error: system error: </source> - <translation>오류: 시스템 오류:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>어떤 포트도 반응하지 않습니다. 사용자 반응=0 만약 원한다면</translation> </message> <message> - <source>Failed to read block info</source> - <translation>블록 정보를 읽는데 실패했습니다</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>블록을 읽는데 실패했습니다</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>블록 인덱스를 동기화하는데 실패했습니다</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>블록 인덱스를 기록하는데 실패했습니다</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>블록 정보를 기록하는데 실패했습니다</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>블록을 기록하는데 실패했습니다</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>파일 정보를 기록하는데 실패했습니다</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>코인 데이터베이스에 기록하는데 실패했습니다</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>송금 인덱스에 기록하는데 실패했습니다</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>데이터 실행 취소를 기록하는데 실패했습니다</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>안전 모드로 강제 진입하는 기능입니다.(기본값: 0) </translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>코인 생성(기본값: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>시작할때 검사할 블록 갯수입니다(기본값: 288, 0 = 모두)</translation> + <source>If <category> is not supplied, output all debugging information.</source> + <translation><카테고리>가 제공되지 않을 경우, 모든 디버깅 정보를 출력</translation> </message> <message> <source>Importing...</source> @@ -2581,10 +2481,6 @@ Address: %4 <translation>최대 블락 크기를 Bytes로 지정하세요 (기본: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>원격 프로시져 호출 서비스를 위한 쓰레드 개수를 설정합니다 (기본값 : 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>데이터 폴더 안에 지갑 파일을 선택하세요.</translation> </message> @@ -2621,10 +2517,6 @@ Address: %4 <translation>이 사항과 관련있는 경고가 발생하거나 아주 긴 포크가 발생했을 때 명령어를 실행해 주세요. (cmd 명령어 목록에서 %s는 메시지로 대체됩니다) </translation> </message> <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>출력 오류 정보(기본값:0, 임의의 공급 카테고리)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>최대 크기를 최우선으로 설정 / 바이트당 최소 수수료로 거래(기본값: %d)</translation> </message> @@ -2641,42 +2533,10 @@ Address: %4 <translation>최저 거래 수수료가 부족합니다. -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation><n>번 째 순서에서 전자서명 캐쉬의 용량을 제한합니다. (기본값: 50000) </translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>블럭을 채굴할 때 kB당 거래 우선 순위와 수수료를 로그에 남깁니다. (기본값: 0, 비활성화)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>전체 거래 지수를 유지합니다(기본값: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>최대 연결마다 1000bytes 버퍼를 받는다. (기본값: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>최대 연결 마다 1000bytes 버퍼를 보낸다.(기본값: 1000) </translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>내부 중단점에 일치하는 블록 체인만 수용(기본값: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>노드가 있는 네트워크에만 접속 합니다(IPv4, IPv6 또는 Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>블럭 색인을 발견하면 구동 시 블럭을 출력합니다.</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>구동 시 블럭 트리를 출력합니다. (기본값: 0, 비활성화)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>RPC SSL 옵션: (비트코인 위키의 SSL 설정 설명서 참고)</translation> </message> @@ -2693,14 +2553,6 @@ Address: %4 <translation>추적오류 정보를 degug.log 자료로 보내는 대신 콘솔로 보내기</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>바이트 단위의 최소 블록 크기 설정(기본값: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>전자지갑 데이터베이스 환경에 DB_PRIVATE 플래그를 설정합니다. (기본값: 1, 활성화)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>모든 디버그 설정 보기(설정: --help -help-debug)</translation> </message> @@ -2713,14 +2565,6 @@ Address: %4 <translation>거래를 서명하는것을 실패하였습니다.</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>밀리초 단위로 연결 제한시간을 설정하십시오(기본값: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>시스템 오류:</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>거래량이 너무 적습니다</translation> </message> @@ -2733,10 +2577,6 @@ Address: %4 <translation>너무 큰 거래</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>UPnP사용하여 지도에서 포트 반응기다리는 중 (기본값: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>UPnP사용하여 지도에서 포트 반응기다리는 중 (기본값: 1 반응이 생기면)</translation> </message> @@ -2777,10 +2617,6 @@ Address: %4 <translation>지갑을 최근 형식으로 개선하시오</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>키 풀 크기 설정 <n>(기본값: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>누락된 지갑 송금에 대한 블록 체인 다시 검색</translation> </message> @@ -2789,14 +2625,6 @@ Address: %4 <translation>JSON-RPC 연결에 OpenSSL(https) 사용</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>서버 인증 파일 (기본값: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>서버 개인 키(기본값: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>도움말 메시지입니다</translation> </message> diff --git a/src/qt/locale/bitcoin_ky.ts b/src/qt/locale/bitcoin_ky.ts index ad4b5eae03..ed7542261c 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> @@ -73,10 +73,6 @@ <context> <name>CoinControlDialog</name> <message> - <source>Address</source> - <translation>Дарек</translation> - </message> - <message> <source>Date</source> <translation>Дата</translation> </message> @@ -154,10 +150,6 @@ <context> <name>OverviewPage</name> <message> - <source>Wallet</source> - <translation>Капчык</translation> - </message> - <message> <source>out of sync</source> <translation>синхрондоштурулган эмес</translation> </message> diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts index 450228b221..c399f36159 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> @@ -315,10 +315,6 @@ <translation>Tabella instrumentorum "Tabs"</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Nucleus</translation> </message> @@ -330,10 +326,6 @@ <source>No block source available...</source> <translation>Nulla fons frustorum absens...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Processae %1 frusta historiae transactionum.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n horae</numerusform></translation> @@ -425,10 +417,6 @@ Inscriptio: %4 <translation>Quantitas</translation> </message> <message> - <source>Address</source> - <translation>Inscriptio</translation> - </message> - <message> <source>Date</source> <translation>Dies</translation> </message> @@ -571,14 +559,6 @@ Inscriptio: %4 <translation>&Princeps</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Optionalis merces transactionum singulis kB quae adiuvat curare tuas transactiones processas esse celeriter. Plurimi transactiones 1kB sunt.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Solve &mercedem transactionis</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> @@ -690,10 +670,6 @@ Inscriptio: %4 <translation>Monstrata informatio fortasse non recentissima est. Tuum cassidile per se synchronizat cum rete Bitcoin postquam conexio constabilita est, sed hoc actio nondum perfecta est.</translation> </message> <message> - <source>Wallet</source> - <translation>Cassidile</translation> - </message> - <message> <source>Immature:</source> <translation>Immatura:</translation> </message> @@ -702,10 +678,6 @@ Inscriptio: %4 <translation>Fossum pendendum quod nondum maturum est</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Recentes transactiones</b></translation> - </message> - <message> <source>out of sync</source> <translation>non synchronizato</translation> </message> @@ -1515,26 +1487,10 @@ Inscriptio: %4 <translation>Optiones:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Specifica configurationis plicam (praedefinitum: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Specifica pid plicam (praedefinitum: bitcoin.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Specifica indicem datorum</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Ausculta pro conexionibus in <porta> (praedefinitum: 8333 vel testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Manutene non plures quam <n> conexiones ad paria (praedefinitum: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Conecta ad nodum acceptare inscriptiones parium, et disconecte</translation> </message> @@ -1543,18 +1499,6 @@ Inscriptio: %4 <translation>Specifica tuam propriam publicam inscriptionem</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Limen pro disconectendo paria improba (praedefinitum: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Numerum secundorum prohibere ne paria improba reconectant (praedefinitum: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Ausculta pro conexionibus JSON-RPC in <porta> (praedefinitum: 8332 vel testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Accipe terminalis et JSON-RPC mandata.</translation> </message> @@ -1675,62 +1619,10 @@ exempli gratia: alertnotify=echo %%s | mail -s "Bitcoin Notificatio" admin@foo.c <translation>Error: Cassidile seratum, non posse transactionem creare!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Error: systematis error:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Non potuisse auscultare in ulla porta. Utere -listen=0 si hoc vis.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Non potuisse informationem frusti legere </translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Non potuisse frustum legere</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Synchronizare indicem frustorum abortum est</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Scribere indicem frustorum abortum est</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Scribere informationem abortum est</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Scribere frustum abortum est</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Scribere informationem plicae abortum est</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Scribere databasem nummorum abortum est</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Scribere indicem transactionum abortum est</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Scribere data pro cancellando mutationes abortum est</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Genera nummos (praedefinitum: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Quot frusta proba ad initium (praedefinitum: 288, 0 = omnia)</translation> - </message> - <message> <source>Not enough file descriptors available.</source> <translation>Inopia descriptorum plicarum.</translation> </message> @@ -1739,10 +1631,6 @@ exempli gratia: alertnotify=echo %%s | mail -s "Bitcoin Notificatio" admin@foo.c <translation>Restituere indicem catenae frustorum ex activis plicis blk000??.dat</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Constitue numerum filorum ad tractandum RPC postulationes (praedefinitum: 4)</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>Verificante frusta...</translation> </message> @@ -1767,34 +1655,10 @@ exempli gratia: alertnotify=echo %%s | mail -s "Bitcoin Notificatio" admin@foo.c <translation>Quantitas non valida pro -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Manutene completam indicem transactionum (praedefinitum: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maxima magnitudo memoriae pro datis accipendis singulis conexionibus, <n>*1000 octetis/bytes (praedefinitum: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maxima magnitudo memoriae pro datis mittendis singulis conexionibus, <n>*1000 octetis/bytes (praedefinitum: 1000)</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Tantum accipe catenam frustorum convenientem internis lapidibus (praedefinitum: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Tantum conecte ad nodos in rete <net> (IPv4, IPv6 aut Tor)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Mitte informationem vestigii/debug ad terminale potius quam plicam debug.log</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Constitue minimam magnitudinem frusti in octetis/bytes (praedefinitum: 0)</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> @@ -1803,14 +1667,6 @@ exempli gratia: alertnotify=echo %%s | mail -s "Bitcoin Notificatio" admin@foo.c <translation>Signandum transactionis abortum est</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Specifica tempumfati conexionis in millisecundis (praedefinitum: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Systematis error:</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Magnitudo transactionis nimis parva</translation> </message> @@ -1823,10 +1679,6 @@ exempli gratia: alertnotify=echo %%s | mail -s "Bitcoin Notificatio" admin@foo.c <translation>Transactio nimis magna</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Utere UPnP designare portam auscultandi (praedefinitum: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Utere UPnP designare portam auscultandi (praedefinitum: 1 quando auscultans)</translation> </message> @@ -1859,10 +1711,6 @@ exempli gratia: alertnotify=echo %%s | mail -s "Bitcoin Notificatio" admin@foo.c <translation>Progredere cassidile ad formam recentissimam</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Constitue magnitudinem stagni clavium ad <n> (praedefinitum: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Iterum perlege catenam frustorum propter absentes cassidilis transactiones</translation> </message> @@ -1871,14 +1719,6 @@ exempli gratia: alertnotify=echo %%s | mail -s "Bitcoin Notificatio" admin@foo.c <translation>Utere OpenSSL (https) pro conexionibus JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Plica certificationis daemonis moderantis (praedefinitum: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Clavis privata daemonis moderans (praedefinitum: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Hic nuntius auxilii</translation> </message> diff --git a/src/qt/locale/bitcoin_lt.ts b/src/qt/locale/bitcoin_lt.ts index 6d0fb684da..1f70400df6 100644 --- a/src/qt/locale/bitcoin_lt.ts +++ b/src/qt/locale/bitcoin_lt.ts @@ -1,4 +1,4 @@ -<TS language="lt" version="2.1"> +<TS language="lt" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -38,6 +38,18 @@ <translation>&Trinti</translation> </message> <message> + <source>C&hoose</source> + <translation>P&asirinkti</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Siunčiami adresai</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Gaunami adresai</translation> + </message> + <message> <source>Copy &Label</source> <translation>Kopijuoti ž&ymę</translation> </message> @@ -46,10 +58,22 @@ <translation>&Keisti</translation> </message> <message> + <source>Export Address List</source> + <translation>Eksportuoti adresų sąrašą</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Kableliais išskirtas failas (*.csv)</translation> </message> - </context> + <message> + <source>Exporting Failed</source> + <translation>Eksportavimas nepavyko</translation> + </message> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Bandant išsaugoti adresų sąrašą - įvyko klaida keliant į %1. Prašome bandyti dar kartą.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -179,6 +203,10 @@ <translation>&Apžvalga</translation> </message> <message> + <source>Node</source> + <translation>Taškas</translation> + </message> + <message> <source>Show general overview of wallet</source> <translation>Rodyti piniginės bendrą apžvalgą</translation> </message> @@ -223,6 +251,18 @@ <translation>&Keisti slaptafrazę...</translation> </message> <message> + <source>&Sending addresses...</source> + <translation>&Siunčiami adresai...</translation> + </message> + <message> + <source>&Receiving addresses...</source> + <translation>&Gaunami adresai...</translation> + </message> + <message> + <source>Bitcoin Core client</source> + <translation>Bitcoin Core klientas</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>Blokai importuojami iš disko...</translation> </message> @@ -275,6 +315,10 @@ <translation>&Gauti</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>Rodyti informaciją apie Bitcoin Core</translation> + </message> + <message> <source>&Show / Hide</source> <translation>&Rodyti / Slėpti</translation> </message> @@ -283,6 +327,10 @@ <translation>Rodyti arba slėpti pagrindinį langą</translation> </message> <message> + <source>Encrypt the private keys that belong to your wallet</source> + <translation>Užšifruoti privačius raktus, kurie priklauso jūsų piniginei</translation> + </message> + <message> <source>&File</source> <translation>&Failas</translation> </message> @@ -299,13 +347,13 @@ <translation>Kortelių įrankinė</translation> </message> <message> - <source>[testnet]</source> - <translation>[testavimotinklas]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin branduolys</translation> </message> + <message> + <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> @@ -322,6 +370,10 @@ <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> @@ -380,26 +432,66 @@ Adresas: %4</translation> <context> <name>CoinControlDialog</name> <message> + <source>Quantity:</source> + <translation>Kiekis:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Baitai:</translation> + </message> + <message> <source>Amount:</source> <translation>Suma:</translation> </message> <message> - <source>Amount</source> - <translation>Suma</translation> + <source>Priority:</source> + <translation>Pirmumas:</translation> </message> <message> - <source>Address</source> - <translation>Adresas</translation> + <source>Fee:</source> + <translation>Mokestis:</translation> + </message> + <message> + <source>After Fee:</source> + <translation>Po mokesčio:</translation> + </message> + <message> + <source>Change:</source> + <translation>Graža:</translation> + </message> + <message> + <source>(un)select all</source> + <translation>(ne)pasirinkti viską</translation> + </message> + <message> + <source>Tree mode</source> + <translation>Medžio režimas</translation> + </message> + <message> + <source>List mode</source> + <translation>Sąrašo režimas</translation> + </message> + <message> + <source>Amount</source> + <translation>Suma</translation> </message> <message> <source>Date</source> <translation>Data</translation> </message> <message> + <source>Confirmations</source> + <translation>Patvirtinimai</translation> + </message> + <message> <source>Confirmed</source> <translation>Patvirtintas</translation> </message> <message> + <source>Priority</source> + <translation>Pirmumas</translation> + </message> + <message> <source>Copy address</source> <translation>Kopijuoti adresą</translation> </message> @@ -412,6 +504,74 @@ Adresas: %4</translation> <translation>Kopijuoti sumą</translation> </message> <message> + <source>Copy quantity</source> + <translation>Kopijuoti kiekį</translation> + </message> + <message> + <source>Copy fee</source> + <translation>Kopijuoti mokestį</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Kopijuoti po mokesčio</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Kopijuoti baitus</translation> + </message> + <message> + <source>Copy priority</source> + <translation>Kopijuoti pirmumą</translation> + </message> + <message> + <source>highest</source> + <translation>auksčiausias</translation> + </message> + <message> + <source>higher</source> + <translation>aukštesnis</translation> + </message> + <message> + <source>high</source> + <translation>aukštas</translation> + </message> + <message> + <source>medium-high</source> + <translation>vidutiniškai aukštas</translation> + </message> + <message> + <source>medium</source> + <translation>vidutiniškai</translation> + </message> + <message> + <source>low-medium</source> + <translation>žemai-vidutiniškas</translation> + </message> + <message> + <source>low</source> + <translation>žemas</translation> + </message> + <message> + <source>lower</source> + <translation>žemesnis</translation> + </message> + <message> + <source>lowest</source> + <translation>žemiausias</translation> + </message> + <message> + <source>none</source> + <translation>niekas</translation> + </message> + <message> + <source>yes</source> + <translation>taip</translation> + </message> + <message> + <source>no</source> + <translation>ne</translation> + </message> + <message> <source>(no label)</source> <translation>(nėra žymės)</translation> </message> @@ -465,6 +625,10 @@ Adresas: %4</translation> </context> <context> <name>FreespaceChecker</name> + <message> + <source>name</source> + <translation>pavadinimas</translation> + </message> </context> <context> <name>HelpMessageDialog</name> @@ -477,6 +641,10 @@ Adresas: %4</translation> <translation>versija</translation> </message> <message> + <source>About Bitcoin Core</source> + <translation>Apie Bitcoin Core</translation> + </message> + <message> <source>Command-line options</source> <translation>Komandinės eilutės parametrai</translation> </message> @@ -508,6 +676,10 @@ Adresas: %4</translation> <translation>Sveiki</translation> </message> <message> + <source>Welcome to Bitcoin Core.</source> + <translation>Sveiki atvykę į Bitcoin Core.</translation> + </message> + <message> <source>Bitcoin Core</source> <translation>Bitcoin branduolys</translation> </message> @@ -530,10 +702,6 @@ Adresas: %4</translation> <translation>&Pagrindinės</translation> </message> <message> - <source>Pay transaction &fee</source> - <translation>&Mokėti sandorio mokestį</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>Automatiškai paleisti Bitkoin programą įjungus sistemą.</translation> </message> @@ -618,6 +786,10 @@ Adresas: %4</translation> <translation>numatyta</translation> </message> <message> + <source>none</source> + <translation>niekas</translation> + </message> + <message> <source>The supplied proxy address is invalid.</source> <translation>Nurodytas tarpinio serverio adresas negalioja.</translation> </message> @@ -629,10 +801,6 @@ Adresas: %4</translation> <translation>Forma</translation> </message> <message> - <source>Wallet</source> - <translation>Piniginė</translation> - </message> - <message> <source>Immature:</source> <translation>Nepribrendę:</translation> </message> @@ -645,10 +813,6 @@ Adresas: %4</translation> <translation>Jūsų balansas</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Naujausi sandoriai</b></translation> - </message> - <message> <source>out of sync</source> <translation>nesinchronizuota</translation> </message> @@ -860,10 +1024,34 @@ Adresas: %4</translation> <translation>Siųsti monetas</translation> </message> <message> + <source>Quantity:</source> + <translation>Kiekis:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Baitai:</translation> + </message> + <message> <source>Amount:</source> <translation>Suma:</translation> </message> <message> + <source>Priority:</source> + <translation>Pirmumas:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Mokestis:</translation> + </message> + <message> + <source>After Fee:</source> + <translation>Po mokesčio:</translation> + </message> + <message> + <source>Change:</source> + <translation>Graža:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Siųsti keliems gavėjams vienu metu</translation> </message> @@ -892,10 +1080,30 @@ Adresas: %4</translation> <translation>Patvirtinti monetų siuntimą</translation> </message> <message> + <source>Copy quantity</source> + <translation>Kopijuoti kiekį</translation> + </message> + <message> <source>Copy amount</source> <translation>Kopijuoti sumą</translation> </message> <message> + <source>Copy fee</source> + <translation>Kopijuoti mokestį</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Kopijuoti po mokesčio</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Kopijuoti baitus</translation> + </message> + <message> + <source>Copy priority</source> + <translation>Kopijuoti pirmumą</translation> + </message> + <message> <source>The recipient address is not valid, please recheck.</source> <translation>Negaliojantis gavėjo adresas. Patikrinkite.</translation> </message> @@ -1339,6 +1547,10 @@ Adresas: %4</translation> <translation>Rodyti sandėrio detales</translation> </message> <message> + <source>Exporting Failed</source> + <translation>Eksportavimas nepavyko</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Kableliais atskirtų duomenų failas (*.csv)</translation> </message> @@ -1418,42 +1630,14 @@ Adresas: %4</translation> <translation>Parinktys:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Nurodyti konfigūracijos failą (pagal nutylėjimąt: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Nurodyti pid failą (pagal nutylėjimą: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Nustatyti duomenų aplanką</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Sujungimo klausymas prijungčiai <port> (pagal nutylėjimą: 8333 arba testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Palaikyti ne daugiau <n> jungčių kolegoms (pagal nutylėjimą: 125)</translation> - </message> - <message> <source>Specify your own public address</source> <translation>Nurodykite savo nuosavą viešą adresą</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Atjungimo dėl netinkamo kolegų elgesio riba (pagal nutylėjimą: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Sekundžių kiekis eikiamas palaikyti ryšį dėl lygiarangių nestabilumo (pagal nutylėjimą: 86.400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Klausymas JSON-RPC sujungimui prijungčiai <port> (pagal nutylėjimą: 8332 or testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Priimti komandinę eilutę ir JSON-RPC komandas</translation> </message> @@ -1478,30 +1662,6 @@ Adresas: %4</translation> <translation>Klaida atveriant blokų duombazę</translation> </message> <message> - <source>Error: system error: </source> - <translation>Klaida: sistemos klaida:</translation> - </message> - <message> - <source>Failed to read block info</source> - <translation>Nepavyko nuskaityti bloko informacijos</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Nepavyko nuskaityti bloko</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Nepavyko įrašyti bloko</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Nepavyko įrašyti failo informacijos</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Generuoti monetas (numatyta: 0)</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>Tikrinami blokai...</translation> </message> @@ -1514,30 +1674,10 @@ Adresas: %4</translation> <translation>Informacija</translation> </message> <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maksimalus buferis priėmimo sujungimui <n>*1000 bitų (pagal nutylėjimą: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maksimalus buferis siuntimo sujungimui <n>*1000 bitų (pagal nutylėjimą: 1000)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Siųsti atsekimo/derinimo info į konsolę vietoj debug.log failo</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Nustatyti sujungimo trukmę milisekundėmis (pagal nutylėjimą: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Sistemos klaida:</translation> - </message> - <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Bandymas naudoti UPnP struktūra klausymosi prievadui (default: 0)</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> @@ -1558,10 +1698,6 @@ Adresas: %4</translation> <translation>Atnaujinti piniginę į naujausią formatą</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Nustatyti rakto apimties dydį <n> (pagal nutylėjimą: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Ieškoti prarastų piniginės sandorių blokų grandinėje</translation> </message> @@ -1570,14 +1706,6 @@ Adresas: %4</translation> <translation>Naudoti OpenSSL (https) jungimuisi JSON-RPC </translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Serverio sertifikato failas (pagal nutylėjimą: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Serverio privatus raktas (pagal nutylėjimą: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Pagelbos žinutė</translation> </message> diff --git a/src/qt/locale/bitcoin_lv_LV.ts b/src/qt/locale/bitcoin_lv_LV.ts index 81b2688d03..ac5a1a1396 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> @@ -275,6 +275,10 @@ <translation>Atvērt &URI...</translation> </message> <message> + <source>Bitcoin Core client</source> + <translation>Bitcoin Core klients</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>Importē blokus no diska...</translation> </message> @@ -324,7 +328,11 @@ </message> <message> <source>&Receive</source> - <translation>Saņe&mt</translation> + <translation>&Saņemt</translation> + </message> + <message> + <source>Show information about Bitcoin Core</source> + <translation>Parādīt informāciju par Bitcoin Core</translation> </message> <message> <source>&Show / Hide</source> @@ -363,10 +371,6 @@ <translation>Ciļņu rīkjosla</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -394,10 +398,6 @@ <source>No block source available...</source> <translation>Nav pieejams neviens bloku avots...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Apstrādāti %1 bloki no transakciju vēstures.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n stundas</numerusform><numerusform>%n stunda</numerusform><numerusform>%n stundas</numerusform></translation> @@ -485,10 +485,6 @@ Adrese: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Bitcoin Kontroles Adrešu Atlase</translation> - </message> - <message> <source>Quantity:</source> <translation>Daudzums:</translation> </message> @@ -533,10 +529,6 @@ Adrese: %4 <translation>Daudzums</translation> </message> <message> - <source>Address</source> - <translation>Adrese</translation> - </message> - <message> <source>Date</source> <translation>Datums</translation> </message> @@ -800,15 +792,7 @@ Adrese: %4 <source>Error</source> <translation>Kļūda</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB ar brīvo vietu pieejams</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(no %1GB nepieciešams)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -843,10 +827,6 @@ Adrese: %4 <translation>&Galvenais</translation> </message> <message> - <source>Pay transaction &fee</source> - <translation>&Maksāt par transakciju</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> @@ -867,14 +847,6 @@ Adrese: %4 <translation>Skriptu &pārbaudes pavedienu skaits</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Savienoties ar Bitcoin tīklu caur SOCKS starpniekserveri.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Savienoties caur SOCKS starpniekserveri (noklusējuma starpniekserveris)</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>Starpniekservera IP adrese (piem. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1018,10 +990,6 @@ Adrese: %4 <translation>Attēlotā informācija var būt novecojusi. Jūsu maciņš pēc savienojuma izveides automātiski sinhronizējas ar Bitcoin tīklu, taču šis process vēl nav beidzies.</translation> </message> <message> - <source>Wallet</source> - <translation>Maciņš</translation> - </message> - <message> <source>Available:</source> <translation>Pieejams:</translation> </message> @@ -1050,10 +1018,6 @@ Adrese: %4 <translation>Jūsu kopējā tekošā bilance</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Pēdējās transakcijas</b></translation> - </message> - <message> <source>out of sync</source> <translation>nav sinhronizēts</translation> </message> @@ -2211,26 +2175,10 @@ Adrese: %4 <translation>Iespējas:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Norādiet konfigurācijas failu (pēc noklusēšanas: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Norādiet pid failu (pēc noklusēšanas: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Norādiet datu direktoriju</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Gaidīt savienojumus portā <port> (pēc noklusēšanas: 8333 vai testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Uzturēt līdz <n> savienojumiem ar citiem mezgliem(pēc noklusēšanas: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Pievienoties mezglam, lai iegūtu citu mezglu adreses, un atvienoties</translation> </message> @@ -2239,14 +2187,6 @@ Adrese: %4 <translation>Norādiet savu publisko adresi</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Slieksnis pārkāpējmezglu atvienošanai (pēc noklusēšanas: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Sekundes, cik ilgi atturēt pārkāpējmezglus no atkārtotas pievienošanās (pēc noklusēšanas: 86400)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Pieņemt komandrindas un JSON-RPC komandas</translation> </message> @@ -2263,10 +2203,6 @@ Adrese: %4 <translation>(noklusējums: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(noklusējums: wallet.dat)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> var būt:</translation> </message> @@ -2303,14 +2239,6 @@ Adrese: %4 <translation>Kļūda: Maciņš ir aizslēgts, nevar izveidot transakciju!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Kļūda: sistēmas kļūda:</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Piespiest drošo režīmu (noklusējums: 0)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Ja <category> nav norādīta, izvadīt visu atkļūdošanas informāciju.</translation> </message> @@ -2319,10 +2247,6 @@ Adrese: %4 <translation>Importē...</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Tērēt neapstiprinātu atlikumu kad sūta transakcijas (noklusējums: 1)</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>Pārbauda blokus...</translation> </message> @@ -2355,10 +2279,6 @@ Adrese: %4 <translation>Transakcijas parakstīšana neizdevās</translation> </message> <message> - <source>System error: </source> - <translation>Sistēmas kļūda:</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Transakcijas summa ir pārāk maza</translation> </message> @@ -2403,10 +2323,6 @@ Adrese: %4 <translation>Atjaunot maciņa formātu uz jaunāko</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Uzstādīt atslēgu bufera izmēru uz <n> (pēc noklusēšanas: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Atkārtoti skanēt bloku virkni, meklējot trūkstošās maciņa transakcijas</translation> </message> @@ -2415,14 +2331,6 @@ Adrese: %4 <translation>JSON-RPC savienojumiem izmantot OpenSSL (https)</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Servera sertifikāta fails (pēc noklusēšanas: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Servera privātā atslēga (pēc noklusēšanas: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Šis palīdzības paziņojums</translation> </message> diff --git a/src/qt/locale/bitcoin_mn.ts b/src/qt/locale/bitcoin_mn.ts index 4a296dfce7..f1b0174111 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> @@ -288,10 +288,6 @@ Address: %4 <translation>Хэмжээ</translation> </message> <message> - <source>Address</source> - <translation>Хаяг</translation> - </message> - <message> <source>Date</source> <translation>Огноо</translation> </message> @@ -402,10 +398,6 @@ Address: %4 <translation>МБ</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Биткойны сүлжээрүү SOCKS проксигоор холбогдох.</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> @@ -425,17 +417,9 @@ Address: %4 <context> <name>OverviewPage</name> <message> - <source>Wallet</source> - <translation>Түрүйвч</translation> - </message> - <message> <source>Available:</source> <translation>Хэрэглэж болох хэмжээ:</translation> </message> - <message> - <source><b>Recent transactions</b></source> - <translation><b>Сүүлд хийгдсэн гүйлгээнүүд</b></translation> - </message> </context> <context> <name>PaymentServer</name> @@ -1030,10 +1014,6 @@ Address: %4 <translation>Сонголтууд:</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation><port> дээрх холболтуудыг чагна (ѳгѳгдмѳл: 8333 эсвэл testnet: 18333)</translation> - </message> - <message> <source>Wallet options:</source> <translation>Түрүйвчийн сонголтууд:</translation> </message> diff --git a/src/qt/locale/bitcoin_ms_MY.ts b/src/qt/locale/bitcoin_ms_MY.ts index 428819e92f..d2e8efbb49 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> @@ -10,14 +10,42 @@ <translation>Cipta alamat baru</translation> </message> <message> + <source>&New</source> + <translation>&Baru</translation> + </message> + <message> <source>Copy the currently selected address to the system clipboard</source> <translation>Salin alamat terpilih ke dalam sistem papan klip</translation> </message> <message> + <source>&Copy</source> + <translation>&Salin</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>&Salin Alamat</translation> + </message> + <message> + <source>&Export</source> + <translation>&Eksport</translation> + </message> + <message> <source>&Delete</source> <translation>&Padam</translation> </message> <message> + <source>Choose the address to send coins to</source> + <translation>Pilih alamat untuk menghantar syiling</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>Pilih alamat untuk menerima syiling</translation> + </message> + <message> + <source>C&hoose</source> + <translation>&Pilih</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Fail yang dipisahkan dengan koma</translation> </message> @@ -44,10 +72,6 @@ </context> <context> <name>CoinControlDialog</name> - <message> - <source>Address</source> - <translation>Alamat</translation> - </message> </context> <context> <name>EditAddressDialog</name> @@ -163,6 +187,10 @@ </context> <context> <name>WalletView</name> + <message> + <source>&Export</source> + <translation>&Eksport</translation> + </message> </context> <context> <name>bitcoin-core</name> diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index bb6b78849c..bdde3da534 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> @@ -391,10 +391,6 @@ <translation>Verktøylinje for faner</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnett]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -434,10 +430,6 @@ <source>No block source available...</source> <translation>Ingen kilde for blokker tilgjengelig...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Lastet %1 blokker med transaksjonshistorikk.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n time</numerusform><numerusform>%n timer</numerusform></translation> @@ -486,6 +478,10 @@ <source>Up to date</source> <translation>Ajour</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>Kommer ajour...</translation> @@ -529,8 +525,8 @@ Adresse: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Myntkontroll Adresse Valg</translation> + <source>Coin Selection</source> + <translation>Mynt Valg</translation> </message> <message> <source>Quantity:</source> @@ -581,8 +577,12 @@ Adresse: %4 <translation>Beløp</translation> </message> <message> - <source>Address</source> - <translation>Adresse</translation> + <source>Received with label</source> + <translation>Mottatt med merkelapp</translation> + </message> + <message> + <source>Received with address</source> + <translation>Mottatt med adresse</translation> </message> <message> <source>Date</source> @@ -916,13 +916,13 @@ Adresse: %4 <source>Error</source> <translation>Feil</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB ledig lagringsplass</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB med ledig lagringsplass</numerusform><numerusform>%n GB med ledig lagringsplass</numerusform></translation> </message> - <message> - <source>(of %1GB needed)</source> - <translation>(av %1GB behøvd)</translation> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(av %n GB som trengs)</numerusform><numerusform>(av %n GB som trengs)</numerusform></translation> </message> </context> <context> @@ -959,14 +959,6 @@ Adresse: %4 <translation>&Hoved</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Valgfritt transaksjonsgebyr per kB som sikrer at dine transaksjoner blir raskt prosessert. De fleste transaksjoner er 1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Betal &transaksjonsgebyr</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>Start Bitcoin automatisk etter innlogging.</translation> </message> @@ -995,14 +987,6 @@ Adresse: %4 <translation>Tillatt innkommende tilkoblinger</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Koble til Bitcoin-nettverket gjennom en SOCKS proxy.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Koble til gjennom SOCKS proxy (standardvalg proxy):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>IP-adressen til proxyen (f.eks. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1063,6 +1047,14 @@ Adresse: %4 <translation>Sett opp port ved hjelp av &UPnP</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Koble til Bitcoin-nettverket gjennom en SOCKS5 proxy.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Koble til gjennom SOCKS5 proxy (standardvalg proxy):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>Proxy &IP:</translation> </message> @@ -1166,10 +1158,6 @@ Adresse: %4 <translation>Informasjonen som vises kan være foreldet. Din lommebok synkroniseres automatisk med Bitcoin-nettverket etter at tilkobling er opprettet, men denne prosessen er ikke ferdig enda.</translation> </message> <message> - <source>Wallet</source> - <translation>Lommebok</translation> - </message> - <message> <source>Watch-only:</source> <translation>Kun observerbar:</translation> </message> @@ -1198,6 +1186,10 @@ Adresse: %4 <translation>Minet saldo har ikke modnet enda</translation> </message> <message> + <source>Balances</source> + <translation>Saldoer</translation> + </message> + <message> <source>Total:</source> <translation>Totalt:</translation> </message> @@ -1210,6 +1202,14 @@ Adresse: %4 <translation>Din nåværende balanse i kun observerbare adresser</translation> </message> <message> + <source>Spendable:</source> + <translation>Kan brukes:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Nylige transaksjoner</translation> + </message> + <message> <source>Unconfirmed transactions to watch-only addresses</source> <translation>Ubekreftede transaksjoner til kun observerbare adresser</translation> </message> @@ -1222,10 +1222,6 @@ Adresse: %4 <translation>Nåværende totale balanse i kun observerbare adresser</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Siste transaksjoner</b></translation> - </message> - <message> <source>out of sync</source> <translation>ute av synk</translation> </message> @@ -1485,10 +1481,6 @@ Adresse: %4 <translation>Tjenester</translation> </message> <message> - <source>Sync Node</source> - <translation>Synk-node</translation> - </message> - <message> <source>Starting Height</source> <translation>Starthøyde</translation> </message> @@ -1617,14 +1609,6 @@ Adresse: %4 <translation>Utgående</translation> </message> <message> - <source>Yes</source> - <translation>Ja</translation> - </message> - <message> - <source>No</source> - <translation>Nei</translation> - </message> - <message> <source>Unknown</source> <translation>Ukjent</translation> </message> @@ -1861,6 +1845,78 @@ Adresse: %4 <translation>Egendefinert adresse for veksel</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Transaksjonsgebyr:</translation> + </message> + <message> + <source>Choose...</source> + <translation>Velg...</translation> + </message> + <message> + <source>collapse fee-settings</source> + <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> + <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>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>total at least</source> + <translation>minstebeløp</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>Betaling av bare minimumsavgiften går helt fint så lenge det er mindre transaksjonsvolum enn plass i blokkene. Men vær klar over at dette kan ende opp i en transaksjon som aldri blir bekreftet når det er mer etterspørsel etter Bitcoin-transaksjoner enn nettverket kan behandle.</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(les verktøytipset)</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Anbefalt:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Egendefinert:</translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation>(Smartgebyr ikke innført ennå. Dette tar vanligvis noen blokker...)</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Bekreftelsestid:</translation> + </message> + <message> + <source>normal</source> + <translation>normal</translation> + </message> + <message> + <source>fast</source> + <translation>rask</translation> + </message> + <message> + <source>Send as zero-fee transaction if possible</source> + <translation>Send uten transaksjonsgebyr hvis mulig</translation> + </message> + <message> + <source>(confirmation may take longer)</source> + <translation>(bekreftelse kan ta lengre tid)</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Send til flere enn en mottaker</translation> </message> @@ -1965,6 +2021,18 @@ 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> + </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> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Advarsel: Ugyldig Bitcoin-adresse</translation> </message> @@ -2473,6 +2541,10 @@ Adresse: %4 <translation>Utvunnet</translation> </message> <message> + <source>watch-only</source> + <translation>kun observerbar</translation> + </message> + <message> <source>(n/a)</source> <translation>-</translation> </message> @@ -2489,6 +2561,10 @@ Adresse: %4 <translation>Type transaksjon.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <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> </message> @@ -2584,6 +2660,10 @@ Adresse: %4 <translation>Eksporter Transaksjonshistorikk</translation> </message> <message> + <source>Watch-only</source> + <translation>Kun observer</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Ekport Feilet</translation> </message> @@ -2699,26 +2779,10 @@ Adresse: %4 <translation>Innstillinger:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Angi konfigurasjonsfil (standardverdi: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Angi pid-fil (standardverdi: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Angi mappe for datafiler</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Lytt etter tilkoblinger på <port> (standardverdi: 8333 eller testnett: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Hold maks <n> koblinger åpne til andre noder (standardverdi: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Koble til node for å hente adresser til andre noder, koble så fra igjen</translation> </message> @@ -2727,18 +2791,6 @@ Adresse: %4 <translation>Angi din egen offentlige adresse</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Grenseverdi for å koble fra noder med dårlig oppførsel (standardverdi: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Antall sekunder noder med dårlig oppførsel hindres fra å koble til på nytt (standardverdi: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Lytt etter JSON-RPC tilkoblinger på <port> (standardverdi: 8332 eller testnett: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Ta imot kommandolinje- og JSON-RPC-kommandoer</translation> </message> @@ -2778,22 +2830,18 @@ Det er også anbefalt at å sette varselsmelding slik du får melding om problem For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Akseptable krypteringsmetoder (standardverdi: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Bind til angitt adresse. Bruk [vertsmaskin]:port notasjon for IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Ratebegrens gratistransaksjoner kontinuerlig til <n>*1000 bytes per minutt (standard: 15)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Slett alle transaksjoner i lommeboken og gjenopprett kun de delene av blokkjeden gjennom -rescan ved oppstart</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>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> @@ -2810,14 +2858,6 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Kjør kommando når en lommeboktransaksjon endres (%s i kommando er erstattet med TxID)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Overfør aktiviteten i databasen fra minnelageret til loggen på harddisken for hver <n> megabytes (standardverdi: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Hvor grundig blokkverifiseringen til -checkblocks er (0-4, standard: 3)</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> </message> @@ -2826,10 +2866,6 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Angi antall tråder for skriptverifisering (%u til %d, 0 = auto, <0 = la det antallet kjerner være ledig, standard: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Sett prosessorgrensen for når blokkutvinning er på (-1 = ubegrenset, standard: -1)</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>Dette er en forhåndssluppet testversjon - bruk på egen risiko - ikke for bruk til blokkutvinning eller bedriftsapplikasjoner</translation> </message> @@ -2838,10 +2874,6 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Ute av stand til å binde til %s på denne datamaskinen. Bitcoin Core kjører sannsynligvis allerede.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Bruk separate SOCKS5 proxyer for å nå noder via Tor skjulte tjenester (standardverdi: -proxy)</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> @@ -2862,12 +2894,12 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Advarsel: wallet.dat korrupt, data reddet! Original wallet.dat lagret som wallet.{timestamp}.bak i %s; hvis din saldo eller dine transaksjoner ikke er korrekte bør du gjenopprette fra en backup.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(standardverdi: 1)</translation> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Hvitelist noder som kobler til fra den oppgitte nettmasken eller IP-adressen. Kan oppgis flere ganger.</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(standardverdi: wallet.dat)</translation> + <source>(default: 1)</source> + <translation>(standardverdi: 1)</translation> </message> <message> <source><category> can be:</source> @@ -2898,10 +2930,6 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Valg for feilsøking/testing:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Slå av sikkerhetsmodus, overstyr en virkelig sikkerhetsmodushendelse (standard: 0)</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> @@ -2930,6 +2958,10 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Feil under åpning av blokkdatabase</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Feil: En fatal intern feil oppstod, se debug.log for detaljer</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Feil: Lite ledig lagringsplass!</translation> </message> @@ -2938,66 +2970,10 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Feil: Lommebok låst, kan ikke opprette transaksjon!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Feil: systemfeil:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Kunne ikke lytte på noen port. Bruk -listen=0 hvis det er dette du vil.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Feil ved lesing av blokkinfo</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Feil ved lesing av blokk</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Feil ved synkronisering av blokkindeks</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Ved feil skriving av blokkindeks</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Feil ved skriving av blokkinfo</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Feil ved skriving av blokk</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Feil ved skriving av filinfo</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Feil ved skriving til bitcoin sin database</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Feil ved skriving av transaksjonsindeks</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Feil ved skriving av angredata</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Tving sikkerhetsmodus (standard: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Generer bitcoins (standardverdi: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Hvor mange blokker skal sjekkes ved oppstart (standardverdi: 288, 0 = alle)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Hvis <category> ikke er oppgitt, ta ut all informasjon om feilsøking.</translation> </message> @@ -3018,8 +2994,8 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>For få fildeskriptorer tilgjengelig.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Sett inn tidsstempel i front av feilsøkingsdata (standardverdi: 1)</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <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> @@ -3034,26 +3010,18 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Sett maks blokkstørrelse i bytes (standardverdi: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Sett nummer av tråder til betjening av RPC-kall (standardverdi: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Angi lommebokfil (inne i datamappe)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Bruk ubekreftet veksel ved sending av transaksjoner (standardverdi: 1)</translation> - </message> - <message> - <source>Stop running after importing blocks from disk (default: 0)</source> - <translation>Avslutt etter import av blokker fra disk (standard: 0)</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> + <message> <source>Verifying blocks...</source> <translation>Verifiserer blokker...</translation> </message> @@ -3078,10 +3046,6 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Importerer blokker fra ekstern fil blk000??.dat</translation> </message> <message> - <source>(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> - <translation>(standardverdi: 1, 1 = behold metadata for transaksjon som f. eks. kontoeier og informasjon om betalingsanmodning, 2 = dropp metadata for transaksjon)</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>Tillat JSON-RPC-tilkoblinger fra angitt kilde. Gyldig for <ip> er en enkelt IP (f. eks. 1.2.3.4), et nettverk/nettmaske (f. eks. 1.2.3.4/255.255.255.0) eller et nettverk/CIDR (f. eks. 1.2.3.4/24). Dette alternativet kan angis flere ganger</translation> </message> @@ -3102,12 +3066,12 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Ute av stand til å låse datamappen %s. Bitcoin Core kjører sannsynligvis allerede.</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> + <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>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> - <translation>Distribuert under MIT/X11 programvarelisensen, se medfølgende fil COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation> + <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>Error: Listening for incoming connections failed (listen returned error %s)</source> @@ -3118,10 +3082,6 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Feil: Argumentet -socks er ikke støttet. Det er ikke lenger mulig å sette SOCKS-versjon; bare SOCKS5-proxyer er støttet.</translation> </message> <message> - <source>Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)</source> - <translation>Utfør kommando når et nettverkstransaksjon gjenbruker inndata fra lommeboktransaksjonen (%s=gjenbruk TxID, %t=lommebok TxID)</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>Utfør kommando når et relevant varsel er mottatt eller vi ser en veldig lang gaffel (%s i kommando er erstattet med melding)</translation> </message> @@ -3134,12 +3094,8 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <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 are confirmed on average within n blocks (default: 1)</source> - <translation>Hvis paytxfee ikke er angitt, inkluderer da nok gebyr til at transaksjoner gjennomsnittligt bekreftes innen n blokker (standardverdi: 1)</translation> - </message> - <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Ta ut feilsøkingsinformasjon (standardverdi: 0, bruk av <category> er valgfritt)</translation> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>Maksimal størrelse på data i databærende transaksjoner vi videresender og ufører graving på (standardverdi: %u)</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> @@ -3150,6 +3106,10 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Sett maksimum størrelse for transaksjoner med høy prioritet / lavt gebyr, i bytes (standardverdi: %d)</translation> </message> <message> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <translation>Angi antall tråder for mynt generering hvis aktivert (-1 = alle kjerner, standardverdi: %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>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> @@ -3158,18 +3118,10 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Advarsel: Vennligst undersøk at din datamaskin har riktig dato og klokkeslett! Hvis klokken er stilt feil vil ikke Bitcoin Core fungere riktig.</translation> </message> <message> - <source>Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.</source> - <translation>Hvitelist noder som kobler til fra den oppgitte nettmasken eller IP-adressen. Kan oppgis flere ganger.</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>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>Always query for peer addresses via DNS lookup (default: 0)</source> - <translation>Alltid søk etter nodeadresser via DNS-oppslag (standardverdi: 0)</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Kan ikke løse -whitebind-adresse: '%s'</translation> </message> @@ -3198,10 +3150,6 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Gebyr (i BTC/kB) for å legge til i transaksjoner du sender (standardverdi: %s)</translation> </message> <message> - <source>Include IP addresses in debug output (default: 0)</source> - <translation>Inkludere IP-adresser i feilsøkingslogg (standard: 0)</translation> - </message> - <message> <source>Information</source> <translation>Informasjon</translation> </message> @@ -3230,24 +3178,8 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Behold på det meste <n> blokker i minnet som ikke er mulig å koble (standardverdi: %u)</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Begrens størrelsen på signatur-hurtigbufferen til <n> oppføringer (standard: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Logg transaksjonsprioritet og gebyr per kB under blokkutvinning (standard: 0)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Oppretthold en full transaksjonsindeks (standard: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maks mottaksbuffer per forbindelse, <n>*1000 bytes (standardverdi: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maks sendebuffer per forbindelse, <n>*1000 bytes (standardverdi: 1000)</translation> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Hold på det meste <n> transaksjoner som ikke kobles i minnet (standardverdi: %u)</translation> </message> <message> <source>Need to specify a port with -whitebind: '%s'</source> @@ -3258,22 +3190,10 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Node alternativer for videresending:</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Aksepter kun en blokkjede som passer med innebygde sjekkpunkter (standardvalg: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Koble kun til noder i nettverket <nett> (IPv4, IPv6 eller Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>Skriv ut blokken ved oppstart, hvis funnet i blokkindeksen</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Skriv ut blokktreet ved oppstart (standardverdi: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>RPC SSL-valg: (se Bitcoin Wiki for oppsettsinstruksjoner for SSL)</translation> </message> @@ -3290,28 +3210,12 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Slumpvis bland 1 av hver <n> nettverksmeldinger</translation> </message> <message> - <source>Relay and mine data carrier transactions (default: 1)</source> - <translation>Videresend og ufør graving av databærende transaksjoner (standardverdi: 1)</translation> - </message> - <message> - <source>Relay non-P2SH multisig (default: 1)</source> - <translation>Videresende ikke-P2SH multisig (standard: 1)</translation> - </message> - <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Kjør en tråd som skriver lommeboken til disk periodisk (standard: 1)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Send spor-/feilsøkingsinformasjon til konsollen istedenfor filen debug.log</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Sett minimum blokkstørrelse i bytes (standardverdi: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Setter flagget DB_PRIVATE i miljøet til lommebokdatabasen (standard: 1)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Send transaksjoner uten transaksjonsgebyr hvis mulig (standardverdi: %u)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> @@ -3326,14 +3230,6 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Signering av transaksjon feilet</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Angi tidsavbrudd for forbindelse i millisekunder (standardverdi: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Systemfeil:</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Dette er eksperimentell programvare.</translation> </message> @@ -3354,10 +3250,6 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Kan ikke binde til %s på denne datamaskinen (binding returnerte feilen %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Bruk UPnP for lytteport (standardverdi: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Bruk UPnP for lytteport (standardverdi: 1 ved lytting)</translation> </message> @@ -3410,10 +3302,6 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Oppgrader lommebok til nyeste format</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Angi størrelsen på nøkkellageret til <n> (standardverdi: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Se gjennom blokkjeden etter manglende lommeboktransaksjoner</translation> </message> @@ -3422,14 +3310,6 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Bruk OpenSSL (https) for JSON-RPC forbindelser</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Servers sertifikat (standardverdi: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Servers private nøkkel (standardverdi: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Denne hjelpemeldingen</translation> </message> @@ -3446,14 +3326,178 @@ For eksempel: varselmelding=echo %%s | mail -s "Bitcoin Varsel" admin@foo.com</t <translation>Feil ved lasting av wallet.dat: Lommeboken er skadet</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 = 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>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source> + <translation>Hvis paytxfee ikke er angitt, inkluderer da nok gebyr til at transaksjoner gjennomsnittligt bekreftes innen n blokker (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> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Antall sekunder noder med dårlig oppførsel hindres fra å koble til på nytt (standardverdi: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Ta ut feilsøkingsinformasjon (standardverdi: %u, bruk av <category> er valgfritt)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Bruk separate SOCKS5 proxyer for å nå noder via Tor skjulte tjenester (standardverdi: %s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(standardverdi: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Akseptable sifre (standardverdi: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <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> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Hvor mange blokker skal sjekkes ved oppstart (standardverdi: %u, 0 = alle)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Inkludere IP-adresser i feilsøkingslogg (standardverdi: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <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> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Lytt etter tilkoblinger på <port> (standardverdi: %u eller testnett: %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Hold maks <n> koblinger åpne til andre noder (standardverdi: %u)</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> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <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> + <message> + <source>Print block tree on startup (default: %u)</source> + <translation>Skriv ut blokktreet ved oppstart (standardverdi: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Videresend og ufør graving av databærende transaksjoner (standardverdi: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <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> + <message> + <source>Server private key (default: %s)</source> + <translation>Privat nøkkel for tjener (standardverdi: %s) </translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Angi størrelse på nøkkel-lager til <n> (standardverdi: %u)</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Sett minimum blokkstørrelse i bytes (standardverdi: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <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> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Angi tidsavbrudd for forbindelse i millisekunder (minimum: 1, standardverdi: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Angi pid-fil (standardverdi: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <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> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Ukjent nettverk angitt i -onlynet '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 0a9c6e2efa..258c7f109f 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -1,9 +1,9 @@ -<TS language="nl" version="2.1"> +<TS language="nl" version="2.0"> <context> <name>AddressBookPage</name> <message> <source>Double-click to edit address or label</source> - <translation>Dubbelklik om adres of label te wijzigen</translation> + <translation>Dubbelklik om het adres of label te wijzigen</translation> </message> <message> <source>Create a new address</source> @@ -59,7 +59,7 @@ </message> <message> <source>Sending addresses</source> - <translation>Bezig met versturen adressen</translation> + <translation>Bezig met het versturen van de adressen</translation> </message> <message> <source>Receiving addresses</source> @@ -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>Dit zijn uw Bitcoinadressen om betalingen mee te verzenden. Check altijd het bedrag en het ontvangende adres voordat u uw bitcoins verzendt.</translation> + <translation>Dit zijn uw Bitcoinadressen om betalingen mee te verzenden. Controleer altijd het bedrag en het ontvangende adres voordat u uw bitcoins verzendt.</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> @@ -184,6 +184,10 @@ <translation>Portemonnee versleuteld</translation> </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>Vul een nieuw </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. Onthoud dat het versleutelen van uw portemonnee u niet volledig kan beschermen: Malware kan uw computer infecteren en uw bitcoins stelen.</translation> </message> @@ -291,6 +295,10 @@ <translation>Open &URI...</translation> </message> <message> + <source>Bitcoin Core client</source> + <translation>Bitcoin kern applicatie</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>Blokken aan het importeren vanaf harde schijf...</translation> </message> @@ -343,6 +351,10 @@ <translation>&Ontvangen</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>Toon informatie over bitcoin kern</translation> + </message> + <message> <source>&Show / Hide</source> <translation>&Toon / Verberg</translation> </message> @@ -379,10 +391,6 @@ <translation>Tab-werkbalk</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnetwerk]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Kern</translation> </message> @@ -422,10 +430,6 @@ <source>No block source available...</source> <translation>Geen bron van blokken beschikbaar...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>%1 blokken van transactiehistorie verwerkt.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n uur</numerusform><numerusform>%n uur</numerusform></translation> @@ -474,6 +478,10 @@ <source>Up to date</source> <translation>Bijgewerkt</translation> </message> + <message numerus="yes"> + <source>Processed %n blocks of transaction history.</source> + <translation><numerusform>%n Blok verwerkt van transactie geschiedenis.</numerusform><numerusform>%n Blokken verwerkt van transactie geschiedenis.</numerusform></translation> + </message> <message> <source>Catching up...</source> <translation>Aan het bijwerken...</translation> @@ -517,8 +525,8 @@ Adres: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Coin controle adres selectie</translation> + <source>Coin Selection</source> + <translation>Munt Selectie</translation> </message> <message> <source>Quantity:</source> @@ -541,6 +549,10 @@ Adres: %4 <translation>Vergoeding:</translation> </message> <message> + <source>Dust:</source> + <translation>Stof:</translation> + </message> + <message> <source>After Fee:</source> <translation>Na vergoeding:</translation> </message> @@ -565,8 +577,12 @@ Adres: %4 <translation>Bedrag</translation> </message> <message> - <source>Address</source> - <translation>Adres</translation> + <source>Received with label</source> + <translation>Ontvangen met label</translation> + </message> + <message> + <source>Received with address</source> + <translation>Ontvangen met adres</translation> </message> <message> <source>Date</source> @@ -629,6 +645,10 @@ Adres: %4 <translation>Kopieer prioriteit</translation> </message> <message> + <source>Copy dust</source> + <translation>Kopieër stof</translation> + </message> + <message> <source>Copy change</source> <translation>Kopieer wisselgeld</translation> </message> @@ -677,6 +697,10 @@ Adres: %4 <translation>geen</translation> </message> <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>Kan per input +/- %1 satoshi(s) variëren.</translation> + </message> + <message> <source>yes</source> <translation>ja</translation> </message> @@ -885,16 +909,20 @@ Adres: %4 <translation>Bitcoin Kern</translation> </message> <message> + <source>Error: Specified data directory "%1" cannot be created.</source> + <translation>Fout: De gespecificeerde directory "%1" kan niet worden gecreëerd.</translation> + </message> + <message> <source>Error</source> <translation>Fout</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB aan vrije opslagruimte beschikbaar</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB aan vrije oplsagruimte beschikbaar</numerusform><numerusform>%n GB aan vrije oplsagruimte beschikbaar</numerusform></translation> </message> - <message> - <source>(of %1GB needed)</source> - <translation>(van %1GB benodigd)</translation> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(van %n GB nodig)</numerusform><numerusform>(van %n GB nodig)</numerusform></translation> </message> </context> <context> @@ -931,14 +959,6 @@ Adres: %4 <translation>&Algemeen</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Optionele transactiekosten per kB. Transactiekosten helpen ervoor te zorgen dat uw transacties snel verwerkt worden. De meeste transacties zijn 1kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Betaal &transactiekosten</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> @@ -959,12 +979,12 @@ Adres: %4 <translation>Aantal threads voor &scriptverificatie</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Verbind met het Bitcoin-netwerk via een SOCKS-proxy.</translation> + <source>Accept connections from outside</source> + <translation>Accepteer binnenkomende verbindingen</translation> </message> <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Verbind via een SOCKS-proxy (standaardproxy):</translation> + <source>Allow incoming connections</source> + <translation>Sta inkomende verbindingen toe</translation> </message> <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> @@ -1027,6 +1047,14 @@ Adres: %4 <translation>Portmapping via &UPnP</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Verbind met het Bitcoin netwerk via een SOCKS5 proxy.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Verbind via een SOCKS5-proxy (standaardproxy):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>Proxy &IP:</translation> </message> @@ -1130,8 +1158,8 @@ Adres: %4 <translation>De weergegeven informatie kan verouderd zijn. Uw portemonnee synchroniseert automaticsh met het Bitcoinnetwerk nadat een verbinding is gelegd, maar dit proces is nog niet voltooid.</translation> </message> <message> - <source>Wallet</source> - <translation>Portemonnee</translation> + <source>Watch-only:</source> + <translation>Alleen-bekijkbaar:</translation> </message> <message> <source>Available:</source> @@ -1158,6 +1186,10 @@ Adres: %4 <translation>Gedolven saldo dat nog niet tot wasdom is gekomen</translation> </message> <message> + <source>Balances</source> + <translation>Saldi</translation> + </message> + <message> <source>Total:</source> <translation>Totaal:</translation> </message> @@ -1166,8 +1198,28 @@ Adres: %4 <translation>Uw totale saldo</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Recente transacties</b></translation> + <source>Your current balance in watch-only addresses</source> + <translation>Uw huidige balans in alleen-bekijkbare adressen</translation> + </message> + <message> + <source>Spendable:</source> + <translation>Besteedbaar:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Recente transacties</translation> + </message> + <message> + <source>Unconfirmed transactions to watch-only addresses</source> + <translation>Onbevestigde transacties naar alleen-bekijkbare adressen</translation> + </message> + <message> + <source>Mined balance in watch-only addresses that has not yet matured</source> + <translation>Ontgonnen saldo dat nog niet tot wasdom is gekomen</translation> + </message> + <message> + <source>Current total balance in watch-only addresses</source> + <translation>Huidige balans in alleen-bekijkbare adressen.</translation> </message> <message> <source>out of sync</source> @@ -1185,6 +1237,22 @@ Adres: %4 <translation>Ongeldig betalingsadres %1</translation> </message> <message> + <source>Payment request rejected</source> + <translation>Betalingsverzoek geweigerd</translation> + </message> + <message> + <source>Payment request network doesn't match client network.</source> + <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> + <message> <source>Requested payment amount of %1 is too small (considered dust).</source> <translation>Het gevraagde betalingsbedrag van %1 is te weinig (beschouwd als stof).</translation> </message> @@ -1201,10 +1269,18 @@ Adres: %4 <translation>URL om betalingsverzoek te verkrijgen is ongeldig: %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 kan niet verwerkt worden! Dit kan het gevolg zijn van een ongeldig Bitcoin adres of misvormde URI parameters.</translation> + </message> + <message> <source>Payment request file handling</source> <translation>Betalingsverzoek bestandsafhandeling</translation> </message> <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>Betalingsverzoek-bestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoek-bestand.</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> @@ -1217,6 +1293,10 @@ Adres: %4 <translation>Fout bij communiceren met %1: %2</translation> </message> <message> + <source>Payment request cannot be parsed!</source> + <translation>Betalingsverzoek kan niet juist worden ontleed of verwerkt!</translation> + </message> + <message> <source>Bad response from server %1</source> <translation>Ongeldige respons van server %1</translation> </message> @@ -1231,7 +1311,19 @@ Adres: %4 </context> <context> <name>PeerTableModel</name> - </context> + <message> + <source>User Agent</source> + <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> +</context> <context> <name>QObject</name> <message> @@ -1239,6 +1331,14 @@ Adres: %4 <translation>Bedrag</translation> </message> <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>Voer een Bitcoin-adres in (bijv. %1)</translation> + </message> + <message> + <source>%1 d</source> + <translation>%1d</translation> + </message> + <message> <source>%1 h</source> <translation>%1 uur</translation> </message> @@ -1247,10 +1347,30 @@ Adres: %4 <translation>%1 m</translation> </message> <message> + <source>%1 s</source> + <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> + <message> <source>N/A</source> <translation>N.v.t.</translation> </message> - </context> + <message> + <source>%1 ms</source> + <translation>%1 ms</translation> + </message> +</context> <context> <name>QRImageWidget</name> <message> @@ -1301,6 +1421,10 @@ Adres: %4 <translation>Gebruikt OpenSSL versie</translation> </message> <message> + <source>Using BerkeleyDB version</source> + <translation>Gebruikt BerkeleyDB versie</translation> + </message> + <message> <source>Startup time</source> <translation>Opstarttijd</translation> </message> @@ -1325,6 +1449,74 @@ Adres: %4 <translation>Huidig aantal blokken</translation> </message> <message> + <source>Received</source> + <translation>Ontvangen</translation> + </message> + <message> + <source>Sent</source> + <translation>Verstuurd</translation> + </message> + <message> + <source>&Peers</source> + <translation>&Peers</translation> + </message> + <message> + <source>Select a peer to view detailed information.</source> + <translation>Selecteer een peer om gedetailleerde informatie te bekijken.</translation> + </message> + <message> + <source>Direction</source> + <translation>Directie</translation> + </message> + <message> + <source>Version</source> + <translation>Versie</translation> + </message> + <message> + <source>User Agent</source> + <translation>User Agent</translation> + </message> + <message> + <source>Services</source> + <translation>Services</translation> + </message> + <message> + <source>Starting Height</source> + <translation>Aanvangshoogte</translation> + </message> + <message> + <source>Sync Height</source> + <translation>Synchronisatiehoogte</translation> + </message> + <message> + <source>Ban Score</source> + <translation>Ban score</translation> + </message> + <message> + <source>Connection Time</source> + <translation>Connectie tijd</translation> + </message> + <message> + <source>Last Send</source> + <translation>Laatst verstuurd</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Laatst ontvangen</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Bytes Verzonden</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Bytes Ontvangen</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Ping Tijd</translation> + </message> + <message> <source>Last block time</source> <translation>Tijd laatste blok</translation> </message> @@ -1400,7 +1592,31 @@ Adres: %4 <source>%1 GB</source> <translation>%1 Gb</translation> </message> - </context> + <message> + <source>via %1</source> + <translation>via %1</translation> + </message> + <message> + <source>never</source> + <translation>nooit</translation> + </message> + <message> + <source>Inbound</source> + <translation>Inkomend</translation> + </message> + <message> + <source>Outbound</source> + <translation>Uitgaand</translation> + </message> + <message> + <source>Unknown</source> + <translation>Onbekend</translation> + </message> + <message> + <source>Fetching...</source> + <translation>Ophalen...</translation> + </message> +</context> <context> <name>ReceiveCoinsDialog</name> <message> @@ -1629,6 +1845,50 @@ Adres: %4 <translation>Aangepast wisselgeldadres</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Transactiekosten:</translation> + </message> + <message> + <source>Choose...</source> + <translation>Kies...</translation> + </message> + <message> + <source>Minimize</source> + <translation>Minimaliseer</translation> + </message> + <message> + <source>per kilobyte</source> + <translation>per kilobyte</translation> + </message> + <message> + <source>total at least</source> + <translation>totaal ten minste</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Aanbevolen:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Handmatig:</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Bevestigings tijd:</translation> + </message> + <message> + <source>normal</source> + <translation>normaal</translation> + </message> + <message> + <source>fast</source> + <translation>snel</translation> + </message> + <message> + <source>(confirmation may take longer)</source> + <translation>(bevestiging kan langer duren)</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Verstuur aan verschillende ontvangers ineens</translation> </message> @@ -1641,6 +1901,10 @@ Adres: %4 <translation>Wis alle velden van het formulier.</translation> </message> <message> + <source>Dust:</source> + <translation>Stof:</translation> + </message> + <message> <source>Clear &All</source> <translation>Verwijder &Alles</translation> </message> @@ -1729,6 +1993,18 @@ 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> + </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> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Waarschuwing: Ongeldig Bitcoin adres</translation> </message> @@ -1741,6 +2017,10 @@ Adres: %4 <translation>Waarschuwing: Onbekend wisselgeldadres</translation> </message> <message> + <source>Copy dust</source> + <translation>Kopieër stof</translation> + </message> + <message> <source>Are you sure you want to send?</source> <translation>Weet u zeker dat u wilt verzenden?</translation> </message> @@ -1776,6 +2056,10 @@ Adres: %4 <translation>Dit is een normale betaling.</translation> </message> <message> + <source>The Bitcoin address to send the payment to</source> + <translation>Het Bitcoin adres om betaling aan te voldoen</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1846,6 +2130,10 @@ Adres: %4 <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> </message> <message> + <source>The Bitcoin address to sign the message with</source> + <translation>Het Bitcoin adres om bericht mee te ondertekenen</translation> + </message> + <message> <source>Choose previously used address</source> <translation>Kies een eerder gebruikt adres</translation> </message> @@ -1898,6 +2186,10 @@ Adres: %4 <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> + <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>Controleer een bericht om te verifiëren dat het gespecificeerde Bitcoinadres het bericht heeft ondertekend.</translation> </message> @@ -2039,6 +2331,10 @@ Adres: %4 <translation>eigen adres</translation> </message> <message> + <source>watch-only</source> + <translation>alleen-bekijkbaar</translation> + </message> + <message> <source>label</source> <translation>label</translation> </message> @@ -2059,6 +2355,14 @@ Adres: %4 <translation>Debet</translation> </message> <message> + <source>Total debit</source> + <translation>Totaal debit</translation> + </message> + <message> + <source>Total credit</source> + <translation>Totaal credit</translation> + </message> + <message> <source>Transaction fee</source> <translation>Transactiekosten</translation> </message> @@ -2209,6 +2513,10 @@ Adres: %4 <translation>Gedolven</translation> </message> <message> + <source>watch-only</source> + <translation>alleen-bekijkbaar</translation> + </message> + <message> <source>(n/a)</source> <translation>(nvt)</translation> </message> @@ -2320,6 +2628,10 @@ Adres: %4 <translation>Exporteer Transactieverleden</translation> </message> <message> + <source>Watch-only</source> + <translation>Alleen-bekijkbaar</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Export Mislukt</translation> </message> @@ -2374,7 +2686,11 @@ Adres: %4 </context> <context> <name>UnitDisplayStatusBarControl</name> - </context> + <message> + <source>Unit to show amounts in. Click to select another unit.</source> + <translation>Eenheid om bedragen uit te drukken. Klik om een andere eenheid te selecteren.</translation> + </message> +</context> <context> <name>WalletFrame</name> <message> @@ -2431,28 +2747,10 @@ Adres: %4 <translation>Opties:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Specificeer configuratiebestand (standaard: bitcoin.conf) -</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Specificeer pid-bestand (standaard: bitcoind.pid) -</translation> - </message> - <message> <source>Specify data directory</source> <translation>Stel datamap in</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Luister voor verbindingen op <poort> (standaard: 8333 of testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Onderhoud maximaal <n> verbindingen naar peers (standaard: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Verbind naar een node om adressen van anderen op te halen, en verbreek vervolgens de verbinding</translation> </message> @@ -2461,18 +2759,6 @@ Adres: %4 <translation>Specificeer uw eigen publieke adres</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Drempel om verbinding te verbreken naar zich misdragende peers (standaard: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Aantal seconden dat zich misdragende peers niet opnieuw mogen verbinden (standaard: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Wacht op JSON-RPC-connecties op poort <port> (standaard: 8332 of testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Aanvaard commandoregel- en JSON-RPC-commando's</translation> </message> @@ -2511,18 +2797,10 @@ Het is ook aan te bevelen "alertnotify" in te stellen zodat u op de hoogte geste bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Aanvaardbare cijfers (standaard: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Bind aan opgegeven adres en luister er altijd op. Gebruik [host]:port notatie voor IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Doorlopend tarief-limiet op gratis transacties toepassen tot <n>*1000 bytes per minuut (standaard: 15)</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> @@ -2539,14 +2817,6 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Voer opdracht uit zodra een portemonneetransactie verandert (%s in cmd wordt vervangen door TxID)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Leeg database-activiteit uit de geheugenpool naar schijf log elke <n> megabytes (standaard: 100) </translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Hoe grondig de blokverificatie van -checkblocks is (0-4, standaard: 3)</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> @@ -2555,10 +2825,6 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Kies het aantal script verificatie processen (%u tot %d, 0 = auto, <0 = laat dit aantal kernen vrij, standaard: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Kies de processorlimiet wanneer generation is aan (-1 = ongelimiteerd, standaard: -1)</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>Dit is een pre-release testversie - gebruik op eigen risico! Gebruik deze niet voor het delven van munten of handelsdoeleinden</translation> </message> @@ -2567,10 +2833,6 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Niet in staat om %s te verbinden op deze computer. Bitcoin Core draait waarschijnlijk al.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Gebruik een aparte SOCKS5 proxy om 'Tor hidden services' te bereiken (standaard: hetzelfde als -proxy)</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> @@ -2595,10 +2857,6 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>(standaard: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(standaard: wallet.dat)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> kan zijn:</translation> </message> @@ -2627,10 +2885,6 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Foutopsporing/Testopties:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Veilige modus uitschakelen, hef een echte veilige modus gebeurtenis uit (default: 0)</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> @@ -2667,66 +2921,10 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Fout: Portemonnee vergrendeld, aanmaak transactie niet mogelijk!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Fout: Systeemfout:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Mislukt om op welke poort dan ook te luisteren. Gebruik -listen=0 as u dit wilt.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Lezen van blokinformatie mislukt</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Lezen van blok mislukt</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Synchroniseren van blokindex mislukt</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Schrijven van blokindex mislukt</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Schrijven van blokinformatie mislukt</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Schrijven van blok mislukt</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Schrijven van bestandsinformatie mislukt</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Schrijven naar coindatabase mislukt</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Schrijven van transactieindex mislukt</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Schrijven van undo-data mislukt</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Forceer veilige modus (default: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Genereer munten (standaard: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Aantal te checken blokken bij het opstarten (standaard: 288, 0 = allemaal)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Als er geen <category> is opgegeven, laat dan alle debugging informatie zien.</translation> </message> @@ -2747,10 +2945,6 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Niet genoeg file descriptors beschikbaar.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Prepend debug output met tijdstempel (standaard: 1)</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> @@ -2763,22 +2957,18 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Stel maximum blokgrootte in in bytes (standaard: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Stel het aantal threads in om RPC-aanvragen mee te bedienen (standaard: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Specificeer het portemonnee bestand (vanuit de gegevensmap)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Spendeer onbevestigd wisselgeld wanneer transacties verstuurd worden (standaard: 1)</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> + <message> <source>Verifying blocks...</source> <translation>Blokken aan het controleren...</translation> </message> @@ -2811,14 +3001,14 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Voer commando uit zodra een waarschuwing is ontvangen of wanneer we een erg lange fork detecteren (%s in commando wordt vervangen door bericht)</translation> </message> <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Output extra debugginginformatie (standaard: 0, het leveren van <category> is optioneel)</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> <message> + <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> + <translation>Fout bij laden wallet.dat: Portemonnee vereist een nieuwere versie van Bitcoin Core</translation> + </message> + <message> <source>Information</source> <translation>Informatie</translation> </message> @@ -2831,42 +3021,22 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Ongeldig bedrag voor -mintxfee=<bedrag>: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Limiteer grootte van de handtekening cache tot <n> entries (default: 50000)</translation> + <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> + <translation>Ongeldig bedrag voor -paytxfee=<bedrag>: '%s' (Minimum %s)</translation> </message> <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Log transactieprioriteit en vergoeding per kB bij mijnen blocks (standaard: 0)</translation> + <source>Keep at most <n> unconnectable blocks in memory (default: %u)</source> + <translation>Houd maximaal <n> onverbonden blokken in geheugen (standaard: %u)</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Onderhoud een volledige transactieindex (standaard: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maximum per-connectie ontvangstbuffer, <n>*1000 bytes (standaard: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maximum per-connectie zendbuffer, <n>*1000 bytes (standaard: 1000)</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Accepteer alleen blokketen die overeenkomt met de ingebouwde checkpoints (standaard: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Verbind alleen naar nodes in netwerk <net> (IPv4, IPv6 of Tor)</translation> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Houd maximaal <n> onverbonden transacties in geheugen (standaard: %u)</translation> </message> <message> <source>Print block on startup, if found in block index</source> <translation>Toon block bij opstarten, wanneer gevonden in block index</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Toon block structuur bij opstarten (default: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>RPC SSL opties: (zie de Bitcoin Wiki voor SSL installatie-instructies)</translation> </message> @@ -2883,22 +3053,10 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Fuzz willekeurig 1 van elke <n> netwerkberichten</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Draai een proces om de wallet periodiek te flushen (default: 1)</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> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Stel minimum blokgrootte in in bytes (standaard: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Plaatst de DB_PRIVATE vlag in de wallet db omgeving (default: 1)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Toon alle foutopsporingsopties (gebruik: --help -help-debug)</translation> </message> @@ -2911,12 +3069,8 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Ondertekenen van transactie mislukt</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Specificeer de time-outtijd in milliseconden (standaard: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Systeemfout:</translation> + <source>This is experimental software.</source> + <translation>Dit is experimentele software.</translation> </message> <message> <source>Transaction amount too small</source> @@ -2931,10 +3085,6 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Transactie te groot</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Gebruik UPnP om de luisterende poort te mappen (standaard: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Gebruik UPnP om de luisterende poort te mappen (standaard: 1 als er wordt geluisterd)</translation> </message> @@ -2975,10 +3125,6 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Vernieuw portemonnee naar nieuwste versie</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Stel sleutelpoelgrootte in op <n> (standaard: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Doorzoek de blokketen op ontbrekende portemonnee-transacties</translation> </message> @@ -2987,14 +3133,6 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Gebruik OpenSSL (https) voor JSON-RPC-verbindingen</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Certificaat-bestand voor server (standaard: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Geheime sleutel voor server (standaard: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Dit helpbericht</translation> </message> @@ -3011,14 +3149,134 @@ bijvoorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</tran <translation>Fout bij laden wallet.dat: Portemonnee corrupt</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> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Aantal seconden dat zich misdragende peers niet opnieuw kunnen verbinden (standaard: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Output extra debugginginformatie (standaard: %u, het leveren van <category> is optioneel)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Gebruik een aparte SOCKS5 proxy om 'Tor hidden services' te bereiken (standaard: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <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> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Aantal te checken blokken bij het opstarten (standaard: %u, 0 = allemaal)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <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> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Luister naar verbindingen op <poort> (standaard: %u of testnet: %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Onderhoud maximaal <n> verbindingen naar peers (standaard: %u)</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> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <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> + <message> + <source>Print block tree on startup (default: %u)</source> + <translation>Toon block structuur bij opstarten (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> + <message> + <source>Server private key (default: %s)</source> + <translation>Geheime sleutel voor server (standaard: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Stel sleutelpoelgrootte in op <&> (standaard: %u)</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Stel minimum blokgrootte in in bytes (standaard: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <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> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Specificeer de time-out tijd in milliseconden (minimum: 1, standaard: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Specificeer pid-bestand (standaard: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <translation>Besteed onbevestigd wisselgeld bij het versturen van transacties (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> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Onbekend netwerk gespecificeerd in -onlynet: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_pam.ts b/src/qt/locale/bitcoin_pam.ts index d109c24423..b0a92a1578 100644 --- a/src/qt/locale/bitcoin_pam.ts +++ b/src/qt/locale/bitcoin_pam.ts @@ -1,4 +1,4 @@ -<TS language="pam" version="2.1"> +<TS language="pam" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -10,10 +10,22 @@ <translation>Maglalang kang bayung address</translation> </message> <message> + <source>&New</source> + <translation>&Bayu</translation> + </message> + <message> <source>Copy the currently selected address to the system clipboard</source> <translation>Kopyan me ing salukuyan at makipiling address keng system clipboard</translation> </message> <message> + <source>&Copy</source> + <translation>&Kopyan</translation> + </message> + <message> + <source>C&lose</source> + <translation>I&sara</translation> + </message> + <message> <source>&Copy Address</source> <translation>&Kopyan ing address</translation> </message> @@ -26,10 +38,34 @@ <translation>&Ilako</translation> </message> <message> + <source>Choose the address to send coins to</source> + <translation>Pilinan ing address a magpadalang coins kang</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>Pilinan ing address a tumanggap coins a atin</translation> + </message> + <message> + <source>C&hoose</source> + <translation>P&ilinan</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Address king pamag-Padala</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Address king pamag-Tanggap</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>Reni reng kekang Bitcoin address king pamagpadalang kabayaran. Lawan mulang masalese reng alaga ampo ing address na ning tumanggap bayu ka magpadalang barya.</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>Reni reng kekang Bitcoin addresses keng pamananggap bayad. Rerekomenda mi na gumamit kang bayung address keng balang transaksiyon.</translation> + </message> + <message> <source>Copy &Label</source> <translation>Kopyan ing &Label</translation> </message> @@ -279,10 +315,6 @@ <translation>Gamit para king Tabs</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Kapilubluban ning Bitcoin</translation> </message> @@ -357,10 +389,6 @@ Address: %4 <translation>Alaga</translation> </message> <message> - <source>Address</source> - <translation>Address</translation> - </message> - <message> <source>Date</source> <translation>Kaaldauan</translation> </message> @@ -503,10 +531,6 @@ Address: %4 <translation>&Pun</translation> </message> <message> - <source>Pay transaction &fee</source> - <translation>Mamayad &bayad para king transaksion </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> @@ -606,10 +630,6 @@ Address: %4 <translation>Ing makaltong impormasion mapalyaring luma ne. Ing kekang wallet otomatiku yang mag-synchronize keng Bitcoin network istung mekakonekta ne king network, oneng ing prosesung ini ali ya pa kumpletu.</translation> </message> <message> - <source>Wallet</source> - <translation>Wallet</translation> - </message> - <message> <source>Your current spendable balance</source> <translation>Ing kekang kasalungsungan balanse a malyari mung gastusan</translation> </message> @@ -634,10 +654,6 @@ Address: %4 <translation>Ing kekang kasalungsungan kabuuang balanse</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Reng kapilan pamung transaksion</b></translation> - </message> - <message> <source>out of sync</source> <translation>ali ya maka-sync</translation> </message> @@ -1375,26 +1391,10 @@ Address: %4 <translation>Pipamilian:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Pilinan ing configuration file(default: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Pilinan ing pid file(default: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Pilinan ing data directory</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Makiramdam king koneksion king <port>(default: 8333 o testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Mag-maintain peka <n> koneksion keng peers (default: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Kumunekta king note ban ayakua mula reng peer address, at mako king panga konekta</translation> </message> @@ -1403,14 +1403,6 @@ Address: %4 <translation>Sabyan me ing kekang pampublikong address</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Threshold for disconnecting misbehaving peers (default: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Tumanggap command line at JSON-RPC commands</translation> </message> @@ -1463,58 +1455,10 @@ Address: %4 <translation>Kamalian: Mababa ne ing espasyu king disk!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Kamalian: kamalian na ning sistema:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Memali ya ing pamakiramdam kareng gang nanung port. Gamita me ini -listen=0 nung buri me ini.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Me-mali king pamagbasa king impormasion ning block</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Me-mali king pamagbasa keng block</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Me-mali para i-sync ing block index</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Me-mali king pamanyulat king block index</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Me-mali king pamanyulat king block info</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Me-mali king pamanyulat block</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Me-mali king pamanyulat king file info</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Me-mali king pamanyulat king coin database</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Me-mali king pamanyulat king index ning transaksion</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Me-mali king pamanyulat king undo data</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Pilan la reng block a lawan keng umpisa (default: 288, 0 = all)</translation> - </message> - <message> <source>Information</source> <translation>&Impormasion</translation> </message> @@ -1523,14 +1467,6 @@ Address: %4 <translation>Magpadalang trace/debug info okeng console kesa keng debug.log file</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Ilage ing pekaditak a dagul na ning block king bytes (default: 0)</translation> - </message> - <message> - <source>System error: </source> - <translation>Kamalian ning sistema:</translation> - </message> - <message> <source>Transaction too large</source> <translation>Maragul yang masiadu ing transaksion</translation> </message> @@ -1559,10 +1495,6 @@ Address: %4 <translation>I-upgrade ing wallet king pekabayung porma</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>I-set ing key pool size king <n>(default: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>I-scan pasibayu ing block chain para kareng mauaualang transaksion</translation> </message> @@ -1571,14 +1503,6 @@ Address: %4 <translation>Gumamit OpenSSL(https) para king JSON-RPC koneksion</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Server certificate file (default: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Server private key (default: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Ining saup a mensayi</translation> </message> diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index 7cf3d042a1..c53a9970ef 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -1,4 +1,4 @@ -<TS language="pl" version="2.1"> +<TS language="pl" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -387,10 +387,6 @@ <translation>Pasek zakładek</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Rdzeń BitCoin</translation> </message> @@ -426,10 +422,6 @@ <source>No block source available...</source> <translation>Brak dostępnych źródeł bloków...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Pobrano %1 bloków z historią transakcji.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n godzina</numerusform><numerusform>%n godzin</numerusform><numerusform>%n godzin</numerusform></translation> @@ -565,10 +557,6 @@ Adres: %4 <translation>Kwota</translation> </message> <message> - <source>Address</source> - <translation>Adres</translation> - </message> - <message> <source>Date</source> <translation>Data</translation> </message> @@ -888,15 +876,7 @@ Adres: %4 <source>Error</source> <translation>Błąd</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB dostępnego wolnego miejsca</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(z %1GB potrzebnego)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -931,14 +911,6 @@ Adres: %4 <translation>Główne</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Opcjonalna prowizja za transakcje za kB, wspomaga ona szybkość przebiegu transakcji. Większość transakcji jest 1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Płać prowizję za transakcje</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>Automatycznie uruchamia Bitcoin po zalogowaniu do systemu.</translation> </message> @@ -963,10 +935,6 @@ Adres: %4 <translation>Zezwól na połączenia przychodzące</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Połącz się z siecią Bitcoin poprzez SOCKS proxy.</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>Adres IP serwera proxy (np. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1102,10 +1070,6 @@ Adres: %4 <translation>Wyświetlana informacja może być nieaktualna. Twój portfel synchronizuje się automatycznie z siecią bitcoin, zaraz po tym jak uzyskano połączenie, ale proces ten nie został jeszcze ukończony.</translation> </message> <message> - <source>Wallet</source> - <translation>Portfel</translation> - </message> - <message> <source>Available:</source> <translation>Dostępne:</translation> </message> @@ -1138,10 +1102,6 @@ Adres: %4 <translation>Twoje obecne saldo</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Ostatnie transakcje</b></translation> - </message> - <message> <source>out of sync</source> <translation>desynchronizacja</translation> </message> @@ -2347,26 +2307,10 @@ Adres: %4 <translation>Opcje:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Wskaż plik konfiguracyjny (domyślnie: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Wskaż plik pid (domyślnie: bitcoin.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Wskaż folder danych</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Nasłuchuj połączeń na <port> (domyślnie: 8333 lub testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Utrzymuj maksymalnie <n> połączeń z peerami (domyślnie: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Podłącz się do węzła aby otrzymać adresy peerów i rozłącz</translation> </message> @@ -2375,18 +2319,6 @@ Adres: %4 <translation>Podaj swój publiczny adres</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Próg po którym nastąpi rozłączenie nietrzymających się zasad peerów (domyślnie: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Czas w sekundach, przez jaki nietrzymający się zasad peerzy nie będą mogli ponownie się podłączyć (domyślnie: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Nasłuchuj połączeń JSON-RPC na <port> (domyślnie: 8332 or testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Akceptuj linię poleceń oraz polecenia JSON-RPC</translation> </message> @@ -2426,10 +2358,6 @@ Zalecane jest ustawienie alertnotify aby poinformować o problemach:⏎ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com⏎</translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Dopuszczalne szyfry (domyślnie: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Skojarz z podanym adresem. Użyj formatu [host]:port dla IPv6 </translation> </message> @@ -2474,10 +2402,6 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com⏎</t <translation>(domyślnie: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(domyślnie: wallet.dat)</translation> - </message> - <message> <source>Attempt to recover private keys from a corrupt wallet.dat</source> <translation>Próbuj odzyskać klucze prywatne z uszkodzonego wallet.dat</translation> </message> @@ -2538,66 +2462,10 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com⏎</t <translation>Błąd: Zablokowany portfel, nie można utworzyć transakcji!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Błąd: błąd systemu:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Próba otwarcia jakiegokolwiek portu nie powiodła się. Użyj -listen=0 jeśli tego chcesz.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Nie udało się odczytać informacji bloku</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Nie udało się odczytać bloku.</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Nie udało się zsynchronizować indeksu bloków.</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Nie udało się zapisać indeksu bloków.</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Nie udało się zapisać informacji bloku</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Nie udało się zapisać bloku</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Nie udało się zapisać informacji o pliku</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Nie udało się zapisać do bazy monet</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Nie udało się zapisać indeksu transakcji</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Nie udało się zapisać danych odtwarzających</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Wymuś tryb bezpieczny (domyślnie: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Generuj monety (domyślnie: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Ile bloków sprawdzić przy starcie (domyślnie: 288, 0 = wszystkie)</translation> - </message> - <message> <source>Importing...</source> <translation>Importowanie…</translation> </message> @@ -2626,18 +2494,10 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com⏎</t <translation>Ustaw maksymalną wielkość bloku w bajtach (domyślnie: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Ustaw liczbę wątków do odwołań RPC (domyślnie: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Określ plik portfela (w obrębie folderu danych)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Wydawaj niepotwierdzoną resztę podczas wysyłania transakcji (domyślnie: 1)</translation> - </message> - <message> <source>Verifying blocks...</source> <translation>Weryfikacja bloków...</translation> </message> @@ -2682,46 +2542,14 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com⏎</t <translation>Nieprawidłowa kwota dla -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Ogranicz rozmiar pamięci podręcznej sygnatur do <n> wpisów (domyslnie: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Loguj priorytety transakcji i opłaty na kB podczas kopania bloków (domyślnie: 0)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Utrzymuj pełen indeks transakcji (domyślnie: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maksymalny bufor odbioru na połączenie, <n>*1000 bajtów (domyślnie: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maksymalny bufor wysyłu na połączenie, <n>*1000 bajtów (domyślnie: 1000)</translation> - </message> - <message> <source>Node relay options:</source> <translation>Opcje przekaźnikowe węzła:</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Akceptuj tylko łańcuch bloków zgodny z wbudowanymi punktami kontrolnymi (domyślnie: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Łącz z węzłami tylko w sieci <net> (IPv4, IPv6 lub Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>Wyświetlaj blok podczas uruchamiania, jeżeli znaleziono indeks bloków</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Wypisz drzewo bloków podczas uruchomienia (domyślnie: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Opcje RPC SSL: (odwiedź Bitcoin Wiki w celu uzyskania instrukcji)</translation> </message> @@ -2738,18 +2566,10 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com⏎</t <translation>Losowo ignoruje 1 z wszystkich <n> wiadomości sieciowych.</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Uruchom wątek do okresowego zapisywania portfela (domyślnie: 1)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Wyślij informację/raport do konsoli zamiast do pliku debug.log.</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Ustaw minimalny rozmiar bloku w bajtach (domyślnie: 0)</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> @@ -2762,14 +2582,6 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com⏎</t <translation>Podpisywanie transakcji nie powiodło się</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Wskaż czas oczekiwania bezczynności połączenia w milisekundach (domyślnie: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Błąd systemu:</translation> - </message> - <message> <source>This is experimental software.</source> <translation>To oprogramowanie eksperymentalne.</translation> </message> @@ -2786,10 +2598,6 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com⏎</t <translation>Transakcja zbyt duża</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Używaj UPnP do mapowania portu nasłuchu (domyślnie: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Używaj UPnP do mapowania portu nasłuchu (domyślnie: 1 gdy nasłuchuje)</translation> </message> @@ -2830,10 +2638,6 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com⏎</t <translation>Zaktualizuj portfel do najnowszego formatu.</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Ustaw rozmiar puli kluczy na <n> (domyślnie: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Przeskanuj blok łańcuchów żeby znaleźć zaginione transakcje portfela</translation> </message> @@ -2842,14 +2646,6 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com⏎</t <translation>Użyj OpenSSL (https) do połączeń JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Plik certyfikatu serwera (domyślnie: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Klucz prywatny serwera (domyślnie: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Ta wiadomość pomocy</translation> </message> diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index 0cdb7d6694..65f07ca59c 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> @@ -391,10 +391,6 @@ <translation>Barra de ferramentas</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Núcleo Bitcoin</translation> </message> @@ -434,10 +430,6 @@ <source>No block source available...</source> <translation>Nenhum servidor disponível...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Processado %1 blocos do histórico de transações.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation> @@ -528,10 +520,6 @@ Endereço: %4</translation> <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Coin Control Address Selection</translation> - </message> - <message> <source>Quantity:</source> <translation>Quantidade:</translation> </message> @@ -580,10 +568,6 @@ Endereço: %4</translation> <translation>Quantidade</translation> </message> <message> - <source>Address</source> - <translation>Endereço</translation> - </message> - <message> <source>Date</source> <translation>Data</translation> </message> @@ -915,13 +899,13 @@ Endereço: %4</translation> <source>Error</source> <translation>Erro</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB de espaço disponível</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB de espaço livre disponível</numerusform><numerusform>%n GB de espaço livre disponível</numerusform></translation> </message> - <message> - <source>(of %1GB needed)</source> - <translation>(Mais de %1GB necessário)</translation> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(de %n GB necessário)</numerusform><numerusform>(de %n GB necessário)</numerusform></translation> </message> </context> <context> @@ -958,14 +942,6 @@ Endereço: %4</translation> <translation>Principal</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Taxa de transação opcional por kB que ajuda a garantir que suas transações sejam processadas rapidamente. A maioria das transações são de 1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Pagar taxa de &transação</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> @@ -994,14 +970,6 @@ Endereço: %4</translation> <translation>Permitir conexões de entrada</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Conectado na rede do Bitcoin através de proxy SOCKS.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Conectado via proxy SOCKS (padrão proxy):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>Endereço de IP do proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1165,10 +1133,6 @@ Endereço: %4</translation> <translation>A informação mostrada pode estar desatualizada. Sua carteira sincroniza automaticamente com a rede Bitcoin depois que a conexão é estabelecida, mas este processo pode não estar completo ainda.</translation> </message> <message> - <source>Wallet</source> - <translation>Carteira</translation> - </message> - <message> <source>Watch-only:</source> <translation>Apenas visualizar:</translation> </message> @@ -1197,6 +1161,10 @@ Endereço: %4</translation> <translation>Saldo minerado que ainda não maturou</translation> </message> <message> + <source>Balances</source> + <translation>Saldos</translation> + </message> + <message> <source>Total:</source> <translation>Total:</translation> </message> @@ -1209,8 +1177,8 @@ Endereço: %4</translation> <translation>Sua balança atual em endereços apenas visualizados</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Transações recentes</b></translation> + <source>Recent transactions</source> + <translation>Transações recentes</translation> </message> <message> <source>out of sync</source> @@ -1282,7 +1250,11 @@ Endereço: %4</translation> </context> <context> <name>PeerTableModel</name> - </context> + <message> + <source>Ping Time</source> + <translation>Tempo de Ping</translation> + </message> +</context> <context> <name>QObject</name> <message> @@ -1416,6 +1388,10 @@ Endereço: %4</translation> <translation>&Pares</translation> </message> <message> + <source>Direction</source> + <translation>Direção</translation> + </message> + <message> <source>Version</source> <translation>Versão</translation> </message> @@ -1424,6 +1400,30 @@ Endereço: %4</translation> <translation>Serviços</translation> </message> <message> + <source>Ban Score</source> + <translation>Banir pontuação</translation> + </message> + <message> + <source>Last Send</source> + <translation>Ultimo Envio</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Ultimo Recebido</translation> + </message> + <message> + <source>Bytes Sent</source> + <translation>Bytes Enviados</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>bytes Recebidos</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Tempo de Ping</translation> + </message> + <message> <source>Last block time</source> <translation>Horário do último bloco</translation> </message> @@ -1516,14 +1516,6 @@ Endereço: %4</translation> <translation>Saída</translation> </message> <message> - <source>Yes</source> - <translation>Sim</translation> - </message> - <message> - <source>No</source> - <translation>Não</translation> - </message> - <message> <source>Unknown</source> <translation>Desconhecido</translation> </message> @@ -1911,6 +1903,10 @@ Endereço: %4</translation> <translation>Este é um pagamento normal.</translation> </message> <message> + <source>The Bitcoin address to send the payment to</source> + <translation>O enderesso Bitcoin que enviarár o pagamento</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1981,6 +1977,10 @@ Endereço: %4</translation> <translation>Você pode assinar mensagens com seus endereços para provar que você é o dono deles. Seja cuidadoso para não assinar algo vago, pois ataques de pishing podem tentar te enganar para dar sua assinatura de identidade para eles. Apenas assine afirmações completamente detalhadas com as quais você concorda.</translation> </message> <message> + <source>The Bitcoin address to sign the message with</source> + <translation>O enderesso Bitcoin que assinará a mensagem</translation> + </message> + <message> <source>Choose previously used address</source> <translation>Escolha um endereço usado anteriormente</translation> </message> @@ -2033,6 +2033,10 @@ Endereço: %4</translation> <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> </message> <message> + <source>The Bitcoin address the message was signed with</source> + <translation>O enderesso Bitcoin que assionou a mesnagem</translation> + </message> + <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> <translation>Verificar mensagem para se assegurar que ela foi assinada pelo dono de um endereço Bitcoin específico.</translation> </message> @@ -2174,6 +2178,10 @@ Endereço: %4</translation> <translation>seu próprio endereço</translation> </message> <message> + <source>watch-only</source> + <translation>Vizualização apenas</translation> + </message> + <message> <source>label</source> <translation>rótulo</translation> </message> @@ -2194,6 +2202,14 @@ Endereço: %4</translation> <translation>Débito</translation> </message> <message> + <source>Total debit</source> + <translation>Débito total</translation> + </message> + <message> + <source>Total credit</source> + <translation>Credito total</translation> + </message> + <message> <source>Transaction fee</source> <translation>Taxa de transação</translation> </message> @@ -2344,6 +2360,10 @@ Endereço: %4</translation> <translation>Minerado</translation> </message> <message> + <source>watch-only</source> + <translation>Vizualização apenas</translation> + </message> + <message> <source>(n/a)</source> <translation>(n/a)</translation> </message> @@ -2455,6 +2475,10 @@ Endereço: %4</translation> <translation>Exportar Histórico de Transação</translation> </message> <message> + <source>Watch-only</source> + <translation>Vizualização apenas</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Exportação Falhou</translation> </message> @@ -2566,26 +2590,10 @@ Endereço: %4</translation> <translation>Opções:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Especifique um arquivo de configurações (padrão: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Especifique um arquivo de pid (padrão: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Especificar diretório de dados</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Procurar por conexões em <port> (padrão: 8333 ou testnet:18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Manter no máximo <n> conexões aos peers (padrão: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Conectar a um nó para receber endereços de participantes, e desconectar.</translation> </message> @@ -2594,18 +2602,6 @@ Endereço: %4</translation> <translation>Especificar seu próprio endereço público</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Limite para desconectar peers mal comportados (padrão: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Número de segundos para impedir que peers mal comportados reconectem (padrão: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Escutar conexões JSON-RPC na porta <porta> (padrão: 8332 ou testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Aceitar linha de comando e comandos JSON-RPC</translation> </message> @@ -2646,18 +2642,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Codificadores aceitos (padrão: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on 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>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Restringe a taxa de transações gratuitas para <n>*1000 bytes por minuto (padrão:15)</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> @@ -2674,14 +2662,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Executar comando quando uma transação da carteira mudar (%s no comando será substituído por TxID)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Descarrega a atividade do banco de dados da memória para log em disco a cada <n> megabytes (padrão: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Quão completa a verificação de blocos do -checkblocks é (0-4, padrão: 3)</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> </message> @@ -2690,10 +2670,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Define o número de threads de verificação de script (%u a %d, 0 = automático, <0 = número de cores deixados livres, padrão: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Define o limite de processador para quando geração está ativa (-1 = ilimitada, padrão: -1)</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>Este pode ser um build de teste pré-lançamento - use por sua conta e risco - não use para mineração ou aplicações de comércio.</translation> </message> @@ -2702,10 +2678,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Impossível ouvir em %s neste computador. Bitcoin Core já está sendo executado provavelmente.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Use proxy SOCKS5 separado para alcançar nós via Tor hidden services (padrão: -proxy)</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>Atenção: valor de -paytxfee escolhido é muito alto! Este é o valor da taxa de transação que você irá pagar se enviar a transação.</translation> </message> @@ -2730,10 +2702,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>(padrão: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(padrão: wallet.dat)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> pode ser:</translation> </message> @@ -2762,10 +2730,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Opções de Debug/Teste:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Desabilita modo seguro, sobrepõe um evento de modo seguro real (padrão: 0)</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> </message> @@ -2794,6 +2758,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Erro ao abrir banco de dados de blocos</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Erro: Um erro interno fatal ocorreu, ver o debug.log para detalhes</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Erro: Espaço em disco insuficiente!</translation> </message> @@ -2802,66 +2770,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Erro: Carteira bloqueada, impossível criar transação!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Erro: erro de sistema</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Falha ao escutar em qualquer porta. Use -listen=0 se você quiser isso.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Falha ao ler informação de bloco</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Falha ao ler bloco</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Falha ao sincronizar índice de blocos</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Falha ao escrever índice de blocos</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Falha ao escrever informações de bloco</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Falha ao escrever bloco</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Falha ao escrever informções de arquivo</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Falha ao escrever banco de dados de moedas</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Falha ao escrever índice de transações</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Falha ao escrever dados para desfazer ações</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Força modo seguro (padrão: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Gerar moedas (padrão: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Quantos blocos checar ao inicializar (padrão: 288, 0 = todos)</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> </message> @@ -2882,10 +2794,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Decriptadores de arquivos disponíveis insuficientes.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Adiciona timestamp como prefixo no debug (padrão: 1)</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> </message> @@ -2898,22 +2806,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Define o tamanho máximo de cada bloco em bytes (padrão: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Defina o número de threads de chamadas RPC (padrão: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Especifique o arquivo da carteira (dentro do diretório de dados)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Permite gastar troco não confirmado ao criar transações (padrão: 1)</translation> - </message> - <message> - <source>Stop running after importing blocks from disk (default: 0)</source> - <translation>Parar de executar após importar blocos do disco (padrão: 0)</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> @@ -2954,10 +2850,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Erro: Escutar por conexões de entrada falhou (escutar retornou erro %s)</translation> </message> <message> - <source>Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)</source> - <translation>Executa comando quando uma transação da rede gasta novamente uma transação de entrada da carteira (%s=TxID do gasto duplo, %t=TxID da Carteira)</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> </message> @@ -2970,10 +2862,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <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> </message> <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Informação de saída de debug (padrão: 0, definir <category> é opcional)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Define o tamanho máximo de alta-prioridade por taxa baixa nas transações em bytes (padrão: %d)</translation> </message> @@ -2982,6 +2870,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Impossível resolver endereço -whitebind: '%s'</translation> </message> <message> + <source>Connect through SOCKS5 proxy</source> + <translation>Connecte-se através de um proxy SOCKS5</translation> + </message> + <message> <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> <translation>Copyright (C) 2009-%i Desenvolvedores Bitcoin Core</translation> </message> @@ -2994,10 +2886,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Taxa (em BTC/kB) a adicionar nas transações que você envia (padrão: %s)</translation> </message> <message> - <source>Include IP addresses in debug output (default: 0)</source> - <translation>Incluir endereços IP na saída de depuração (padrão: 0)</translation> - </message> - <message> <source>Information</source> <translation>Informação</translation> </message> @@ -3022,46 +2910,14 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Manter no máximo <n> blocos pendentes em memória (padrão: %u)</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Limita tamanho do cache de assinaturas em <n> entradas (padrão: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Registra log da prioridade de transação e taxa por kB quando minerando blocos (padrão: 0)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Manter índice completo de transações (padrão: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Buffer máximo de recebimento por conexão, <n>*1000 bytes (padrão: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Buffer máximo de envio por conexão, <n>*1000 bytes (padrão: 1000)</translation> - </message> - <message> <source>Need to specify a port with -whitebind: '%s'</source> <translation>Necessário informar uma porta com -whitebind: '%s'</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Apenas aceitar cadeia de blocos correspondente a marcas de verificação internas (padrão: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Apenas conectar em nós na rede <net> (IPv4, IPv6, ou Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>Imprime bloco ao iniciar, se encontrado no índice de blocos</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Imprime árvore de blocos ao iniciar (padrão: 0)</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> @@ -3078,22 +2934,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Aleatoriamente embaralha 1 em cada <n> mensagens da rede</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Executa uma thread para limpar a carteira periodicamente (padrão: 1)</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> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Determinar tamanho mínimo de bloco em bytes (padrão: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Define a flag DB_PRIVATE no ambiente de banco de dados da carteira (padrão: 1)</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> </message> @@ -3106,14 +2950,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Assinatura de transação falhou</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Especifique o tempo limite (timeout) da conexão em milissegundos (padrão: 5000) </translation> - </message> - <message> - <source>System error: </source> - <translation>Erro de sistema:</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Este é um software experimental.</translation> </message> @@ -3134,10 +2970,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Impossível se ligar a %s neste computador (bind retornou erro %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Usar UPnP para mapear porta de escuta (padrão: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Usar UPnP para mapear porta de escuta (padrão: 1 quando estiver escutando)</translation> </message> @@ -3146,6 +2978,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Nome de usuário para conexões JSON-RPC</translation> </message> <message> + <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source> + <translation>Sua carteira precisou ser reescrita: favor reiniciar o Bitcoin para completar</translation> + </message> + <message> <source>Warning</source> <translation>Atenção</translation> </message> @@ -3178,10 +3014,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Atualizar carteira para o formato mais recente</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Determinar tamanho do pool de endereços para <n> (padrão: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Re-escanear blocos procurando por transações perdidas da carteira</translation> </message> @@ -3190,14 +3022,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Usar OpenSSL (https) para conexões JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Arquivo de certificado do servidor (padrão: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Chave privada do servidor (padrão: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Esta mensagem de ajuda</translation> </message> @@ -3222,6 +3046,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com⏎ <translation>Endereço -proxy inválido: '%s'</translation> </message> <message> + <source>Specify pid file (default: %s)</source> + <translation>Especificar aqrquivo pid (default: %s)</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_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index 2d277528b1..dc016623e4 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> @@ -180,6 +180,10 @@ <translation>Carteira encriptada</translation> </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>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> </message> @@ -375,10 +379,6 @@ <translation>Barra de separadores</translation> </message> <message> - <source>[testnet]</source> - <translation>[rede de testes]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -418,10 +418,6 @@ <source>No block source available...</source> <translation>Nenhuma fonte de blocos disponível...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Processados %1 blocos do histórico de transações.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation> @@ -512,10 +508,6 @@ Endereço: %4</translation> <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Seleção de Endereço Coin Control</translation> - </message> - <message> <source>Quantity:</source> <translation>Quantidade:</translation> </message> @@ -560,10 +552,6 @@ Endereço: %4</translation> <translation>Quantia</translation> </message> <message> - <source>Address</source> - <translation>Endereço</translation> - </message> - <message> <source>Date</source> <translation>Data</translation> </message> @@ -875,15 +863,7 @@ Endereço: %4</translation> <source>Error</source> <translation>Erro</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB de espaço livre disponível</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(de %1GB necessários)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -918,14 +898,6 @@ Endereço: %4</translation> <translation>&Principal</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Taxa de transação opcional por KB que ajuda a assegurar que as suas transações serão processadas rapidamente. A maioria das transações tem 1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Pagar &taxa de transação</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> @@ -946,14 +918,6 @@ Endereço: %4</translation> <translation>Número de processos de &verificação de scripts</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Ligar à rede Bitcoin através de um proxy SOCKS.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>Ligar através de um proxy SO&CKS (proxy por defeito):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>Endereço IP do proxy (p.ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1105,10 +1069,6 @@ Endereço: %4</translation> <translation>A informação mostrada poderá estar desatualizada. A sua carteira sincroniza automaticamente com a rede Bitcoin depois de estabelecer ligação, mas este processo ainda não está completo.</translation> </message> <message> - <source>Wallet</source> - <translation>Carteira</translation> - </message> - <message> <source>Available:</source> <translation>Disponível:</translation> </message> @@ -1141,10 +1101,6 @@ Endereço: %4</translation> <translation>O seu saldo total actual</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Transações recentes</b></translation> - </message> - <message> <source>out of sync</source> <translation>fora de sincronia</translation> </message> @@ -1160,6 +1116,10 @@ Endereço: %4</translation> <translation>Endereço de pagamento inválido %1</translation> </message> <message> + <source>Payment request rejected</source> + <translation>Pedido de pagamento rejeitado</translation> + </message> + <message> <source>Requested payment amount of %1 is too small (considered dust).</source> <translation>Quantia solicitada para pagamento de %1 é muito pequena (considerada "pó").</translation> </message> @@ -2406,26 +2366,10 @@ Endereço: %4</translation> <translation>Opções:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Especificar ficheiro de configuração (por defeito: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Especificar ficheiro pid (por defeito: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Especificar pasta de dados</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Escute ligações na porta <n> (por defeito: 8333 ou testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Manter no máximo <n> ligações a outros nós da rede (por defeito: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Ligar a um nó para recuperar endereços de pares, e desligar</translation> </message> @@ -2434,18 +2378,6 @@ Endereço: %4</translation> <translation>Especifique o seu endereço público</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Tolerância para desligar nós com comportamento indesejável (por defeito: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Número de segundos a impedir que nós com comportamento indesejado se liguem de novo (por defeito: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Escutar por ligações JSON-RPC na porta <n> (por defeito: 8332 ou rede de testes: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Aceitar comandos de linha de comandos e JSON-RPC</translation> </message> @@ -2485,10 +2417,6 @@ Também é recomendado definir um alertnotify para que seja alertado sobre probl por exemplo: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com</translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Cifras aceitáveis (por defeito: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Associar a endereço específico e escutar sempre nele. Use a notação [anfitrião]:porta para IPv6</translation> </message> @@ -2517,10 +2445,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com</tran <translation>Incapaz de vincular à porta %s neste computador. O Bitcoin Core provavelmente já está a correr.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Usar um proxy SOCKS5 separado para aceder a pares através de Tor hidden services (por defeito: -proxy)</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>Atenção: -paytxfee está definida com um valor muito alto! Esta é a taxa que irá pagar se enviar uma transação.</translation> </message> @@ -2597,62 +2521,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com</tran <translation>Erro: Carteira bloqueada, incapaz de criar transação! </translation> </message> <message> - <source>Error: system error: </source> - <translation>Erro: erro do sistema:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Falhou a escutar em qualquer porta. Use -listen=0 se quiser isto.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Falha ao ler informação do bloco</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Falha ao ler bloco</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Falha ao sincronizar índice de blocos</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Falha ao escrever índice de blocos</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Falha ao escrever informação do bloco</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Falha ao escrever bloco</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Falha ao escrever informação do ficheiro</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Falha ao escrever na base de dados de moedas</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Falha ao escrever índice de transações</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Falha ao escrever histórico de modificações</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Gerar moedas (por defeito: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Quantos blocos verificar ao inicializar (por defeito: 288, 0 = todos)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Se uma <categoria> não é fornecida, imprimir toda a informação de depuração.</translation> </message> @@ -2669,10 +2541,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com</tran <translation>Os descritores de ficheiros disponíveis são insuficientes.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Adicionar data e hora à informação de depuração (por defeito: 1)</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> @@ -2685,18 +2553,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com</tran <translation>Definir tamanho máximo por bloco em bytes (por defeito: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Defina o número de processos para servir as chamadas RPC (por defeito: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Especifique ficheiro de carteira (dentro da pasta de dados)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Gastar saldo não confirmado ao enviar transações (padrão: 1)</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> @@ -2733,10 +2593,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com</tran <translation>Executar comando quando um alerta relevante for recebido ou em caso de uma divisão longa da cadeia de blocos (no comando, %s é substituído pela mensagem)</translation> </message> <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Informação de depuração (por defeito: 0, fornecer uma <categoria> é opcional)</translation> - </message> - <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> <translation>Definir tamanho máximo de transações com alta-prioridade/baixa-taxa em bytes (por defeito: %d)</translation> </message> @@ -2753,34 +2609,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com</tran <translation>Quantia inválida para -mintxfee=<quantidade>: '%s'</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Manter índice de transações completo (por defeito: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maximo armazenamento intermédio de recepção por ligação, <n>*1000 bytes (por defeito: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maximo armazenamento intermédio de envio por ligação, <n>*1000 bytes (por defeito: 1000)</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Apenas aceitar cadeia de blocos coincidente com pontos de controle internos (por defeito: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Apenas ligar a nós na rede <net> (IPv4, IPv6 ou Tor)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Enviar informação de rastreio/depuração para a consola e não para o ficheiro debug.log</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Definir tamanho minímo de um bloco em bytes (por defeito: 0)</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> @@ -2789,14 +2621,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com</tran <translation>Falhou assinatura da transação</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Especificar tempo de espera da ligação em millisegundos (por defeito: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Erro de sistema:</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Quantia da transação é muito baixa</translation> </message> @@ -2809,10 +2633,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com</tran <translation>Transação grande demais</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Usar UPnP para mapear a porta de escuta (padrão: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Usar UPnP para mapear a porta de escuta (padrão: 1 ao escutar)</translation> </message> @@ -2849,10 +2669,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com</tran <translation>Atualize a carteira para o formato mais recente</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Definir o tamanho da memória de chaves para <n> (por defeito: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Procurar transações em falta na cadeia de blocos</translation> </message> @@ -2861,14 +2677,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com</tran <translation>Usar OpenSSL (https) para ligações JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Ficheiro de certificado do servidor (por defeito: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Chave privada do servidor (por defeito: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Esta mensagem de ajuda</translation> </message> diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index c9cad3d92a..81342c5dbc 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> @@ -275,6 +275,14 @@ <translation>S&chimbă parola...</translation> </message> <message> + <source>&Sending addresses...</source> + <translation>&Trimitere adrese...</translation> + </message> + <message> + <source>&Receiving addresses...</source> + <translation>&Primire adrese...</translation> + </message> + <message> <source>Open &URI...</source> <translation>Vizitaţi &URI...</translation> </message> @@ -367,10 +375,6 @@ <translation>Bara de file</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -398,6 +402,10 @@ <source>&Command-line options</source> <translation>Command-line setări</translation> </message> + <message> + <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> + <translation>Arată mesajul de ajutor Bitcoin Core pentru a obține o listă cu opțiunile posibile de linii de comandă Bitcoin</translation> + </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n conexiune activă către rețeaua Bitcoin</numerusform><numerusform>%n conexiuni active către rețeaua Bitcoin</numerusform><numerusform>%n de conexiuni active către rețeaua Bitcoin</numerusform></translation> @@ -406,10 +414,6 @@ <source>No block source available...</source> <translation>Nici o sursă de bloc disponibil ...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>S-au procesat %1 blocuri din istoricul tranzacțiilor.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n oră</numerusform><numerusform>%n ore</numerusform><numerusform>%n ore</numerusform></translation> @@ -497,10 +501,6 @@ Adresa: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Selectare Adresă de Comandă Monedă</translation> - </message> - <message> <source>Quantity:</source> <translation>Cantitate:</translation> </message> @@ -545,10 +545,6 @@ Adresa: %4 <translation>Sumă</translation> </message> <message> - <source>Address</source> - <translation>Adresă</translation> - </message> - <message> <source>Date</source> <translation>Data</translation> </message> @@ -778,6 +774,10 @@ Adresa: %4 <translation>versiunea</translation> </message> <message> + <source>(%1-bit)</source> + <translation>(%1-bit)</translation> + </message> + <message> <source>About Bitcoin Core</source> <translation>Despre Nucleul Bitcoin</translation> </message> @@ -844,15 +844,7 @@ Adresa: %4 <source>Error</source> <translation>Eroare</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB de spațiu liber disponibil</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(din %1GB necesari)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -887,14 +879,6 @@ Adresa: %4 <translation>&Principal</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Taxa optionala de tranzactie per kB care ajuta ca tranzactiile dumneavoastra sa fie procesate rapid. Majoritatea tranzactiilor sunt 1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Plăteşte comision pentru tranzacţie &f</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>Porneşte automat programul Bitcoin la pornirea computerului.</translation> </message> @@ -907,10 +891,6 @@ Adresa: %4 <translation>MB</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Conecteaza-te la reteaua Bitcoin printr-un proxy SOCKS</translation> - </message> - <message> <source>Reset all client options to default.</source> <translation>Resetează toate setările clientului la valorile implicite.</translation> </message> @@ -1038,10 +1018,6 @@ Adresa: %4 <translation>Informațiile afișate pot neactualizate. Portofelul tău se sincronizează automat cu rețeaua Bitcoin după ce o conexiune este stabilită, dar acest proces nu a fost finalizat încă.</translation> </message> <message> - <source>Wallet</source> - <translation>Portofel</translation> - </message> - <message> <source>Available:</source> <translation>Disponibil:</translation> </message> @@ -1074,10 +1050,6 @@ Adresa: %4 <translation>Balanța totală curentă</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Tranzacții recente</b></translation> - </message> - <message> <source>out of sync</source> <translation>Nu este sincronizat</translation> </message> @@ -2279,26 +2251,10 @@ Adresa: %4 <translation>Setări:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Specifică fișierul de configurare (implicit: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Specifică fișierul pid (implicit bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Specifică dosarul de date</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Ascultă pentru conectări pe <port> (implicit: 8333 sau testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Menține cel mult <n> conexiuni cu partenerii (implicit: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Conectează-te la nod pentru a obține adresele partenerilor, și apoi deconectează-te</translation> </message> @@ -2307,18 +2263,6 @@ Adresa: %4 <translation>Specifică adresa ta publică</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Prag pentru deconectarea partenerilor care nu funcționează corect (implicit: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Numărul de secunde pentru a preveni reconectarea partenerilor care nu funcționează corect (implicit: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Ascultă pentru conexiuni JSON-RPC pe <port> (implicit:8332 sau testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Se acceptă comenzi din linia de comandă și comenzi JSON-RPC</translation> </message> @@ -2360,10 +2304,6 @@ spre exemplu: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Cifruri acceptabile (implicit: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Atasati adresei date si ascultati totdeauna pe ea. Folositi [host]:port notatia pentru IPv6</translation> </message> @@ -2384,10 +2324,6 @@ spre exemplu: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com <translation>Aceasta este o versiune de test preliminara - va asumati riscul folosind-o - nu folositi pentru minerit sau aplicatiile comerciantilor.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Utilizare proxy SOCKS5 separat pentru a ajunge la servicii ascunse TOR (implicit: -proxy)</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>Atentie: setarea -paytxfee este foarte ridicata! Aceasta este taxa tranzactiei pe care o vei plati daca trimiti o tranzactie.</translation> </message> @@ -2460,66 +2396,10 @@ spre exemplu: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com <translation>Eroare: Portofel blocat, nu se poate crea o tranzacție!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Eroare: eroare de sistem:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Am esuat ascultarea pe orice port. Folositi -listen=0 daca vreti asta.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Citirea informațiilor despre bloc a eșuat</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Citirea blocului a eșuat</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>A eșuat sincronizarea indexului de blocuri</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>A eșuat scrierea indexului de blocuri</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Scrierea informațiilor despre bloc a eșuat</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Scrierea blocului a eșuat</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Nu a reușit scrierea informației în fișier</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Eșuarea scrierii în baza de date de monede</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Nu a reușit scrierea indexului de tranzacție</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Esuare in scrierea datelor anulate</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Pornire fortata a modului safe mode (prestabilit: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Generează monede (implicit: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Cate block-uri se verifica la initializare (implicit: 288, 0=toate)</translation> - </message> - <message> <source>Incorrect or no genesis block found. Wrong datadir for network?</source> <translation>Incorect sau nici un bloc de Geneza găsite. Directorul de retea greşit?</translation> </message> @@ -2540,10 +2420,6 @@ spre exemplu: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com <translation>Setaţi dimensiunea maximă a unui block în bytes (implicit: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Stabileste numarul de thread-uri care servesc apeluri RPC (implicit: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Specifică fișierul wallet (în dosarul de date)</translation> </message> @@ -2592,42 +2468,14 @@ spre exemplu: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com <translation>Suma invalida pentru -mintxfee=<suma>: '%s'</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Păstrează un index complet al tranzacțiilor (implicit: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Tampon maxim pentru recepție per conexiune, <n>*1000 baiți (implicit: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Tampon maxim pentru transmitere per conexiune, <n>*1000 baiți (implicit: 1000)</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Se accepta decat lantul de block care se potriveste punctului de control implementat (implicit: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Efectuează conexiuni doar către nodurile din rețeaua <net> (IPv4, IPv6 sau Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>Publica bloc la pornire daca exista in index-ul de blocuri. </translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Publicare arbore blocuri la pornire (prestabilit: 0)</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> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Setează mărimea minimă a blocului în baiți (implicit: 0)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Micsorati fisierul debug.log la inceperea clientului (implicit: 1 cand nu -debug)</translation> </message> @@ -2636,14 +2484,6 @@ spre exemplu: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com <translation>Semnarea tranzacției a eșuat</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Specifică intervalul maxim de conectare în milisecunde (implicit: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Eroare de sistem:</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Suma tranzacționată este prea mică</translation> </message> @@ -2656,10 +2496,6 @@ spre exemplu: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com <translation>Tranzacția este prea mare</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Foloseste UPnP pentru a vedea porturile (initial: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Foloseste UPnP pentru a vedea porturile (initial: 1 cand listezi)</translation> </message> @@ -2696,10 +2532,6 @@ spre exemplu: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com <translation>Actualizează portofelul la ultimul format</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Setează mărimea bazinului de chei la <n> (implicit: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Rescanează lanțul de bloc pentru tranzacțiile portofel lipsă</translation> </message> @@ -2708,14 +2540,6 @@ spre exemplu: alertnotify=echo %%s | mail -s "Alerta Bitcoin" admin@foo.com <translation>Folosește OpenSSL (https) pentru conexiunile JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Certificatul serverului (implicit: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Cheia privată a serverului (implicit: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Acest mesaj de ajutor</translation> </message> diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index d6a145928c..55986d4092 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> @@ -264,7 +264,7 @@ </message> <message> <source>&Options...</source> - <translation>Опции</translation> + <translation>&Параметры</translation> </message> <message> <source>&Encrypt Wallet...</source> @@ -387,10 +387,6 @@ <translation>Панель вкладок</translation> </message> <message> - <source>[testnet]</source> - <translation>[тестовая сеть]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Core</translation> </message> @@ -416,11 +412,11 @@ </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> - <translation>Показать помощь по Bitcoin Core и получить список доступных опций командной строки.</translation> + <translation>Показать помощь по Bitcoin Core и получить список доступных параметров командной строки.</translation> </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> @@ -430,10 +426,6 @@ <source>No block source available...</source> <translation>Источник блоков недоступен...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Обработано %1 блоков истории транзакций.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n час</numerusform><numerusform>%n часа</numerusform><numerusform>%n часов</numerusform></translation> @@ -482,6 +474,10 @@ <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> @@ -525,8 +521,8 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Выбор адреса контроля монет</translation> + <source>Coin Selection</source> + <translation>Выбор монет</translation> </message> <message> <source>Quantity:</source> @@ -577,8 +573,12 @@ Address: %4 <translation>Сумма</translation> </message> <message> - <source>Address</source> - <translation>Адрес</translation> + <source>Received with label</source> + <translation>Получено с пометкой</translation> + </message> + <message> + <source>Received with address</source> + <translation>Получено с адреса</translation> </message> <message> <source>Date</source> @@ -847,11 +847,11 @@ Address: %4 </message> <message> <source>command-line options</source> - <translation>опции командной строки</translation> + <translation>параметры командной строки</translation> </message> <message> <source>UI options</source> - <translation>Опции интерфейса</translation> + <translation>Настройки интерфейса</translation> </message> <message> <source>Set language, for example "de_DE" (default: system locale)</source> @@ -912,13 +912,13 @@ Address: %4 <source>Error</source> <translation>Ошибка</translation> </message> - <message> - <source>GB of free space available</source> - <translation>ГБ свободного места доступно</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%nГБ свободного места доступно</numerusform><numerusform>%nГБ свободного места доступно</numerusform><numerusform>%nГБ свободного места доступно</numerusform></translation> </message> - <message> - <source>(of %1GB needed)</source> - <translation>(из необходимых %1ГБ)</translation> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(из необходимых %nГБ)</numerusform><numerusform>(из необходимых %nГБ)</numerusform><numerusform>(из необходимых %nГБ)</numerusform></translation> </message> </context> <context> @@ -948,21 +948,13 @@ Address: %4 <name>OptionsDialog</name> <message> <source>Options</source> - <translation>Опции</translation> + <translation>Параметры</translation> </message> <message> <source>&Main</source> <translation>&Главная</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Необязательная комиссия за каждый КБ транзакции, которая ускоряет обработку Ваших транзакций. Большинство транзакций занимают 1КБ.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Заплатить ко&миссию</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>Автоматически запускать Bitcoin после входа в систему</translation> </message> @@ -991,14 +983,6 @@ Address: %4 <translation>Разрешить входящие подключения</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Подключаться к сети Bitcoin через прокси SOCKS.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Подключаться через SOCKS прокси (прокси по умолчанию):</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> @@ -1016,11 +1000,11 @@ Address: %4 </message> <message> <source>Reset all client options to default.</source> - <translation>Сбросить все опции клиента на значения по умолчанию.</translation> + <translation>Сбросить все настройки клиента на значения по умолчанию.</translation> </message> <message> <source>&Reset Options</source> - <translation>&Сбросить опции</translation> + <translation>&Сбросить параметры</translation> </message> <message> <source>&Network</source> @@ -1059,6 +1043,14 @@ Address: %4 <translation>Пробросить порт через &UPnP</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Подключаться к сети Bitcoin через прокси SOCKS5</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Подключаться к сети Bitcoin через прокси SOCKS5 (прокси по умолчанию):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>&IP Прокси: </translation> </message> @@ -1132,7 +1124,7 @@ Address: %4 </message> <message> <source>Confirm options reset</source> - <translation>Подтвердите сброс опций</translation> + <translation>Подтвердите сброс параметров</translation> </message> <message> <source>Client restart required to activate changes.</source> @@ -1162,10 +1154,6 @@ Address: %4 <translation>Отображаемая информация может быть устаревшей. Ваш бумажник автоматически синхронизируется с сетью Bitcoin после подключения, но этот процесс пока не завершён.</translation> </message> <message> - <source>Wallet</source> - <translation>Бумажник</translation> - </message> - <message> <source>Watch-only:</source> <translation>Только наблюдение:</translation> </message> @@ -1194,6 +1182,10 @@ Address: %4 <translation>Баланс добытых монет, который ещё не созрел</translation> </message> <message> + <source>Balances</source> + <translation>Балансы</translation> + </message> + <message> <source>Total:</source> <translation>Итого:</translation> </message> @@ -1206,6 +1198,14 @@ Address: %4 <translation>Ваш текущий баланс в адресах наблюдения</translation> </message> <message> + <source>Spendable:</source> + <translation>Доступно:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Последние транзакции</translation> + </message> + <message> <source>Unconfirmed transactions to watch-only addresses</source> <translation>Неподтверждённые транзакции на адреса наблюдения</translation> </message> @@ -1218,10 +1218,6 @@ Address: %4 <translation>Текущий общий баланс на адресах наблюдения</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Недавние транзакции</b></translation> - </message> - <message> <source>out of sync</source> <translation>не синхронизировано</translation> </message> @@ -1481,10 +1477,6 @@ Address: %4 <translation>Сервисы</translation> </message> <message> - <source>Sync Node</source> - <translation>Узел синхронизации</translation> - </message> - <message> <source>Starting Height</source> <translation>Начальная высота</translation> </message> @@ -1613,14 +1605,6 @@ Address: %4 <translation>Исходящие</translation> </message> <message> - <source>Yes</source> - <translation>Да</translation> - </message> - <message> - <source>No</source> - <translation>Нет</translation> - </message> - <message> <source>Unknown</source> <translation>Неизвестно</translation> </message> @@ -1857,6 +1841,78 @@ Address: %4 <translation>Свой адрес для сдачи</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Комиссия</translation> + </message> + <message> + <source>Choose...</source> + <translation>Выберите...</translation> + </message> + <message> + <source>collapse fee-settings</source> + <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> + <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 сатоши, а транзакция составляет лишь 250 байт, тогда комиссия "на килобайт" составит 250 сатоши, а "всего как минимум" — 1000 сатоши. Для транзакций крупнее килобайта в обоих случаях будет использоваться платёж "на килобайт".</translation> + </message> + <message> + <source>total at least</source> + <translation>Итого как минимум</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>Уплата минимальной комиссии — не проблема, пока объём транзакций меньше, чем свободное место в блоках. Учтите, однако, что такая транзакция может никогда не подтвердиться, если спрос на транзакции превышает возможности сети по их обработке.</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(прочтите подсказку)</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Рекомендовано:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Выборочно:</translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</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 as zero-fee transaction if possible</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> @@ -1961,6 +2017,14 @@ Address: %4 <translation>Транзакция была отклонена! Такое может произойти, если некоторые монеты уже были потрачены, например, если Вы используете одну копию бумажника (wallet.dat), а монеты были потрачены из другой копии, но не были отмечены как потраченные в этой.</translation> </message> <message> + <source>A fee higher than %1 is considered an insanely high fee.</source> + <translation>Комиссия больше, чем %1, считается невероятно большой.</translation> + </message> + <message> + <source>Estimated to begin confirmation within %1 block(s).</source> + <translation>Начало подтверждения ожидается через %1 блок(ов).</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Внимание: неверный адрес Bitcoin</translation> </message> @@ -2465,6 +2529,10 @@ Address: %4 <translation>Добыто</translation> </message> <message> + <source>watch-only</source> + <translation>только наблюдение</translation> + </message> + <message> <source>(n/a)</source> <translation>[не доступно]</translation> </message> @@ -2481,6 +2549,10 @@ Address: %4 <translation>Тип транзакции.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Использовался ли в транзакции адрес для наблюдения.</translation> + </message> + <message> <source>Destination address of transaction.</source> <translation>Адрес назначения транзакции.</translation> </message> @@ -2576,6 +2648,10 @@ Address: %4 <translation>Экспортировать историю транзакций</translation> </message> <message> + <source>Watch-only</source> + <translation>Для наблюдения</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Экспорт не удался</translation> </message> @@ -2688,29 +2764,13 @@ Address: %4 <name>bitcoin-core</name> <message> <source>Options:</source> - <translation>Опции:</translation> - </message> - <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Указать конфигурационный файл (по умолчанию: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Задать pid-файл (по умолчанию: bitcoin.pid)</translation> + <translation>Параметры:</translation> </message> <message> <source>Specify data directory</source> <translation>Задать каталог данных</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Принимать входящие подключения на <port> (по умолчанию: 8333 или 18333 в тестовой сети)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Поддерживать не более <n> подключений к участникам (по умолчанию: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Подключиться к участнику, чтобы получить список адресов других участников и отключиться</translation> </message> @@ -2719,18 +2779,6 @@ Address: %4 <translation>Укажите ваш собственный публичный адрес</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Порог для отключения неправильно ведущих себя участников (по умолчанию: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Число секунд блокирования неправильно ведущих себя участников (по умолчанию: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Прослушивать подключения JSON-RPC на <порту> (по умолчанию: 8332 или для testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Принимать командную строку и команды JSON-RPC</translation> </message> @@ -2771,22 +2819,18 @@ rpcpassword=%s </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Разрешённые алгоритмы(по умолчанию: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Привязаться к указанному адресу и всегда прослушивать только его. Используйте [хост]:порт для IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Ограничить скорость передачи бесплатных транзакций до <n>*1000 байт в минуту (по умолчанию: 15)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Удалить все транзакции бумажника с возможностью восстановить эти части цепи блоков с помощью -rescan при запуске</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>Распространяется под лицензией 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> @@ -2803,14 +2847,6 @@ rpcpassword=%s <translation>Выполнить команду, когда меняется транзакция в бумажнике (%s в команде заменяется на TxID)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Сбрасывать активность базы данных из памяти на диск каждые <n> мегабайт (по умолчанию: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Насколько тщательна проверка контрольных блоков -checkblocks (0-4, по умолчанию: 3)</translation> - </message> - <message> <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> <translation>В этом режиме -genproclimit определяет, сколько блоков генерируется немедленно.</translation> </message> @@ -2819,10 +2855,6 @@ rpcpassword=%s <translation>Задать число потоков проверки скрипта (от %u до %d, 0=авто, <0 = оставить столько ядер свободными, по умолчанию: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Задать лимит процессора, когда генерация работает (-1 = безлимитно, по умолчанию: -1)</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>Это пре-релизная тестовая сборка - используйте на свой страх и риск - не используйте для добычи или торговых приложений</translation> </message> @@ -2831,10 +2863,6 @@ rpcpassword=%s <translation>Не удалось забиндиться на %s на этом компьютере. Возможно, Bitcoin Core уже запущен.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Использовать отдельный прокси SOCKS5 для соединения с участниками через скрытые сервисы Tor (по умолчанию: -proxy)</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> @@ -2855,12 +2883,12 @@ rpcpassword=%s <translation>Внимание: wallet.dat повреждён, данные спасены! Оригинальный wallet.dat сохранён как wallet.{timestamp}.bak в %s; если ваш баланс или транзакции некорректны, вы должны восстановить файл из резервной копии.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(по умолчанию: 1)</translation> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Вносить в белый список участников, подключающихся с указанной маски сети или IP. Можно использовать многократно.</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(по умолчанию: wallet.dat)</translation> + <source>(default: 1)</source> + <translation>(по умолчанию: 1)</translation> </message> <message> <source><category> can be:</source> @@ -2891,10 +2919,6 @@ rpcpassword=%s <translation>Параметры отладки/тестирования:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Отключить безопасный режим, отклонить реальное событие безопасного режима (по умолчанию: 0)</translation> - </message> - <message> <source>Discover own IP address (default: 1 when listening and no -externalip)</source> <translation>Определить свой IP (по умолчанию: 1 при прослушивании и если не используется -externalip)</translation> </message> @@ -2923,6 +2947,10 @@ rpcpassword=%s <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> @@ -2931,66 +2959,10 @@ rpcpassword=%s <translation>Ошибка: бумажник заблокирован, невозможно создать транзакцию!</translation> </message> <message> - <source>Error: system error: </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>Failed to read block info</source> - <translation>Не удалось прочитать информацию блока</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Не удалось прочитать блок</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Не удалось синхронизировать индекс блоков</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Не удалось записать индекс блоков</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Не удалось записать информацию блока</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Не удалось записать блок</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Не удалось записать информацию файла</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Не удалось записать БД монет</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Не удалось записать индекс транзакций</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Не удалось записать данные для отмены</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Принудительный безопасный режим (по умолчанию: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Включить добычу монет (по умолчанию: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Сколько блоков проверять при запуске (по умолчанию: 288, 0 = все)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Если <category> не предоставлена, выводить всю отладочную информацию.</translation> </message> @@ -3011,8 +2983,8 @@ rpcpassword=%s <translation>Недостаточно файловых дескрипторов.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Дописывать отметки времени к отладочному выводу (по умолчанию: 1)</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>Соединяться только по сети <net> (ipv4, ipv6 или onion)</translation> </message> <message> <source>Rebuild block chain index from current blk000??.dat files</source> @@ -3027,26 +2999,18 @@ rpcpassword=%s <translation>Задать максимальный размер блока в байтах (по умолчанию: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Задать число потоков выполнения(по умолчанию: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Укажите файл бумажника (внутри каталога данных)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Тратить неподтвержденную сдачу при отправке транзакций (по умолчанию: 1)</translation> - </message> - <message> - <source>Stop running after importing blocks from disk (default: 0)</source> - <translation>Остановиться после импорта блоков с диска (по умолчанию: 0)</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> + <message> <source>Verifying blocks...</source> <translation>Проверка блоков...</translation> </message> @@ -3060,7 +3024,7 @@ rpcpassword=%s </message> <message> <source>Wallet options:</source> - <translation>Опции бумажника:</translation> + <translation>Настройки бумажника:</translation> </message> <message> <source>You need to rebuild the database using -reindex to change -txindex</source> @@ -3071,10 +3035,6 @@ rpcpassword=%s <translation>Импортировать блоки из внешнего файла blk000??.dat</translation> </message> <message> - <source>(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> - <translation>(по умолчанию: 1, 1 = сохранять метаданные транзакции, например, владельца аккаунта и информацию запроса платежа, 2 = отбросить метаданные)</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>Разрешить подключения JSON-RPC с указанного источника. Разрешённые значения для <ip> — отдельный IP (например, 1.2.3.4), сеть/маска сети (например, 1.2.3.4/255.255.255.0) или сеть/CIDR (например, 1.2.3.4/24). Эту опцию можно использовать многократно</translation> </message> @@ -3095,12 +3055,12 @@ rpcpassword=%s <translation>Не удалось установить блокировку на каталог данных %s. Возможно, Bitcoin Core уже запущен.</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> + <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> + <translation>Ограничить скорость передачи бесплатных транзакций до <n>*1000 байт в минуту (по умолчанию: %u)</translation> </message> <message> - <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> - <translation>Распространяется под лицензией MIT/X11, см. приложенный файл COPYING или <http://www.opensource.org/licenses/mit-license.php>.</translation> + <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>Error: Listening for incoming connections failed (listen returned error %s)</source> @@ -3111,10 +3071,6 @@ rpcpassword=%s <translation>Ошибка: обнаружен неподдерживаемый аргумент -socks. Выбор версии SOCKS более невозможен, поддерживаются только прокси SOCKS5.</translation> </message> <message> - <source>Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)</source> - <translation>Выполнить команду, когда транзакция из сети повторно тратит вход транзакции в бумажнике (%s=TxID транзакции сети, %t=TxID транзакции в бумажнике)</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>Выполнить команду, когда приходит соответствующее сообщение о тревоге или наблюдается очень длинное расщепление цепи (%s в команде заменяется на сообщение)</translation> </message> @@ -3127,12 +3083,8 @@ rpcpassword=%s <translation>Комиссии (в BTC/Кб) меньшие этого значения считаются нулевыми для создания транзакции (по умолчанию: %s)</translation> </message> <message> - <source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: 1)</source> - <translation>Если paytxfee не задан, включить достаточную комиссию для подтверждения транзакции в среднем за n блоков (по умолчанию: 1)</translation> - </message> - <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Выводить отладочную информацию (по умолчанию: 0, указание <category> необязательно)</translation> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>Наибольший размер данных в носителе данных транзакций, которые мы передаем и генерируем (по умолчанию: %u)</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> @@ -3143,6 +3095,10 @@ rpcpassword=%s <translation>Задать максимальный размер высокоприоритетных/низкокомиссионных транзакций в байтах (по умолчанию: %d)</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>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> @@ -3151,18 +3107,10 @@ rpcpassword=%s <translation>Внимание: убедитесь, что дата и время на Вашем компьютере выставлены верно. Если Ваши часы идут неправильно, Bitcoin Core будет работать некорректно.</translation> </message> <message> - <source>Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.</source> - <translation>Вносить в белый список участников, подключающихся с указанной маски сети или ip. Можно использовать многократно.</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>Участники из белого списка не могуть быть забанены за DoS, и их транзакции всегда транслируются, даже если они уже содержатся в памяти. Полезно, например, для шлюза.</translation> </message> <message> - <source>Always query for peer addresses via DNS lookup (default: 0)</source> - <translation>Всегда запрашивать адреса участников с помощью DNS (по умолчанию: 0)</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Не удаётся разрешить адрес в параметре -whitebind: '%s'</translation> </message> @@ -3191,10 +3139,6 @@ rpcpassword=%s <translation>Комиссия (в BTC/Кб) для добавления к вашим транзакциям (по умолчанию: %s)</translation> </message> <message> - <source>Include IP addresses in debug output (default: 0)</source> - <translation>Включать IP-адреса в отладочный вывод (по умолчанию: 0)</translation> - </message> - <message> <source>Information</source> <translation>Информация</translation> </message> @@ -3223,24 +3167,8 @@ rpcpassword=%s <translation>Хранить максимум <n> несоединённых блоков в памяти (по умолчанию: %u)</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Ограничить размер кэша подписей <n> записями (по умолчанию: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Записывать в лог приоритет транзакции и комиссию на килобайт во время добычи блоков (по умолчанию: 0)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Держать полный индекс транзакций (по умолчанию: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Максимальный размер буфера приёма на соединение, <n>*1000 байт (по умолчанию: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Максимальный размер буфера отправки на соединение, <n>*1000 байт (по умолчанию: 1000)</translation> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Держать в памяти до <n> несвязных транзакций (по умолчанию: %u)</translation> </message> <message> <source>Need to specify a port with -whitebind: '%s'</source> @@ -3251,22 +3179,10 @@ rpcpassword=%s <translation>Параметры трансляции узла:</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Принимать цепь блоков, только если она соответствует встроенным контрольным точкам (по умолчанию: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Подключаться только к узлам из сети <net> (IPv4, IPv6 или Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>Печатать блок при запуске, если он найден в индексе блоков</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Печатать дерево блоков при запуске (по умолчанию: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>Параметры RPC SSL: (см. Bitcoin вики для инструкций по настройке SSL)</translation> </message> @@ -3283,28 +3199,12 @@ rpcpassword=%s <translation>Случайно разбрасывать 1 из каждых <n> сетевых сообщений</translation> </message> <message> - <source>Relay and mine data carrier transactions (default: 1)</source> - <translation>Транслировать и генерировать транзакции носители данных (по умолчанию: 1)</translation> - </message> - <message> - <source>Relay non-P2SH multisig (default: 1)</source> - <translation>Транслировать не-P2SH мультиподпись (по умолчанию: 1)</translation> - </message> - <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Запустить поток для периодического сохранения бумажника (по умолчанию: 1)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Выводить информацию трассировки/отладки на консоль вместо файла debug.log</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Минимальный размер блока в байтах (по умолчанию: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Установить флаг DB_PRIVATE в окружении базы данных бумажника (по умолчанию: 1)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Осуществить транзакцию бесплатно, если возможно (по умолчанию: %u)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> @@ -3319,14 +3219,6 @@ rpcpassword=%s <translation>Не удалось подписать транзакцию</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Тайм-аут соединения в миллисекундах (по умолчанию: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Системная ошибка:</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Это экспериментальное ПО.</translation> </message> @@ -3347,10 +3239,6 @@ rpcpassword=%s <translation>Невозможно привязаться к %s на этом компьютере (bind вернул ошибку %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Использовать UPnP для проброса порта (по умолчанию: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Использовать UPnP для проброса порта (по умолчанию: 1, если используется прослушивание)</translation> </message> @@ -3403,10 +3291,6 @@ rpcpassword=%s <translation>Обновить бумажник до последнего формата</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Установить размер запаса ключей в <n> (по умолчанию: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Перепроверить цепь блоков на предмет отсутствующих в бумажнике транзакций</translation> </message> @@ -3415,14 +3299,6 @@ rpcpassword=%s <translation>Использовать OpenSSL (https) для подключений JSON-RPC</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Файл серверного сертификата (по умолчанию: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Приватный ключ сервера (по умолчанию: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Эта справка</translation> </message> @@ -3439,14 +3315,174 @@ rpcpassword=%s <translation>Ошибка загрузки wallet.dat: Бумажник поврежден</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 = сохранять метаданные транзакции: например, владельца аккаунта и информацию запроса платежа; 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>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source> + <translation>Если paytxfee не задан, включить достаточную комиссию для подтверждения транзакции в среднем за n блоков (по умолчанию: %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> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Число секунд блокирования неправильно ведущих себя узлов (по умолчанию: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Выводить отладочную информацию (по умолчанию: %u, указание <category> необязательно)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Использовать отдельный прокси SOCKS5 для соединения с участниками через скрытые сервисы Tor (по умолчанию: %s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(по умолчанию: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Допустимые шифры (по умолчанию: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <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> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Сколько блоков проверять при запуске (по умолчанию: %u, 0 = все)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Включить IP-адреса в отладочный вывод (по умолчанию: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <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> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Принимать входящие подключения на <port> (по умолчанию: %u или %u в тестовой сети)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Поддерживать не более <n> подключений к узлам (по умолчанию: %u)</translation> + </message> + <message> + <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> + <translation>Максимальный размер буфера приёма на соединение, <n>*1000 байт (по умолчанию: %u)</translation> + </message> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <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> + <message> + <source>Print block tree on startup (default: %u)</source> + <translation>Печатать дерево блоков при запуске (по умолчанию: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Транслировать и генерировать транзакции носителей данных (по умолчанию: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <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> + <message> + <source>Server private key (default: %s)</source> + <translation>Закрытый ключ сервера (по умолчанию: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Установить размер пула ключей в <n> (по умолчанию: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <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> + <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>Spend unconfirmed change when sending transactions (default: %u)</source> + <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> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>В параметре -onlynet указана неизвестная сеть: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_sah.ts b/src/qt/locale/bitcoin_sah.ts index a951e10ab9..84b973bf92 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> <message> diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index 793cbfa377..fe7c62cd60 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> @@ -93,7 +93,11 @@ <source>Exporting Failed</source> <translation>Export zlyhal</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Nastala chyba pri pokuse uložiť zoznam adries do %1. Skúste znovu.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -180,6 +184,10 @@ <translation>Peňaženka zašifrovaná</translation> </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>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> </message> @@ -287,6 +295,10 @@ <translation>Otvoriť &URI...</translation> </message> <message> + <source>Bitcoin Core client</source> + <translation>Bitcoin Core klient</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>Importujem bloky z disku...</translation> </message> @@ -339,6 +351,10 @@ <translation>&Prijať</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>Zobraziť informácie o Bitcoin Core</translation> + </message> + <message> <source>&Show / Hide</source> <translation>Zobraziť / skryť</translation> </message> @@ -375,10 +391,6 @@ <translation>Lišta záložiek</translation> </message> <message> - <source>[testnet]</source> - <translation>[testovacia sieť]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Jadro Bitcoin</translation> </message> @@ -410,18 +422,34 @@ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> <translation>Zobraziť pomocnú správu od Bitcoin Jadra pre získanie zoznamu dostupných možností príkazového riadku</translation> </message> + <message numerus="yes"> + <source>%n active connection(s) to Bitcoin network</source> + <translation><numerusform>%n aktívne pripojenie do siete Bitcoin</numerusform><numerusform>%n aktívne pripojenia do siete Bitcoin</numerusform><numerusform>%n aktívnych pripojení do siete Bitcoin</numerusform></translation> + </message> <message> <source>No block source available...</source> <translation>Nedostupný zdroj blokov...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Spracovaných %1 blokov transakčnej histórie.</translation> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n hodina</numerusform><numerusform>%n hodiny</numerusform><numerusform>%n hodín</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n deň</numerusform><numerusform>%n dni</numerusform><numerusform>%n dní</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <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> <translation> %1 a %2</translation> </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n rok</numerusform><numerusform>%n roky</numerusform><numerusform>%n rokov</numerusform></translation> + </message> <message> <source>%1 behind</source> <translation>%1 pozadu</translation> @@ -492,10 +520,6 @@ Adresa: %4</translation> <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Coin Control výber adresy</translation> - </message> - <message> <source>Quantity:</source> <translation>Množstvo:</translation> </message> @@ -540,10 +564,6 @@ Adresa: %4</translation> <translation>Suma</translation> </message> <message> - <source>Address</source> - <translation>Adresa</translation> - </message> - <message> <source>Date</source> <translation>Dátum</translation> </message> @@ -863,15 +883,7 @@ Adresa: %4</translation> <source>Error</source> <translation>Chyba</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB dostupného voľného miesta</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(z %1GB potrebných)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -906,14 +918,6 @@ Adresa: %4</translation> <translation>&Hlavné</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Voliteľný transakčný poplatok za kB ktorý pomôže rýchlemu spracovaniu transakcie. Väčšina transakcií má 1 kB. Poplatok 0.01 je odporúčaný.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Zaplatiť transakčné &poplatky</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> @@ -934,14 +938,6 @@ Adresa: %4</translation> <translation>Počet skript overujucich vlákien</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Pripojiť k Bitcoin sieti cez SOCKS proxy.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>Pripojiť sa cez SOCKS proxy (predvolené proxy)</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>IP adresy proxy (napr. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1105,10 +1101,6 @@ Adresa: %4</translation> <translation>Zobrazené informácie môžu byť neaktuápne. Vaša peňaženka sa automaticky synchronizuje so sieťou Bitcoin po nadviazaní spojenia ale tento proces ešte nieje ukončený.</translation> </message> <message> - <source>Wallet</source> - <translation>Peňaženka</translation> - </message> - <message> <source>Available:</source> <translation>Disponibilné:</translation> </message> @@ -1141,10 +1133,6 @@ Adresa: %4</translation> <translation>Váš súčasný celkový zostatok</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Nedávne transakcie</b></translation> - </message> - <message> <source>out of sync</source> <translation>nesynchronizované</translation> </message> @@ -2390,26 +2378,10 @@ Adresa: %4</translation> <translation>Možnosti:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Určiť súbor s nastaveniami (predvolené: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Určiť súbor pid (predvolené: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Určiť priečinok s dátami</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Načúvať spojeniam na <port> (prednastavené: 8333 alebo testovacia sieť: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Udržiavať maximálne <n> spojení (predvolené: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Pripojiť sa k nóde, získať adresy ďaľších počítačov v sieti a odpojit sa.</translation> </message> @@ -2418,18 +2390,6 @@ Adresa: %4</translation> <translation>Určite vašu vlastnú verejnú adresu</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Hranica pre odpojenie zle sa správajúcich peerov (predvolené: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Počet sekúnd kedy sa zabráni zle sa správajúcim peerom znovupripojenie (predvolené: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Počúvať JSON-RPC spojeniam na <port> (predvolené: 8332 or testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Prijímať príkazy z príkazového riadku a JSON-RPC</translation> </message> @@ -2470,18 +2430,10 @@ napríklad: alertnotify=echo %%s | mail -s "Bitcoin Výstraha" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Prijateľlné šifry (prednastavené: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Spojiť s danou adresou a vždy na nej počúvať. Použite zápis [host]:port pre IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Priebežne obmedzuj transakcie bez poplatku na <n>*1000 bajtov za minútu (prednastavené: 15)</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> </message> @@ -2498,14 +2450,6 @@ napríklad: alertnotify=echo %%s | mail -s "Bitcoin Výstraha" admin@foo.com <translation>Vykonaj príkaz keď sa zmení transakcia peňaženky (%s v príkaze je nahradená TxID)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Odložiť aktivitu databázy spoločnej pamäti do logu na disku každých <n> megabajtov (prednastavené: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Ako dôkladne sú overované bloky -checkblocks (0-4, prednastavené: 3)</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> </message> @@ -2514,10 +2458,6 @@ napríklad: alertnotify=echo %%s | mail -s "Bitcoin Výstraha" admin@foo.com <translation>Nastaviť počeť vlákien overujúcich skripty (%u až %d, 0 = auto, <0 = nechať toľkoto jadier voľných, prednastavené: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Nastaviť obmedzenie pre procesor keď je zapnuté generovanie (-1 = bez obmedzenia, prednastavené: -1)</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>Toto je pred-testovacia verzia - použitie je na vlastné riziko - nepoužívajte na tvorbu bitcoin ani obchodovanie.</translation> </message> @@ -2526,10 +2466,6 @@ napríklad: alertnotify=echo %%s | mail -s "Bitcoin Výstraha" admin@foo.com <translation>Nepodarilo sa pripojiť na %s na tomto počítači. Bitcoin Jadro je už pravdepodobne spustené.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Použite rozdielne SOCKS5 proxy pre dosiahnutie peer-ov cez Tor skryté služby (prednastavené: -proxy)</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>Varovanie: -paytxfee je nastavené veľmi vysoko. Toto sú transakčné poplatky ktoré zaplatíte ak odošlete transakciu.</translation> </message> @@ -2556,10 +2492,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>(predvolené: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(predvolené: wallet.dat)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> môže byť:</translation> </message> @@ -2588,10 +2520,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Možnosti ladenia/testovania:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Vypnúť bezpečný režim, vypnúť udalosť skutočný bezpečný režim (prednastavené: 0)</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> @@ -2628,66 +2556,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Chyba: Peňaženka je zamknutá, nemôžem vytvoriť transakciu!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Chyba: systémová chyba:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Chyba počúvania na ktoromkoľvek porte. Použi -listen=0 ak toto chcete.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Zlyhalo čítanie info o bloku</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Zlyhalo čítanie bloku</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Zlyhalo synchronizovanie zoznamu blokov</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Zlyhalo zapisovanie do zoznamu blokov</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Zlyhal zápis info o bloku</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Zlyhal zápis bloku</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Zlyhalo zapisovanie informácié o súbore</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Zlyhalo zapisovanie do databázy coins</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Zlyhal zápis zoznamu transakcií</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Zlyhalo zapisovanie </translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Vnútiť bezpečný režim (prenastavené: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Vytvárať mince (predvolené: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Koľko blokov skontrolovať pri spustení (predvolené: 288, 0 = všetky)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Ak nie je uvedená <category>, na výstupe zobrazuj všetky informácie pre ladenie.</translation> </message> @@ -2708,10 +2580,6 @@ 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>Prepend debug output with timestamp (default: 1)</source> - <translation>Na začiatok logu pre ladenie vlož dátum a čas (prednastavené: 1)</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> </message> @@ -2724,18 +2592,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Nastaviť najväčšiu veľkosť bloku v bytoch (predvolené: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Nastaviť množstvo vlákien na obsluhu RPC volaní (predvolené: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Označ súbor peňaženky (v priečinku s dátami)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Míňať nepotvrdený výdavok pri odosielaní (prednastavené: 1)</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> </message> @@ -2772,10 +2632,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Vykonať príkaz keď po prijatí patričné varovanie alebo vidíme veľmi dlhé rozdvojenie siete (%s v cmd je nahradené správou)</translation> </message> <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Výstup informácií pre ladenie (prednastavené: 0, uvádzanie <category> je voliteľné)</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> @@ -2792,42 +2648,10 @@ 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>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Obmedziť veľkosť pomocnej pamäti pre podpisy na <n> vstupov (prednastavené: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Zaznamenávať dôležitosť transakcií a poplatky za kB ak hľadáme bloky (prednastavené: 0)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Udržiavaj úplný zoznam transakcií (prednastavené: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maximálna veľkosť prijímacieho zásobníka pre jedno spojenie, <n>*1000 bytov (predvolené: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maximálna veľkosť vysielacieho zásobníka pre jedno spojenie, <n>*1000 bytov (predvolené: 1000)</translation> - </message> - <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Akceptuj iba kontrolné body zhodné s blockchain (prednastavené: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Pripájať sa len k nódam v sieti <net> (IPv4, IPv6 alebo Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>Vytlač blok pri spustení, ak nájdený v zozname blokov</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Vytlačiť strom blokov pri spustení (prednastavené: 0)</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> @@ -2844,22 +2668,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Náhodne premiešaj 1 z každých <n> sieťových správ</translation> </message> <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Mať spustené vlákno pravidelného čístenia peňaženky (predvolené: 1)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Odoslať trace/debug informácie na konzolu namiesto debug.info žurnálu</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Nastaviť minimálnu veľkosť bloku v bytoch (predvolené: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Nastaví DB_PRIVATE možnosť v db prostredí peňaženky (prednastavené: 1)</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> @@ -2872,14 +2684,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Podpísanie správy zlyhalo</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Určiť aut spojenia v milisekundách (predvolené: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Systémová chyba:</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Suma transakcie príliš malá</translation> </message> @@ -2892,10 +2696,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Transakcia príliš veľká</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Skúsiť použiť UPnP pre mapovanie počúvajúceho portu (default: 0)</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> @@ -2936,10 +2736,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Aktualizuj peňaženku na najnovší formát.</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Nastaviť zásobu adries na <n> (predvolené: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Znovu skenovať reťaz blokov pre chýbajúce transakcie</translation> </message> @@ -2948,14 +2744,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Použiť OpenSSL (https) pre JSON-RPC spojenia</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Súbor s certifikátom servra (predvolené: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Súkromný kľúč servra (predvolené: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Táto pomocná správa</translation> </message> diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index f615d31343..60fc4a93e5 100644 --- a/src/qt/locale/bitcoin_sl_SI.ts +++ b/src/qt/locale/bitcoin_sl_SI.ts @@ -1,4 +1,4 @@ -<TS language="sl_SI" version="2.1"> +<TS language="sl_SI" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -331,6 +331,10 @@ <translation>&Sprejmi</translation> </message> <message> + <source>Show information about Bitcoin Core</source> + <translation>Pokaži informacije o Bitcoin Core</translation> + </message> + <message> <source>&Show / Hide</source> <translation>&Prikaži / Skrij</translation> </message> @@ -363,10 +367,6 @@ <translation>Orodna vrstica zavihkov</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Jedro Bitcoina</translation> </message> @@ -402,6 +402,10 @@ <source>%n week(s)</source> <translation><numerusform>%n teden</numerusform><numerusform>%n tedna</numerusform><numerusform>%n tedni</numerusform><numerusform>%n tednov</numerusform></translation> </message> + <message> + <source>%1 and %2</source> + <translation>%1 in %2</translation> + </message> <message numerus="yes"> <source>%n year(s)</source> <translation><numerusform>%n leto</numerusform><numerusform>%n leti</numerusform><numerusform>%n leta</numerusform><numerusform>%n let</numerusform></translation> @@ -501,12 +505,20 @@ Naslov: %4 <translation>Sprememba:</translation> </message> <message> - <source>Amount</source> - <translation>Količina</translation> + <source>(un)select all</source> + <translation>(ne)izberi vse</translation> </message> <message> - <source>Address</source> - <translation>Naslov</translation> + <source>Tree mode</source> + <translation>Drevo</translation> + </message> + <message> + <source>List mode</source> + <translation>Seznam</translation> + </message> + <message> + <source>Amount</source> + <translation>Količina</translation> </message> <message> <source>Date</source> @@ -541,6 +553,14 @@ Naslov: %4 <translation>Kopiraj ID transakcije</translation> </message> <message> + <source>Lock unspent</source> + <translation>Zakleni neporabljeno</translation> + </message> + <message> + <source>Unlock unspent</source> + <translation>Odkleni neporabljeno</translation> + </message> + <message> <source>Copy quantity</source> <translation>Kopiraj količino</translation> </message> @@ -557,6 +577,14 @@ Naslov: %4 <translation>Kopiraj prednostno mesto</translation> </message> <message> + <source>Copy dust</source> + <translation>Kopiraj prah</translation> + </message> + <message> + <source>Copy change</source> + <translation>Kopiraj drobiž</translation> + </message> + <message> <source>highest</source> <translation>najvišja</translation> </message> @@ -597,6 +625,14 @@ Naslov: %4 <translation>(%1 zaklenjeno)</translation> </message> <message> + <source>none</source> + <translation>Nič</translation> + </message> + <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>Se lahko razlikuje +/- %1 satošijev na vnos.</translation> + </message> + <message> <source>yes</source> <translation>da</translation> </message> @@ -609,10 +645,30 @@ Naslov: %4 <translation>V primeru, da je velikost transakcije večja od 1000 bitov, se ta oznaka se obarva rdeče.</translation> </message> <message> + <source>Can vary +/- 1 byte per input.</source> + <translation>Se lahko razlikuje +/- 1 byte na vnos.</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> </message> - </context> + <message> + <source>change from %1 (%2)</source> + <translation>drobiž od %1 (%2)</translation> + </message> + <message> + <source>(change)</source> + <translation>(drobiž)</translation> + </message> +</context> <context> <name>EditAddressDialog</name> <message> @@ -628,6 +684,10 @@ Naslov: %4 <translation>Oznaka je povezana s tem vnosom seznama 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> + </message> + <message> <source>&Address</source> <translation>&Naslov</translation> </message> @@ -663,10 +723,26 @@ Naslov: %4 <context> <name>FreespaceChecker</name> <message> + <source>A new data directory will be created.</source> + <translation>Ustvarjena bo nova mapa za shranjevanje podatkov.</translation> + </message> + <message> <source>name</source> <translation>ime</translation> </message> - </context> + <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> + </message> + <message> + <source>Path already exists, and is not a directory.</source> + <translation>Pot že obstaja, vendar ni mapa.</translation> + </message> + <message> + <source>Cannot create data directory here.</source> + <translation>Na tem mestu ne moreš ustvariti nove mape.</translation> + </message> +</context> <context> <name>HelpMessageDialog</name> <message> @@ -678,6 +754,10 @@ Naslov: %4 <translation>različica</translation> </message> <message> + <source>(%1-bit)</source> + <translation>(%1-bit)</translation> + </message> + <message> <source>About Bitcoin Core</source> <translation>O jedru Bitcoina</translation> </message> @@ -705,7 +785,19 @@ Naslov: %4 <source>Start minimized</source> <translation>Zaženi pomanjšano</translation> </message> - </context> + <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> <message> @@ -717,16 +809,32 @@ Naslov: %4 <translation>Dobrodošli v jedru Bitcoina</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> + </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> + </message> + <message> + <source>Use the default data directory</source> + <translation>Uporabi privzeto mapo za shranjevanje podatkov.</translation> + </message> + <message> + <source>Use a custom data directory:</source> + <translation>Uporabi to mapo za shranjevanje podatkov:</translation> + </message> + <message> <source>Bitcoin Core</source> <translation>Jedro Bitcoina</translation> </message> <message> - <source>Error</source> - <translation>Napaka</translation> + <source>Error: Specified data directory "%1" cannot be created.</source> + <translation>Napaka: Ne morem ustvariti mape "%1".</translation> </message> <message> - <source>GB of free space available</source> - <translation>GB prostora na voljo</translation> + <source>Error</source> + <translation>Napaka</translation> </message> </context> <context> @@ -743,7 +851,15 @@ Naslov: %4 <source>URI:</source> <translation>URI:</translation> </message> - </context> + <message> + <source>Select payment request file</source> + <translation>Izberi datoteko plačilnega zahtevka</translation> + </message> + <message> + <source>Select payment request file to open</source> + <translation>Izberi datoteko plačilnega zahtevka</translation> + </message> +</context> <context> <name>OptionsDialog</name> <message> @@ -755,10 +871,6 @@ Naslov: %4 <translation>&Glavno</translation> </message> <message> - <source>Pay transaction &fee</source> - <translation>Nakazilo plačila & provizija</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> @@ -767,10 +879,30 @@ Naslov: %4 <translation>&Zaženi Bitcoin ob prijavi v sistem</translation> </message> <message> + <source>Size of &database cache</source> + <translation>Velikost lokalne zbirke &podatkovne baze</translation> + </message> + <message> <source>MB</source> <translation>megabite</translation> </message> <message> + <source>Accept connections from outside</source> + <translation>Sprejmi povezave od zunaj</translation> + </message> + <message> + <source>Allow incoming connections</source> + <translation>Dovoli prihajajoče 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> + </message> + <message> + <source>&Reset Options</source> + <translation>&Opcije resetiranja</translation> + </message> + <message> <source>&Network</source> <translation>&Omrežje</translation> </message> @@ -783,6 +915,10 @@ Naslov: %4 <translation>Poznavalec</translation> </message> <message> + <source>Enable coin &control features</source> + <translation>Omogoči Coin & Control funkcijo</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> </message> @@ -850,6 +986,10 @@ Naslov: %4 <source>default</source> <translation>privzeto</translation> </message> + <message> + <source>none</source> + <translation>Nič</translation> + </message> </context> <context> <name>OverviewPage</name> @@ -862,8 +1002,8 @@ Naslov: %4 <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> </message> <message> - <source>Wallet</source> - <translation>Denarnica</translation> + <source>Watch-only:</source> + <translation>Samo gledanje</translation> </message> <message> <source>Available:</source> @@ -886,10 +1026,6 @@ Naslov: %4 <translation>Vaše trenutno skupno stanje</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Nedavne transakcije</></translation> - </message> - <message> <source>out of sync</source> <translation>iz sinhronizacije</translation> </message> @@ -1105,14 +1241,6 @@ Naslov: %4 <translation>nikoli</translation> </message> <message> - <source>Yes</source> - <translation>Da</translation> - </message> - <message> - <source>No</source> - <translation>Ne</translation> - </message> - <message> <source>Unknown</source> <translation>Neznano</translation> </message> @@ -1349,6 +1477,10 @@ Naslov: %4 <translation>Kopiraj prednostno mesto</translation> </message> <message> + <source>Copy change</source> + <translation>Kopiraj drobiž</translation> + </message> + <message> <source>or</source> <translation>ali</translation> </message> @@ -1373,6 +1505,10 @@ Naslov: %4 <translation>(ni oznake)</translation> </message> <message> + <source>Copy dust</source> + <translation>Kopiraj prah</translation> + </message> + <message> <source>Are you sure you want to send?</source> <translation>Ali ste prepričani, da želite poslati?</translation> </message> @@ -1923,26 +2059,10 @@ Naslov: %4 <translation>Možnosti:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Določi datoteko z nastavitvami (privzeta: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Določi pid datoteko (privzeta: bitcoin.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Določi podatkovni imenik</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Sprejmi povezave na <port> (privzeta vrata: 8333 ali testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Obdrži maksimalno število <n> povezav (privzeto: 125)</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> </message> @@ -1951,14 +2071,6 @@ Naslov: %4 <translation>Določite vaš lasten javni naslov</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Prag za prekinitev povezav s slabimi odjemalci (privzeto: 1000)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Število sekund za težavo pri vzpostavitvi povezave med uporabniki (privzeto: 86400)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Sprejmi ukaze iz ukazne vrstice in JSON-RPC</translation> </message> @@ -1987,10 +2099,6 @@ Naslov: %4 <translation>To je pred izdana poizkusna verzija - uporaba na lastno odgovornost - ne uporabljajte je za rudarstvo ali trgovske aplikacije</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Za doseg soležnikov preko Tor skritih storitev uporabi ločen SOCKS5 proxy (privzeto: -proxy)</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> </message> @@ -1999,12 +2107,8 @@ Naslov: %4 <translation>(privzeto: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(privzeto: wallet.dat)</translation> - </message> - <message> <source><category> can be:</source> - <translation><kategorija> je lahko:</translation> + <translation><category> je lahko:</translation> </message> <message> <source>Block creation options:</source> @@ -2019,22 +2123,6 @@ Naslov: %4 <translation>Opozorilo: Denarnica je zaklenjena, ni mogoče opraviti transkacijo! </translation> </message> <message> - <source>Error: system error: </source> - <translation>Napaka: sistemska napaka:</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Zapisovanje informacij o datoteki neuspešno</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Neuspešno zapisovanje na bazi podatkov kovancev</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Ustvari kovance (privzeto: 0)</translation> - </message> - <message> <source>Importing...</source> <translation>Uvažam...</translation> </message> @@ -2051,10 +2139,6 @@ Naslov: %4 <translation>Podpisovanje transakcije spodletelo</translation> </message> <message> - <source>System error: </source> - <translation>Sistemska napaka:</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Količina transakcije je pramajhna</translation> </message> @@ -2095,10 +2179,6 @@ Naslov: %4 <translation>Posodobi denarnico v najnovejši zapis</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Nastavi velikost ključa bazena na <n> (privzeto: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Ponovno preglej verigo blokov za manjkajoče transakcije denarnice</translation> </message> @@ -2107,14 +2187,6 @@ Naslov: %4 <translation>Uporabi OpenSSL (https) za JSON-RPC povezave</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Datoteka potrdila strežnika (privzeta: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Zasebni ključ strežnika (privzet: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>To sporočilo pomoči</translation> </message> diff --git a/src/qt/locale/bitcoin_sq.ts b/src/qt/locale/bitcoin_sq.ts index f779e391c0..7e63f239ca 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> @@ -163,10 +163,6 @@ <translation>Shiriti i mjeteve</translation> </message> <message> - <source>[testnet]</source> - <translation>[testo rrjetin]</translation> - </message> - <message> <source>Up to date</source> <translation>I azhornuar</translation> </message> @@ -201,10 +197,6 @@ <translation>Sasia</translation> </message> <message> - <source>Address</source> - <translation>Adresë</translation> - </message> - <message> <source>Date</source> <translation>Data</translation> </message> @@ -281,10 +273,6 @@ <source>Form</source> <translation>Formilarë</translation> </message> - <message> - <source><b>Recent transactions</b></source> - <translation><b>Transaksionet e fundit</b></translation> - </message> </context> <context> <name>PaymentServer</name> diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts index f5723efece..b005ce23ad 100644 --- a/src/qt/locale/bitcoin_sr.ts +++ b/src/qt/locale/bitcoin_sr.ts @@ -1,17 +1,33 @@ -<TS language="sr" version="2.1"> +<TS language="sr" version="2.0"> <context> <name>AddressBookPage</name> <message> <source>Double-click to edit address or label</source> - <translation>Кликните два пута да промените адресу и/или етикету</translation> + <translation>Kliknite dva puta da izmenite adresu ili etiketu</translation> </message> <message> <source>Create a new address</source> - <translation>Прави нову адресу</translation> + <translation>Napravite novu adresu</translation> + </message> + <message> + <source>&New</source> + <translation>Novo</translation> </message> <message> <source>Copy the currently selected address to the system clipboard</source> - <translation>Копира изабрану адресу на системски клипборд</translation> + <translation>Kopirajte trenutno izabranu adresu</translation> + </message> + <message> + <source>&Copy</source> + <translation>Kopirajte</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>Kopirajte adresu</translation> + </message> + <message> + <source>Delete the currently selected address from the list</source> + <translation>Izbrisite trenutno izabranu adresu sa liste</translation> </message> <message> <source>&Delete</source> @@ -219,10 +235,6 @@ <translation>Трака са картицама</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Up to date</source> <translation>Ажурно</translation> </message> @@ -269,10 +281,6 @@ Address: %4 <translation>iznos</translation> </message> <message> - <source>Address</source> - <translation>Адреса</translation> - </message> - <message> <source>Date</source> <translation>datum</translation> </message> @@ -330,6 +338,10 @@ Address: %4 <translation>верзија</translation> </message> <message> + <source>About Bitcoin Core</source> + <translation>O Bitcoin Coru</translation> + </message> + <message> <source>Usage:</source> <translation>Korišćenje:</translation> </message> @@ -361,14 +373,6 @@ Address: %4 <source>Form</source> <translation>Форма</translation> </message> - <message> - <source>Wallet</source> - <translation>новчаник</translation> - </message> - <message> - <source><b>Recent transactions</b></source> - <translation><b>Недавне трансакције</b></translation> - </message> </context> <context> <name>PaymentServer</name> @@ -763,27 +767,10 @@ Address: %4 <translation>Opcije</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Potvrdi željeni konfiguracioni fajl (podrazumevani:bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Konkretizuj pid fajl (podrazumevani: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Gde je konkretni data direktorijum </translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Slušaj konekcije na <port> (default: 8333 or testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Održavaj najviše <n> konekcija po priključku (default: 125) -</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Prihvati komandnu liniju i JSON-RPC komande</translation> </message> @@ -804,10 +791,6 @@ Address: %4 <translation>Lozinka za JSON-RPC konekcije</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Odredi veličinu zaštićenih ključeva na <n> (default: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Ponovo skeniraj lanac blokova za nedostajuće transakcije iz novčanika</translation> </message> @@ -816,10 +799,6 @@ Address: %4 <translation>Koristi OpenSSL (https) za JSON-RPC konekcije</translation> </message> <message> - <source>Server private key (default: server.pem)</source> - <translation>privatni ključ za Server (podrazumevan: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Ova poruka Pomoći</translation> </message> diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index 8e771c5ce7..551f6976cf 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> @@ -392,10 +392,6 @@ Var vänlig och försök igen.</translation> <translation>Verktygsfält för Tabbar</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Kärna</translation> </message> @@ -435,10 +431,6 @@ Var vänlig och försök igen.</translation> <source>No block source available...</source> <translation>Ingen block-källa tillgänglig...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Bearbetat %1 block i transaktionshistoriken.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n timme</numerusform><numerusform>%n timmar</numerusform></translation> @@ -487,6 +479,10 @@ 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> @@ -530,8 +526,8 @@ Adress: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Adressval för myntkontroll</translation> + <source>Coin Selection</source> + <translation>Myntval</translation> </message> <message> <source>Quantity:</source> @@ -582,8 +578,12 @@ Adress: %4 <translation>Mängd</translation> </message> <message> - <source>Address</source> - <translation>Adress</translation> + <source>Received with label</source> + <translation>Mottagen med etikett</translation> + </message> + <message> + <source>Received with address</source> + <translation>Mottagen med adress</translation> </message> <message> <source>Date</source> @@ -913,13 +913,13 @@ Adress: %4 <source>Error</source> <translation>Fel</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB ledigt utrymme är tillgängligt</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB fritt utrymme kvar</numerusform><numerusform>%n GB fritt utrymme kvar</numerusform></translation> </message> - <message> - <source>(of %1GB needed)</source> - <translation>(av %1GB behövs)</translation> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(av %n GB behövs)</numerusform><numerusform>(av %n GB behövs)</numerusform></translation> </message> </context> <context> @@ -956,14 +956,6 @@ Adress: %4 <translation>&Allmänt</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Valfri transaktionsavgift per kB som ser till att dina transaktioner behandlas snabbt. De flesta transaktioner är 1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Betala överförings&avgift</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>Starta Bitcoin automatiskt efter inloggning.</translation> </message> @@ -992,14 +984,6 @@ Adress: %4 <translation>Acceptera inkommande anslutningar</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Anslut till Bitcoin-nätverket genom en SOCKS-proxy.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>&Anslut genom SOCKS-proxy (förvald proxy):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>Proxyns IP-adress (t.ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1060,6 +1044,14 @@ Adress: %4 <translation>Tilldela port med hjälp av &UPnP</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Anslut till Bitcoin-nätverket genom en SOCKS5-proxy.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Anslut genom SOCKS5-proxy (förvald proxy):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>Proxy-&IP: </translation> </message> @@ -1163,10 +1155,6 @@ Adress: %4 <translation>Den visade informationen kan vara inaktuell. Plånboken synkroniseras automatiskt med Bitcoin-nätverket efter att anslutningen är upprättad, men denna process har inte slutförts ännu.</translation> </message> <message> - <source>Wallet</source> - <translation>Plånbok</translation> - </message> - <message> <source>Watch-only:</source> <translation>Granska-bara:</translation> </message> @@ -1195,6 +1183,10 @@ Adress: %4 <translation>Den genererade balansen som ännu inte har mognat</translation> </message> <message> + <source>Balances</source> + <translation>Balanser</translation> + </message> + <message> <source>Total:</source> <translation>Totalt:</translation> </message> @@ -1207,6 +1199,14 @@ Adress: %4 <translation>Ditt nuvarande saldo i granska-bara adresser</translation> </message> <message> + <source>Spendable:</source> + <translation>Spenderbar:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Nyligen genomförda transaktioner</translation> + </message> + <message> <source>Unconfirmed transactions to watch-only addresses</source> <translation>Okonfirmerade transaktioner till granska-bara adresser</translation> </message> @@ -1219,10 +1219,6 @@ Adress: %4 <translation>Nuvarande total balans i granska-bara adresser</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Nyligen genomförda transaktioner</b></translation> - </message> - <message> <source>out of sync</source> <translation>osynkroniserad</translation> </message> @@ -1482,10 +1478,6 @@ Adress: %4 <translation>Tjänster</translation> </message> <message> - <source>Sync Node</source> - <translation>Syncnod</translation> - </message> - <message> <source>Starting Height</source> <translation>Starthöjd</translation> </message> @@ -1614,14 +1606,6 @@ Adress: %4 <translation>Utgående</translation> </message> <message> - <source>Yes</source> - <translation>Ja</translation> - </message> - <message> - <source>No</source> - <translation>Nej</translation> - </message> - <message> <source>Unknown</source> <translation>Okänd</translation> </message> @@ -1854,6 +1838,78 @@ Adress: %4 <translation>Specialväxeladress</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Transaktionsavgift:</translation> + </message> + <message> + <source>Choose...</source> + <translation>Välj...</translation> + </message> + <message> + <source>collapse fee-settings</source> + <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> + <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>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>total at least</source> + <translation>totalt minst</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>Att betala endast den minsta avgiften är bara bra så länge det är mindre transaktionsvolym än utrymme i blocken. Men tänk på att det kan hamna i en aldrig bekräftar transaktion när det finns mer efterfrågan på bitcoin transaktioner än nätverket kan bearbeta.</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(läs verktygstips)</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Rekommenderad:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Anpassad:</translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation>(Smartavgiften är inte initierad än. Detta tar vanligen några block...)</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Bekräftelsetid:</translation> + </message> + <message> + <source>normal</source> + <translation>normal</translation> + </message> + <message> + <source>fast</source> + <translation>snabb</translation> + </message> + <message> + <source>Send as zero-fee transaction if possible</source> + <translation>Sänd som nollavgiftstransaktion om möjligt</translation> + </message> + <message> + <source>(confirmation may take longer)</source> + <translation>(bekräftelse kan ta längre tid)</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Skicka till flera mottagare samtidigt</translation> </message> @@ -1958,6 +2014,18 @@ 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> + </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> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Varning: Felaktig Bitcoinadress</translation> </message> @@ -2466,6 +2534,10 @@ Adress: %4 <translation>Genererade</translation> </message> <message> + <source>watch-only</source> + <translation>granska-bara</translation> + </message> + <message> <source>(n/a)</source> <translation>(n/a)</translation> </message> @@ -2482,6 +2554,10 @@ Adress: %4 <translation>Transaktionstyp.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Anger om granska-bara--adresser är involverade i denna transaktion.</translation> + </message> + <message> <source>Destination address of transaction.</source> <translation>Transaktionens destinationsadress.</translation> </message> @@ -2577,6 +2653,10 @@ Adress: %4 <translation>Exportera Transaktionshistoriken</translation> </message> <message> + <source>Watch-only</source> + <translation>Granska-bara</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Exporteringen misslyckades</translation> </message> @@ -2692,26 +2772,10 @@ Adress: %4 <translation>Inställningar:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Ange konfigurationsfil (förvalt: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Ange pid fil (förvalt: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Ange katalog för data</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Lyssna efter anslutningar på <port> (förvalt: 8333 eller testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Ha som mest <n> anslutningar till andra klienter (förvalt: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Anslut till en nod för att hämta klientadresser, och koppla från</translation> </message> @@ -2720,18 +2784,6 @@ Adress: %4 <translation>Ange din egen publika adress</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Tröskelvärde för att koppla ifrån klienter som missköter sig (förvalt: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Antal sekunder att hindra klienter som missköter sig från att ansluta (förvalt: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Lyssna på JSON-RPC-anslutningar på <port> (förvalt: 8332 eller testnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Tillåt kommandon från kommandotolken och JSON-RPC-kommandon</translation> </message> @@ -2772,22 +2824,18 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Accepterade krypteringsalgoritmer (förvalt: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Bind till given adress och lyssna alltid på den. Använd [värd]:port notation för IPv6</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Antalsbegränsa kontinuerligt fria transaktioner till <n>*1000 bytes per minut (förvalt:15)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Ta bort alla plånbokstransaktioner och återskapa bara dom som är en del av blockkedjan genom att ange -rescan vid uppstart</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>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> @@ -2804,14 +2852,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Exekvera kommando när en plånbokstransaktion ändras (%s i cmd är ersatt av TxID)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Töm databasens minnespool till disk varje <n> megabytes (förvalt: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>Hur grundlig blockverifikationen vid -checkblocks är (0-4, förvalt: 3)</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> </message> @@ -2820,10 +2860,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ange antalet skriptkontrolltrådar (%u till %d, 0 = auto, <0 = lämna så många kärnor lediga, förval: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Sätt processorbegränsning när blockgenereringen är på (-1 = obegränsad, förvalt: -1)</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>Detta är ett förhands testbygge - använd på egen risk - använd inte för mining eller handels applikationer</translation> </message> @@ -2832,10 +2868,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Använd separat SOCKS5 proxy för att nå kollegor via dolda tjänster i Tor (default: -proxy)</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> @@ -2856,12 +2888,12 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Varning: wallet.dat korrupt, datan har räddats! Den ursprungliga wallet.dat har sparas som wallet.{timestamp}.bak i %s; om ditt saldo eller transaktioner är felaktiga ska du återställa från en säkerhetskopia.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(förvalt: 1)</translation> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Vitlista klienter som ansluter från angivna nätmasker eller IP-adresser. Kan specificeras flera gånger.</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(förvalt: wallet.dat)</translation> + <source>(default: 1)</source> + <translation>(förvalt: 1)</translation> </message> <message> <source><category> can be:</source> @@ -2892,10 +2924,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Avlusnings/Testnings optioner:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Avaktivera säkert läge. Åsidosätt en riktigt säkert läge händelse (förvalt: 0)</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> @@ -2924,6 +2952,10 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Fel vid öppning av blockdatabasen</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Fel: Ett fatalt internt fel inträffade. Se debug.log för detaljer</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Fel: Hårddiskutrymme är lågt!</translation> </message> @@ -2932,66 +2964,10 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Fel: Plånboken är låst, det går ej att skapa en transaktion!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Fel: systemfel:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Misslyckades att lyssna på någon port. Använd -listen=0 om du vill detta.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Misslyckades att läsa blockinformation</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Misslyckades att läsa blocket</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Misslyckades att synkronisera blockindex</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Misslyckades att skriva blockindex</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Misslyckades att skriva blockinformation</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Misslyckades att skriva blocket</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Misslyckades att skriva filinformation</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Misslyckades att skriva till myntdatabas</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Misslyckades att skriva transaktionsindex</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Misslyckades att skriva ångradata</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Tvångskör i säkert läge (förvalt: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Generera mynt (förvalt: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Hur många block att kontrollera vid uppstart (standardvärde: 288, 0 = alla)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>Om <category> inte anges, skrivs all avlusningsinformation ut.</translation> </message> @@ -3012,8 +2988,8 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Inte tillräckligt med filbeskrivningar tillgängliga.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Skriv ut tidsstämpel i avlusningsinformationen (förvalt: 1)</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <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> @@ -3028,26 +3004,18 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Sätt maximal blockstorlek i byte (förvalt: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Ange antalet trådar för att hantera RPC anrop (standard: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Ange plånboksfil (inom datakatalogen)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Spendera okonfirmerad växel när transaktioner sänds (förvalt: 1)</translation> - </message> - <message> - <source>Stop running after importing blocks from disk (default: 0)</source> - <translation>Sluta köra efter importen av block från disk är klar (förvalt: 0)</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> + <message> <source>Verifying blocks...</source> <translation>Verifierar block...</translation> </message> @@ -3072,10 +3040,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Importerar block från extern blk000??.dat fil</translation> </message> <message> - <source>(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> - <translation>(förvalt: 1, 1 = spara tx metadata t.ex. kontoägare och betalningsbegäransinformation, 2 = släng tx metadata)</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>Tillåt JSON-RPC anslutningar från specifik kalla. Tillåtet för <ip> är enkel IP (t.ex 1.2.3.4), en nätverk/nätmask (t.ex. 1.2.3.4/255.255.255.0) eller ett nätverk/CIDR (t.ex. 1.2.3.4/24). Denna option kan specificeras flera gånger</translation> </message> @@ -3096,12 +3060,12 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Kan inte låsa data-mappen %s. Bitcoin Core körs förmodligen redan.</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> + <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>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> - <translation>Distribuerad under MIT/X11 mjukvarulicens, se den bifogade filen COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation> + <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>Error: Listening for incoming connections failed (listen returned error %s)</source> @@ -3112,10 +3076,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Fel: Argumentet -socks stöds inte. Att sätta SOCKS version är inte möjligt längre. Endast SOCKS5 proxy stöds.</translation> </message> <message> - <source>Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)</source> - <translation>Kör kommando när en nätverks tx återspenderar plånbokens tx input (%s=återspendera TxID, %t=plånbok TxID)</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>Exekvera kommando när ett relevant meddelande är mottagen eller när vi ser en väldigt lång förgrening (%s i cmd är utbytt med ett meddelande)</translation> </message> @@ -3128,12 +3088,8 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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 are confirmed on average within n blocks (default: 1)</source> - <translation>Om paytxfee inte är satt, inkludera tillräcklig avgift så att transaktionen konfirmeras inom n blocks (förvalt: 1)</translation> - </message> - <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Skriv ut avlusningsinformation (förvalt: 0, att ange <category> är frivilligt)</translation> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>Maximal storlek på data i databärartransaktioner som vi reläar och bryter (förvalt: %u) </translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> @@ -3152,18 +3108,10 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Varning: Vänligen kolla så att din dators datum och tid är korrekt! Om din klocka går fel kommer Bitcoin Core inte att fungera korrekt.</translation> </message> <message> - <source>Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.</source> - <translation>Vitlista klienter som ansluter från angivna nätmasker eller ip adresser. Kan specificeras flera gånger.</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>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>Always query for peer addresses via DNS lookup (default: 0)</source> - <translation>Sök alltid efter klientadresser med DNS sökningen (förvalt: 0)</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Kan inte matcha -whitebind adress: '%s'</translation> </message> @@ -3192,10 +3140,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Avgift (i BTC/Kb) att lägga till på transaktioner du skickar (förvalt: %s)</translation> </message> <message> - <source>Include IP addresses in debug output (default: 0)</source> - <translation>Inkludera IP-adresser i debugutskrift (förvalt: 0)</translation> - </message> - <message> <source>Information</source> <translation>Information</translation> </message> @@ -3224,24 +3168,8 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Håll som mest <n> oanslutningsbara block i minnet (förvalt: %u)</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>Begränsa signaturcachestorleken till <n> poster (förvalt: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Logga transaktionsprioritet och avgift per kB vid blockbrytning (förvalt: 0)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Upprätthåll ett fullständigt transaktionsindex (förval: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Maximal buffert för mottagning per anslutning, <n>*1000 byte (förvalt: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Maximal buffert för sändning per anslutning, <n>*1000 byte (förvalt: 5000)</translation> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Håll som mest <n> oanslutningsbara transaktioner i minnet (förvalt: %u)</translation> </message> <message> <source>Need to specify a port with -whitebind: '%s'</source> @@ -3252,22 +3180,10 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Nodreläoptioner:</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Acceptera bara blockkedjans matchande inbyggda kontrollpunkter (förvalt: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Anslut enbart till noder i nätverket <net> (IPv4, IPv6 eller Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>Skriv ut block vid uppstart, om det hittas i blockindexet</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Skriv ut blockträdet vid uppstart (förvalt: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>RPC SSL optioner: (se Bitcoin Wiki för SSL inställningsinstruktioner)</translation> </message> @@ -3284,28 +3200,12 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Slupmässigt brus 1 gång varje <n> nätverksmeddelande</translation> </message> <message> - <source>Relay and mine data carrier transactions (default: 1)</source> - <translation>Reläa och bearbeta databärartransaktioner (förvalt: 1) </translation> - </message> - <message> - <source>Relay non-P2SH multisig (default: 1)</source> - <translation>Reläa icke P2SH multisig (förvalt: 1)</translation> - </message> - <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Kör en tråd för att tömma plånboken periodiskt (förvalt: 1)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Skicka trace-/debuginformation till terminalen istället för till debug.log</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Sätt minsta blockstorlek i byte (förvalt: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Sätt DB_PRIVATE flaggan i plånbokens databasmiljö (förvalt: 1)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Sänd transaktioner som nollavgiftstransaktioner om möjligt (förvalt: %u)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> @@ -3320,14 +3220,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Signering av transaktion misslyckades</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Ange timeout för uppkoppling i millisekunder (förvalt: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Systemfel:</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Detta är experimentmjukvara.</translation> </message> @@ -3348,10 +3240,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Det går inte att binda till %s på den här datorn (bind returnerade felmeddelande %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Använd UPnP för att mappa den lyssnande porten (förvalt: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Använd UPnP för att mappa den lyssnande porten (förvalt: 1 under lyssning)</translation> </message> @@ -3404,10 +3292,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Uppgradera plånboken till senaste formatet</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Sätt storleken på nyckelpoolen till <n> (förvalt: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Sök i blockkedjan efter saknade plånboks transaktioner</translation> </message> @@ -3416,14 +3300,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Använd OpenSSL (https) för JSON-RPC-anslutningar</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Serverns certifikatfil (förvalt: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Serverns privata nyckel (förvalt: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Det här hjälp medelandet</translation> </message> @@ -3440,14 +3316,178 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Fel vid inläsningen av wallet.dat: Plånboken är skadad</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 = 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>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source> + <translation>Om paytxfee inte är satt, inkludera tillräcklig avgift så att transaktionen konfirmeras inom n blocks (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> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Antal sekunder att hindra klienter som missköter sig från att ansluta (förvalt: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Skriv ut avlusningsinformation (förvalt: %u, att ange <category> är frivilligt)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Använd separat SOCKS5 proxy för att nå kollegor via dolda tjänster i Tor (förvalt: -%s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(förvalt: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Accepterbara chiffer (förvalt: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <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> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Hur många block att kontrollera vid uppstart (förvalt: %u, 0 = alla)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Inkludera IP-adresser i debugutskrift (förvalt: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <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> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Lyssna efter anslutningar på <port> (förvalt: %u eller testnet: %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Ha som mest <n> anslutningar till andra klienter (förvalt: %u)</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> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <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> + <message> + <source>Print block tree on startup (default: %u)</source> + <translation>Skriv ut blockträdet vid uppstart (förvalt: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Reläa och bearbeta databärartransaktioner (förvalt: %u) </translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <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> + <message> + <source>Server private key (default: %s)</source> + <translation>Serverns privata nyckel (förvalt: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Sätt storleken på nyckelpoolen till <n> (förvalt: %u)</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Sätt minsta blockstorlek i byte (standard: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <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> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Ange timeout för uppkoppling i millisekunder (minimum:1, förvalt: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Ange pid-fil (förvalt: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <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> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Okänt nätverk som anges i -onlynet: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts index cb52be61b2..174816aaef 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> @@ -162,10 +162,6 @@ <source>Tabs toolbar</source> <translation>แถบเครื่องมือ</translation> </message> - <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n ที่ใช้งานการเชื่อมต่อกับเครือข่าย Bitcoin</numerusform></translation> @@ -201,10 +197,6 @@ <context> <name>CoinControlDialog</name> <message> - <source>Address</source> - <translation>ที่อยู่</translation> - </message> - <message> <source>(no label)</source> <translation>(ไม่มีชื่อ)</translation> </message> @@ -277,10 +269,6 @@ <source>Form</source> <translation>รูป</translation> </message> - <message> - <source><b>Recent transactions</b></source> - <translation><b>รายการทำธุรกรรมล่าสุด</b></translation> - </message> </context> <context> <name>PaymentServer</name> diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index b2a14c92fc..ab02cc92a6 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -1,4 +1,4 @@ -<TS language="tr" version="2.1"> +<TS language="tr" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -391,10 +391,6 @@ <translation>Sekme araç çubuğu</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>Bitcoin Çekirdeği</translation> </message> @@ -434,10 +430,6 @@ <source>No block source available...</source> <translation>Hiçbir blok kaynağı mevcut değil...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Muamele tarihçesinde %1 blok işlendi.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n saat</numerusform><numerusform>%n saat</numerusform></translation> @@ -486,6 +478,10 @@ <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> @@ -529,8 +525,8 @@ Adres: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>Para kontrolü adres seçimi</translation> + <source>Coin Selection</source> + <translation>Bitcoin Seçimi</translation> </message> <message> <source>Quantity:</source> @@ -581,8 +577,12 @@ Adres: %4 <translation>Meblağ</translation> </message> <message> - <source>Address</source> - <translation>Adres</translation> + <source>Received with label</source> + <translation>Şu etiketle alındı</translation> + </message> + <message> + <source>Received with address</source> + <translation>Şu adresle alındı</translation> </message> <message> <source>Date</source> @@ -916,13 +916,13 @@ Adres: %4 <source>Error</source> <translation>Hata</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB boş alan mevcuttur</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB boş alan mevcuttur</numerusform><numerusform>%n GB boş alan mevcuttur</numerusform></translation> </message> - <message> - <source>(of %1GB needed)</source> - <translation>(gereken boyut: %1GB)</translation> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(gereken %n GB alandan)</numerusform><numerusform>(gereken %n GB alandan)</numerusform></translation> </message> </context> <context> @@ -959,14 +959,6 @@ Adres: %4 <translation>&Esas ayarlar</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Muamelelerin hızlı işlenmesini garantilemeye yardım eden, seçime dayalı kB başı muamele ücreti. Muamelelerin çoğunluğunun boyutu 1 kB'dir.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Muamele ücreti &öde</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> @@ -995,14 +987,6 @@ Adres: %4 <translation>Gelen bağlantılara izin ver</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>Bitcoin şebekesine bir SOCKS vekil sunucusu vasıtasıyla bağlan.</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>SOCKS vekil sunucusuyla &bağlan (varsayılan vekil):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>Vekil sunucusunun IP adresi (mesela IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> @@ -1063,6 +1047,14 @@ Adres: %4 <translation>Portları &UPnP kullanarak haritala</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Bitcoin şebekesine SOCKS5 vekil sunucusu vasıtasıyla bağlan.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>SOCKS5 vekil sunucusu vasıtasıyla &bağlan (varsayılan vekil sunucusu):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>Vekil &İP:</translation> </message> @@ -1166,10 +1158,6 @@ Adres: %4 <translation>Görüntülenen veriler zaman aşımına uğramış olabilir. Bağlantı kurulduğunda cüzdanınız otomatik olarak şebeke ile eşleşir ancak bu işlem henüz tamamlanmamıştır.</translation> </message> <message> - <source>Wallet</source> - <translation>Cüzdan</translation> - </message> - <message> <source>Watch-only:</source> <translation>Sadece-izlenen:</translation> </message> @@ -1198,6 +1186,10 @@ Adres: %4 <translation>Oluşturulan bakiye henüz olgunlaşmamıştır</translation> </message> <message> + <source>Balances</source> + <translation>Bakiyeler</translation> + </message> + <message> <source>Total:</source> <translation>Toplam:</translation> </message> @@ -1210,6 +1202,14 @@ Adres: %4 <translation>Sadece izlenen adreslerdeki güncel bakiyeniz</translation> </message> <message> + <source>Spendable:</source> + <translation>Harcanabilir:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Son muameleler</translation> + </message> + <message> <source>Unconfirmed transactions to watch-only addresses</source> <translation>Sadece izlenen adreslere gelen teyit edilmemiş muameleler</translation> </message> @@ -1222,10 +1222,6 @@ Adres: %4 <translation>Sadece izlenen adreslerdeki güncel toplam bakiye</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Son muameleler</b></translation> - </message> - <message> <source>out of sync</source> <translation>eşleşme dışı</translation> </message> @@ -1485,10 +1481,6 @@ Adres: %4 <translation>Servisler</translation> </message> <message> - <source>Sync Node</source> - <translation>Eşleşme Düğümü</translation> - </message> - <message> <source>Starting Height</source> <translation>Başlama Yüksekliği</translation> </message> @@ -1617,14 +1609,6 @@ Adres: %4 <translation>Giden</translation> </message> <message> - <source>Yes</source> - <translation>Evet</translation> - </message> - <message> - <source>No</source> - <translation>Hayır</translation> - </message> - <message> <source>Unknown</source> <translation>Bilinmiyor</translation> </message> @@ -1861,6 +1845,78 @@ Adres: %4 <translation>Özel para üstü adresi</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Muamele ücreti:</translation> + </message> + <message> + <source>Choose...</source> + <translation>Seç...</translation> + </message> + <message> + <source>collapse fee-settings</source> + <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> + <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ğ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>total at least</source> + <translation>toplam asgari</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>Asgari ücreti ödemek, bloklarda boşluktan daha az muamele hacmi olduğu sürece bir sorun çıkarmaz. Fakat şebekenin işleyecebileceğinden daha çok bitcoin muameleleri talebi olduğunda bunun asla teyit edilmeyen bir muamele olabileceğinin farkında olmalısınız.</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(bilgi balonunu oku)</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Tavsiye edilen:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Özel:</translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation>(Zeki ücret henüz başlatılmadı. Bu genelde birkaç blok alır...)</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Teyit süresi:</translation> + </message> + <message> + <source>normal</source> + <translation>normal</translation> + </message> + <message> + <source>fast</source> + <translation>çabuk</translation> + </message> + <message> + <source>Send as zero-fee transaction if possible</source> + <translation>Mümkünse ücretsiz muamele olarak gönder</translation> + </message> + <message> + <source>(confirmation may take longer)</source> + <translation>(teyit daha uzun süre alabilir)</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Birçok alıcıya aynı anda gönder</translation> </message> @@ -1965,6 +2021,18 @@ 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> + </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> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Uyarı: geçersiz Bitcoin adresi</translation> </message> @@ -2473,6 +2541,10 @@ Adres: %4 <translation>Madenden çıkarılan</translation> </message> <message> + <source>watch-only</source> + <translation>sadece-izlenen</translation> + </message> + <message> <source>(n/a)</source> <translation>(mevcut değil)</translation> </message> @@ -2489,6 +2561,10 @@ Adres: %4 <translation>Muamele türü.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Bu muamelede sadece izlenen bir adresin bulunup bulunmadığı.</translation> + </message> + <message> <source>Destination address of transaction.</source> <translation>Muamelenin alıcı adresi.</translation> </message> @@ -2584,6 +2660,10 @@ Adres: %4 <translation>Muamele tarihçesini dışa aktar</translation> </message> <message> + <source>Watch-only</source> + <translation>Sadece izlenen</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Dışa aktarım başarısız oldu</translation> </message> @@ -2699,26 +2779,10 @@ Adres: %4 <translation>Seçenekler:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Yapılandırma dosyası belirt (varsayılan: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Pid dosyası belirt (varsayılan: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Veri dizinini belirt</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Bağlantılar için dinlenecek <port> (varsayılan: 8333 ya da testnet: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Eşler ile en çok <n> adet bağlantı kur (varsayılan: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Eş adresleri elde etmek için bir düğüme bağlan ve ardından bağlantıyı kes</translation> </message> @@ -2727,18 +2791,6 @@ Adres: %4 <translation>Kendi genel adresinizi tanımlayın</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Aksaklık gösteren eşlerle bağlantıyı kesme sınırı (varsayılan: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Aksaklık gösteren eşlerle yeni bağlantıları engelleme süresi, saniye olarak (varsayılan: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>JSON-RPC bağlantılarını <port> üzerinde dinle (varsayılan: 8332 veya tesnet: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Komut satırı ve JSON-RPC komutlarını kabul et</translation> </message> @@ -2779,22 +2831,18 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>Kabul edilebilir şifreler (varsayılan: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>Belirtilen adrese bağlan ve daima ondan dinle. IPv6 için [makine]:port yazımını kullanınız</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>Devamlı olarak ücretsiz muameleleri dakikada <n>*1000 bayt olarak sınırla (varsayılan: 15)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>Tüm cüzdan muamelelerini sil ve başlangıçta -rescan ile sadece blok zincirinin parçası olanları geri getir</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>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> @@ -2811,14 +2859,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>Veritabanı etkinliğini bellekten disk kütüğüne her <n> megabaytta aktar (varsayılan: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>-checkblocks'un blok kontrolünün ne kadar kapsamlı olacağı (0 ilâ 4, varsayılan: 3)</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> </message> @@ -2827,10 +2867,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Betik kontrolü iş parçacıklarının sayısını belirler (%u ilâ %d, 0 = otomatik, <0 = bu sayıda çekirdeği kullanma, varsayılan: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>Oluşturma etkinken işlemci sınırını belirler (-1 = sınırsız, varsayılan: -1)</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>Bu yayın öncesi bir deneme sürümüdür - tüm riski siz üstlenmiş olursunuz - bitcoin oluşturmak ya da ticari uygulamalar için kullanmayınız</translation> </message> @@ -2839,10 +2875,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Bu bilgisayarda %s unsuruna bağlanılamadı. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır.</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>Eşlere gizli Tor servisleri ile ulaşmak için ayrı SOCKS5 vekil sunucusu kullan (varsayılan: -proxy)</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> @@ -2863,12 +2895,12 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Uyarı: wallet.dat bozuk, veriler geri kazanıldı! Özgün wallet.dat, wallet.{zamandamgası}.bak olarak %s klasörüne kaydedildi; bakiyeniz ya da muameleleriniz yanlışsa bir yedeklemeden tekrar yüklemeniz gerekir.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(varsayılan: 1)</translation> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Belirtilen ağ maskesi ya da IP adresinden bağlanan eşleri beyaz listeye al. Birden fazla kez belirtilebilir.</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(varsayılan: wallet.dat)</translation> + <source>(default: 1)</source> + <translation>(varsayılan: 1)</translation> </message> <message> <source><category> can be:</source> @@ -2899,10 +2931,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Hata ayıklama/deneme seçenekleri:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>Güvenli kipi devre dışı bırak, gerçek bir güvenli olayı geçersiz kıl (varsayılan: 0)</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> @@ -2931,6 +2959,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Blok veritabanının açılışı sırasında hata</translation> </message> <message> + <source>Error: A fatal internal error occured, see debug.log for details</source> + <translation>Hata: Ölümcül dahili bir hata meydana geldi, ayrıntılar için debug.log dosyasına bakınız</translation> + </message> + <message> <source>Error: Disk space is low!</source> <translation>Hata: Disk alanı düşük!</translation> </message> @@ -2939,66 +2971,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Hata: Cüzdan kilitli, muamele oluşturulamadı!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Hata: sistem hatası:</translation> - </message> - <message> <source>Failed to listen on any port. Use -listen=0 if you want this.</source> <translation>Herhangi bir portun dinlenmesi başarısız oldu. Bunu istiyorsanız -listen=0 seçeneğini kullanınız.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Blok verileri okunamadı</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>Blok okunamadı</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>Blok indeksi eşleştirilemedi</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>Blok indeksi yazılamadı</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>Blok verileri yazılamadı</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>Blok yazılamadı</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>Dosya verileri yazılamadı</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>Madenî para veritabanına yazılamadı</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>Muamele indeksi yazılamadı</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>Geri alma verilerinin yazılamadı</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>Güvenli kipi zorla (varsayılan: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>Bitcoin oluştur (varsayılan: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Başlangıçta kontrol edilecek blok sayısı (varsayılan: 288, 0 = hepsi)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation><kategori> sağlanmamışsa tüm hata ayıklama verilerini dök.</translation> </message> @@ -3019,8 +2995,8 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Kafi derecede dosya tanımlayıcıları mevcut değil.</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>Hata ayıklama verilerinin önüne zaman damgası ekle (varsayılan: 1)</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <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> @@ -3035,26 +3011,18 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Azami blok boyutunu bayt olarak ayarla (varsayılan: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>RPC aramaları için iş parçacığı sayısını belirle (varsayılan: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>Cüzdan dosyası belirtiniz (veri klasörünün içinde)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>Gönderme muamelelerinde teyit edilmemiş para üstünü harca (varsayılan: 1)</translation> - </message> - <message> - <source>Stop running after importing blocks from disk (default: 0)</source> - <translation>Diskten blokları içeri aktardıktan sonra çalışmayı durdur (varsayılan: 0)</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> + <message> <source>Verifying blocks...</source> <translation>Bloklar kontrol ediliyor...</translation> </message> @@ -3079,10 +3047,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Harici blk000??.dat dosyasından blokları içe aktarır</translation> </message> <message> - <source>(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> - <translation>(varsayılan: 1, 1 = tx meta verilerini tut mesela hesap sahibi ve ödeme talebi bilgileri, 2 = tx meta verilerini at)</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>Belirtilen kaynaktan JSON-RPC bağlantılarını kabul et. Bir <ip> için geçerli olanlar şunlardır: salt IP adresi (mesela 1.2.3.4), bir şebeke/ağ maskesi (örneğin 1.2.3.4/255.255.255.0) ya da bir şebeke/CIDR (mesela 1.2.3.4/24). Bu seçenek birden fazla kez belirtilebilir</translation> </message> @@ -3103,12 +3067,12 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>%s veri dizininde kilit elde edilemedi. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır.</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> + <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>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> - <translation>MIT/X11 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> + <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>Error: Listening for incoming connections failed (listen returned error %s)</source> @@ -3119,10 +3083,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Hata: Desteklenmeyen -socks argümanı bulundu. SOCKS sürümünün ayarlanması artık mümkün değildir, sadece SOCKS5 vekilleri desteklenmektedir.</translation> </message> <message> - <source>Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)</source> - <translation>Bir şebeke muamelesi cüzdan muamele girdisini tekrar harcadığında komut çalıştır (%s=tekrar harcama muamele kimliği, %t=cüzdan muamele kimliği)</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>İlgili bir uyarı alındığında ya da gerçekten uzun bir çatallama gördüğümüzde komutu çalıştır (komuttaki %s mesaj ile değiştirilir)</translation> </message> @@ -3135,12 +3095,8 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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 are confirmed on average within n blocks (default: 1)</source> - <translation>Eğer paytxfee ayarlanmadıysa, kafi derecede ücret ekleyin ki muameleler vasati n blok içinde teyit edilsin (varsayılan: 1)</translation> - </message> - <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>Hata ayıklama bilgisi dök (varsayılan:0, <kategori> sağlanması seçime dayalıdır)</translation> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>Aktardığımız ve oluşturduğumuz veri taşıyıcı muamelelerindeki azami veri boyutu (varsayılan: %u)</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> @@ -3151,6 +3107,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Yüksek öncelikli/düşük ücretli muamelelerin azami boyutunu bayt olarak ayarla (varsayılan: %d)</translation> </message> <message> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <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>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> @@ -3159,18 +3119,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Uyarı: Lütfen bilgisayarınızın saat ve tarihinin doğru olduğunu kontol ediniz! Saatinizde gecikme varsa Bitcoin Çekirdeği doğru şekilde çalışamaz.</translation> </message> <message> - <source>Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.</source> - <translation>Belirtilen ağ maskesi ya da IP adresinden bağlanan eşleri beyaz listeye al. Birden fazla kez belirtilebilir.</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>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>Always query for peer addresses via DNS lookup (default: 0)</source> - <translation>Eş adreslerini daima DNS araması ile sorgula (varsayılan: 0)</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>-whitebind adresi çözümlenemedi: '%s'</translation> </message> @@ -3199,10 +3151,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Yolladığınız muamelelere kB başına BTC olarak eklenecek ücret (varsayılan: %s)</translation> </message> <message> - <source>Include IP addresses in debug output (default: 0)</source> - <translation>Hata ayıklama çıktısına IP adreslerini dahil et (varsayılan: 0)</translation> - </message> - <message> <source>Information</source> <translation>Bilgi</translation> </message> @@ -3231,24 +3179,8 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Hafızada en çok <n> bağlanılamaz blok tut (varsaylan: %u)</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>İmza arabelleğinin boyutunu <n> unsurla sınırla (varsayılan: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>Blok oluşturulduğunda muamele önceliğini ve kB başı ücreti kütüğe al (varsayılan: 0)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Muamelelerin tamamının indeksini tut (varsayılan: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Bağlantı başına azami alım tamponu, <n>*1000 bayt (varsayılan: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Bağlantı başına azami yollama tamponu, <n>*1000 bayt (varsayılan: 1000)</translation> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Hafızada en çok <n> bağlanılamaz muamele tut (varsayılan: %u)</translation> </message> <message> <source>Need to specify a port with -whitebind: '%s'</source> @@ -3259,22 +3191,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Düğüm röle seçenekleri:</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Sadece yerleşik kontrol noktalarıyla eşleşen blok zincirini kabul et (varsayılan: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Sadece <net> şebekesindeki düğümlere bağlan (IPv4, IPv6 ya da Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>Başlangıçta bloğu göster, blok indeksinde bulunduysa</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>Başlangıçta blok ağacını göster (varsayılan: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>RPC SSL seçenekleri: (SSL kurulumu yönergeleri için Bitcoin vikisine bakınız)</translation> </message> @@ -3291,28 +3211,12 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Her <n> şebeke mesajından rastgele birini bulanıklaştır</translation> </message> <message> - <source>Relay and mine data carrier transactions (default: 1)</source> - <translation>Veri taşıyıcı muameleleri oluştur ve aktar (varsayılan: 1)</translation> - </message> - <message> - <source>Relay non-P2SH multisig (default: 1)</source> - <translation>P2SH olmayan çoklu imzaları aktar (varsayılan: 1)</translation> - </message> - <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>Periyodik olarak cüdanı diske yazdırmak için bir iş parçacığı çalıştır (varsayılan: 1)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>Trace/hata ayıklama verilerini debug.log dosyası yerine konsola gönder</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>Bayt olarak asgari blok boyutunu tanımla (varsayılan: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>Cüzdan veritabanı ortamında DB_PRIVATE bayrağını koyar (varsayılan: 1)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Muameleleri mümkünse ücretsiz olarak gönder (varsayılan: %u)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> @@ -3327,14 +3231,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Muamelenin imzalanması başarısız oldu</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Bağlantı zaman aşım süresini milisaniye olarak belirt (varsayılan: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>Sistem hatası:</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Bu, deneysel bir yazılımdır.</translation> </message> @@ -3355,10 +3251,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Bu bilgisayarda %s unsuruna bağlanılamadı (bağlanma %s hatasını verdi)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>Dinlenecek portu haritalamak için UPnP kullan (varsayılan: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>Dinlenecek portu haritalamak için UPnP kullan (varsayılan: dinlenildiğinde 1)</translation> </message> @@ -3411,10 +3303,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Cüzdanı en yeni biçime güncelle</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Anahtar alan boyutunu <n> değerine ayarla (varsayılan: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>Blok zincirini eksik cüzdan muameleleri için tekrar tara</translation> </message> @@ -3423,14 +3311,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>JSON-RPC bağlantıları için OpenSSL (https) kullan</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Sunucu sertifika dosyası (varsayılan: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Sunucu özel anahtarı (varsayılan: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Bu yardım mesajı</translation> </message> @@ -3447,14 +3327,178 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>wallet.dat dosyasının yüklenmesinde hata oluştu: bozuk cüzdan</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 = 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>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source> + <translation>Eğer paytxfee ayarlanmadıysa, kafi derecede ücret ekleyin ki muameleler vasati n blok içinde teyit edilsin (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> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Aksaklık gösteren eşlerle terkar bağlantıyı engelleme süresi, saniye olarak (varsayılan: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Hata ayıklama bilgisi dök (varsayılan: %u, <kategori> sağlanması seçime dayalıdır)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Eşlere gizli Tor servisleri ile ulaşmak için ayrı SOCKS5 vekil sunucusu kullan (varsayılan: %s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(varsayılan: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Kabul edilebilir şifreler (varsayılan: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <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> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Başlangıçta kontrol edilecek blok sayısı (varsayılan: %u, 0 = hepsi)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Hata ayıklama çıktısına IP adreslerini dahil et (varsayılan: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <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> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Bağlantılar için dinlenecek <port> (varsayılan: %u ya da testnet: %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Eşler ile en çok <n> adet bağlantı kur (varsayılan: %u)</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> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <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> + <message> + <source>Print block tree on startup (default: %u)</source> + <translation>Başlangıçta blok ağacını göster (varsayılan: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Veri taşıyıcı muameleleri oluştur ve aktar (varsayılan: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <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> + <message> + <source>Server private key (default: %s)</source> + <translation>Sunucu özel anahtarı (varsayılan: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Anahtar alan boyutunu <n> değerine ayarla (varsayılan: %u)</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Bayt olarak asgari blok boyutunu tanımla (varsayılan: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <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> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Bağlantı zaman aşım süresini milisaniye olarak belirt (asgari: 1, varsayılan: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Pid dosyası belirtiniz (varsayılan: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <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> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>-onlynet için bilinmeyen bir şebeke belirtildi: '%s'</translation> </message> diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index ff8ac68022..9b5f4c9f4e 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -1,4 +1,4 @@ -<TS language="uk" version="2.1"> +<TS language="uk" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -10,10 +10,22 @@ <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> @@ -34,12 +46,28 @@ <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>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>Це ваші Bitcoin адреси для відправки платежів. Перед відправкою монети Завжди перевіряйте суму та адресу прийому.</translation> + <translation>Це ваші Bitcoin-адреси для відправлення платежів. Перед відправленням монет завжди перевіряйте суму та адресу прийому.</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> @@ -59,11 +87,15 @@ </message> <message> <source>Comma separated file (*.csv)</source> - <translation>Файли, розділені комою (*.csv)</translation> + <translation>Значення, розділені комою (*.csv)</translation> + </message> + <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> + <translation>Виникла помилка при спробі зберігання адрес до %1. Будь ласка спробуйте ще.</translation> </message> </context> <context> @@ -141,7 +173,7 @@ </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> @@ -152,6 +184,10 @@ <translation>Гаманець зашифровано</translation> </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> + </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> @@ -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> @@ -199,6 +235,10 @@ <translation>&Огляд</translation> </message> <message> + <source>Node</source> + <translation>Вузол</translation> + </message> + <message> <source>Show general overview of wallet</source> <translation>Показати загальний огляд гаманця</translation> </message> @@ -255,6 +295,10 @@ <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> @@ -288,7 +332,7 @@ </message> <message> <source>&Verify message...</source> - <translation>Перевірити повідомлення...</translation> + <translation>П&еревірити повідомлення...</translation> </message> <message> <source>Bitcoin</source> @@ -347,29 +391,45 @@ <translation>Панель вкладок</translation> </message> <message> - <source>[testnet]</source> - <translation>[тестова мережа]</translation> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> </message> <message> - <source>Bitcoin Core</source> - <translation>Bitcoin Ядро</translation> + <source>Request payments (generates QR codes and bitcoin: URIs)</source> + <translation>Створити запит платежу (генерує QR-код та bitcoin: URI)</translation> + </message> + <message> + <source>&About 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>Відкрити bitcoin: 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><numerusform>%n активних з'єднань з мережею Bitcoin</numerusform></translation> + <translation><numerusform>%n активне з'єднання з мережею</numerusform><numerusform>%n активні з'єднання з мережею</numerusform><numerusform>%n активних з'єднань з мережею Bitcoin</numerusform></translation> </message> <message> <source>No block source available...</source> <translation>Недоступно жодного джерела блоків...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Оброблено %1 блоків історії транзакцій.</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n година</numerusform><numerusform>%n години</numerusform><numerusform>%n годин</numerusform></translation> @@ -418,6 +478,10 @@ <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> @@ -428,7 +492,7 @@ </message> <message> <source>Incoming transaction</source> - <translation>Отримані перекази</translation> + <translation>Отримані транзакції</translation> </message> <message> <source>Date: %1 @@ -461,10 +525,18 @@ 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> @@ -477,30 +549,58 @@ Address: %4 <translation>Комісія:</translation> </message> <message> + <source>Dust:</source> + <translation>Пил:</translation> + </message> + <message> <source>After Fee:</source> - <translation>Після комісії</translation> + <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>Address</source> - <translation>Адреса</translation> + <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> @@ -517,6 +617,14 @@ 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> @@ -537,6 +645,10 @@ Address: %4 <translation>Копіювати пріорітет</translation> </message> <message> + <source>Copy dust</source> + <translation>Копіювати пил</translation> + </message> + <message> <source>Copy change</source> <translation>Копіювати решту</translation> </message> @@ -577,6 +689,18 @@ Address: %4 <translation>найнижчий</translation> </message> <message> + <source>(%1 locked)</source> + <translation>(%1 заблоковано)</translation> + </message> + <message> + <source>none</source> + <translation>відсутній</translation> + </message> + <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>Може відрізнятися на +/- %1 сатоші за вхід</translation> + </message> + <message> <source>yes</source> <translation>так</translation> </message> @@ -589,8 +713,20 @@ Address: %4 <translation>Ця позначка буде червоною, якщо розмір транзакції вищий за 1000 байт.</translation> </message> <message> + <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>Transactions with higher priority are more likely to get included into a block.</source> + <translation>Транзакції з вищим пріоритетом мають більше шансів бути включеними до блоку.</translation> + </message> + <message> <source>This label turns red, if the priority is smaller than "medium".</source> - <translation>Ця позначка буде червоною, якщо пріорітет транзакції нижчий за «середній»".</translation> + <translation>Ця позначка буде червоною, якщо пріоритет транзакції нижчий за «середній».</translation> </message> <message> <source>This label turns red, if any recipient receives an amount smaller than %1.</source> @@ -600,7 +736,15 @@ Address: %4 <source>(no label)</source> <translation>(немає назви)</translation> </message> - </context> + <message> + <source>change from %1 (%2)</source> + <translation>решта з %1 (%2)</translation> + </message> + <message> + <source>(change)</source> + <translation>(решта)</translation> + </message> +</context> <context> <name>EditAddressDialog</name> <message> @@ -612,6 +756,14 @@ Address: %4 <translation>&Мітка</translation> </message> <message> + <source>The label associated with this address list entry</source> + <translation>Мітка, пов'язана з цим записом списку адрес</translation> + </message> + <message> + <source>The address associated with this address list entry. This can only be modified for sending addresses.</source> + <translation>Адреса, пов'язана з цим записом списку адрес. Це поле може бути модифіковане лише для адрес відправлення.</translation> + </message> + <message> <source>&Address</source> <translation>&Адреса</translation> </message> @@ -675,11 +827,19 @@ Address: %4 <name>HelpMessageDialog</name> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Ядро</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>version</source> - <translation>версія</translation> + <translation>версії</translation> + </message> + <message> + <source>(%1-bit)</source> + <translation>(%1-бітний)</translation> + </message> + <message> + <source>About Bitcoin Core</source> + <translation>Про Bitcoin Core</translation> </message> <message> <source>Command-line options</source> @@ -706,6 +866,10 @@ Address: %4 <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> @@ -730,7 +894,7 @@ Address: %4 </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 завантажить та збереже копію ланцюга Bitcoin блоків. Щонайменше %1Gb даних буде збережено в цьому каталозі. Гаманець теж буде збережено в цьому каталозі.</translation> + <translation>Bitcoin Core завантажить та збереже копію ланцюжка блоків Bitcoin. Щонайменше %1ГБ даних буде збережено в цьому каталозі. Гаманець теж буде збережено в цьому каталозі.</translation> </message> <message> <source>Use the default data directory</source> @@ -746,19 +910,19 @@ Address: %4 </message> <message> <source>Error: Specified data directory "%1" cannot be created.</source> - <translation>Помилка: неожливо створити обраний каталог даних «%1».</translation> + <translation>Помилка: неможливо створити обраний каталог даних «%1».</translation> </message> <message> <source>Error</source> <translation>Помилка</translation> </message> - <message> - <source>GB of free space available</source> - <translation>Gb вільного простору доступно</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>Доступно %n ГБ вільного простору</numerusform><numerusform>Доступно %n ГБ вільного простору</numerusform><numerusform>Доступно %n ГБ вільного простору</numerusform></translation> </message> - <message> - <source>(of %1GB needed)</source> - <translation>(з %1Gb, що потрібно)</translation> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(в той час, як необхідно %n ГБ)</numerusform><numerusform>(в той час, як необхідно %n ГБ)</numerusform><numerusform>(в той час, як необхідно %n ГБ)</numerusform></translation> </message> </context> <context> @@ -768,10 +932,22 @@ Address: %4 <translation>Відкрити URI</translation> </message> <message> + <source>Open payment request from URI or file</source> + <translation>Відкрити запит платежу з URI або файлу</translation> + </message> + <message> <source>URI:</source> <translation>URI:</translation> </message> - </context> + <message> + <source>Select payment request file</source> + <translation>Виберіть файл запиту платежу</translation> + </message> + <message> + <source>Select payment request file to open</source> + <translation>Виберіть файл запиту платежу для відкриття</translation> + </message> +</context> <context> <name>OptionsDialog</name> <message> @@ -783,14 +959,6 @@ Address: %4 <translation>&Головні</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Необов'язкова комісия за Кб допомагає переконатися, що ваші транзакції обробляються швидше. Більшість транзакцій є 1 Кб.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>Заплатити комісі&ю</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>Автоматично запускати гаманець при вході до системи.</translation> </message> @@ -799,6 +967,42 @@ Address: %4 <translation>&Запускати гаманець при вході в систему</translation> </message> <message> + <source>Size of &database cache</source> + <translation>Розмір &кешу бази даних</translation> + </message> + <message> + <source>MB</source> + <translation>МБ</translation> + </message> + <message> + <source>Number of script &verification threads</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 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> + <message> + <source>Third party transaction URLs</source> + <translation>Сторонні URL транзакцій</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>Скинути всі параметри клієнта на типові.</translation> </message> @@ -811,6 +1015,30 @@ 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> + <message> + <source>Expert</source> + <translation>Експерт</translation> + </message> + <message> + <source>Enable coin &control features</source> + <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>Автоматично відкривати порт для клієнту біткоін на роутері. Працює лише якщо ваш роутер підтримує UPnP і ця функція увімкнена.</translation> </message> @@ -819,6 +1047,14 @@ Address: %4 <translation>Відображення порту через &UPnP</translation> </message> <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Підключення до мережі Bitcoin через SOCKS5 проксі.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Підключення через SOCKS5 проксі (проксі за замовчуванням):</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>&IP проксі:</translation> </message> @@ -856,7 +1092,7 @@ Address: %4 </message> <message> <source>User Interface &language:</source> - <translation>Мова інтерфейсу користувача:</translation> + <translation>Мов&а інтерфейсу користувача:</translation> </message> <message> <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</source> @@ -871,6 +1107,10 @@ Address: %4 <translation>Виберіть одиницю вимірювання монет, яка буде відображатись в гаманці та при відправленні.</translation> </message> <message> + <source>Whether to show coin control features or not.</source> + <translation>Показати або сховати керування входами.</translation> + </message> + <message> <source>&OK</source> <translation>&Гаразд</translation> </message> @@ -883,10 +1123,26 @@ Address: %4 <translation>типово</translation> </message> <message> + <source>none</source> + <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>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> + <message> <source>The supplied proxy address is invalid.</source> <translation>Невірно вказано адресу проксі.</translation> </message> @@ -902,36 +1158,68 @@ Address: %4 <translation>Показана інформація вже може бути застарілою. Ваш гаманець буде автоматично синхронізовано з мережею Bitcoin після встановлення підключення, але цей процес ще не завершено.</translation> </message> <message> - <source>Wallet</source> - <translation>Гаманець</translation> + <source>Watch-only:</source> + <translation>Тільки спостереження:</translation> + </message> + <message> + <source>Available:</source> + <translation>Наявно:</translation> </message> <message> <source>Your current spendable balance</source> - <translation>Ваш поточний баланс расходуемого</translation> + <translation>Ваш поточний підтверджений баланс</translation> + </message> + <message> + <source>Pending:</source> + <translation>Очікується:</translation> </message> <message> <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source> - <translation>Всього угод, які ще мають бути підтверджені, і до цих пір не враховуються в расходуемого балансу</translation> + <translation>Сума монет у непідтверджених транзакціях</translation> </message> <message> <source>Immature:</source> - <translation>незрілі:</translation> + <translation>Незрілі:</translation> </message> <message> <source>Mined balance that has not yet matured</source> - <translation>Замінований баланс, який ще не дозрів</translation> + <translation>Баланс видобутих та ще недозрілих монет</translation> + </message> + <message> + <source>Balances</source> + <translation>Баланси</translation> </message> <message> <source>Total:</source> - <translation>всього:</translation> + <translation>Всього:</translation> </message> <message> <source>Your current total balance</source> - <translation>Ваше поточне Сукупний баланс</translation> + <translation>Ваш поточний сукупний баланс</translation> + </message> + <message> + <source>Your current balance in watch-only addresses</source> + <translation>Ваш поточний баланс в адресах для спостереження</translation> + </message> + <message> + <source>Spendable:</source> + <translation>Доступно:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Недавні транзакції</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Недавні транзакції</b></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> <message> <source>out of sync</source> @@ -944,10 +1232,98 @@ Address: %4 <source>URI handling</source> <translation>Обробка URI</translation> </message> - </context> + <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>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> + <message> + <source>Cannot start bitcoin: click-to-pay handler</source> + <translation>Неможливо запустити bitcoin: обробник click-to-pay</translation> + </message> + <message> + <source>Payment request fetch URL is invalid: %1</source> + <translation>URL запиту платежу є некоректним: %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! Причиною цього може бути некоректна Bitcoin-адреса або неправильні параметри URI.</translation> + </message> + <message> + <source>Payment request file handling</source> + <translation>Обробка файлу запиту платежу</translation> + </message> + <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>Неможливо прочитати файл запиту платежу! Ймовірно, файл пошкоджено.</translation> + </message> + <message> + <source>Unverified payment requests to custom payment scripts are unsupported.</source> + <translation>Неперевірені запити платежів з власними платіжними сценаріями не підтримуються.</translation> + </message> + <message> + <source>Refund from %1</source> + <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> + <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>Address/Hostname</source> + <translation>Адреса/Ім'я хоста</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Затримка</translation> + </message> +</context> <context> <name>QObject</name> <message> @@ -955,6 +1331,10 @@ Address: %4 <translation>Кількість</translation> </message> <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>Введіть адресу Bitcoin (наприклад %1)</translation> + </message> + <message> <source>%1 d</source> <translation>%1 д</translation> </message> @@ -971,6 +1351,18 @@ 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> + <message> <source>N/A</source> <translation>Н/Д</translation> </message> @@ -993,7 +1385,11 @@ Address: %4 <source>Save QR Code</source> <translation>Зберегти QR-код</translation> </message> - </context> + <message> + <source>PNG Image (*.png)</source> + <translation>Зображення PNG (*.png)</translation> + </message> +</context> <context> <name>RPCConsole</name> <message> @@ -1017,10 +1413,18 @@ Address: %4 <translation>Вікно зневадження</translation> </message> <message> + <source>General</source> + <translation>Загальна</translation> + </message> + <message> <source>Using OpenSSL version</source> <translation>Використовується OpenSSL версії</translation> </message> <message> + <source>Using BerkeleyDB version</source> + <translation>Використовується BerkeleyDB версії</translation> + </message> + <message> <source>Startup time</source> <translation>Час запуску</translation> </message> @@ -1053,10 +1457,66 @@ Address: %4 <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>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>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>Байтів відправлено</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> @@ -1069,8 +1529,24 @@ Address: %4 <translation>Консоль</translation> </message> <message> + <source>&Network Traffic</source> + <translation>&Мережевий трафік</translation> + </message> + <message> + <source>&Clear</source> + <translation>&Очистити</translation> + </message> + <message> <source>Totals</source> - <translation>всього:</translation> + <translation>Всього</translation> + </message> + <message> + <source>In:</source> + <translation>Вхідних:</translation> + </message> + <message> + <source>Out:</source> + <translation>Вихідних:</translation> </message> <message> <source>Build date</source> @@ -1082,7 +1558,7 @@ Address: %4 </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> + <translation>Відкрийте файл журналу налагодження Bitcoin з поточного каталогу даних. Це може зайняти кілька секунд для великих файлів журналів.</translation> </message> <message> <source>Clear console</source> @@ -1101,18 +1577,46 @@ Address: %4 <translation>Наберіть <b>help</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>Yes</source> - <translation>Так</translation> + <source>Outbound</source> + <translation>Вихідний</translation> </message> <message> - <source>No</source> - <translation>Ні</translation> + <source>Unknown</source> + <translation>Невідома</translation> </message> - </context> + <message> + <source>Fetching...</source> + <translation>Отримання...</translation> + </message> +</context> <context> <name>ReceiveCoinsDialog</name> <message> @@ -1128,6 +1632,30 @@ Address: %4 <translation>&Повідомлення:</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>Повторно використати одну з адрес. Повторне використання адрес створює ризики безпеки та конфіденційності. Не використовуйте її, окрім як для створення повторного запиту платежу.</translation> + </message> + <message> + <source>R&euse an existing receiving address (not recommended)</source> + <translation>По&вторно використати адресу для отримання (не рекомендується)</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>Необов'язкове повідомлення на додаток до запиту платежу, котре буде показане під час відкриття запиту. Примітка: Це повідомлення не буде відправлено з платежем через мережу Bitcoin.</translation> + </message> + <message> + <source>An optional label to associate with the new receiving address.</source> + <translation>Необов'язкове поле для мітки нової адреси отримувача.</translation> + </message> + <message> + <source>Use this form to request payments. All fields are <b>optional</b>.</source> + <translation>Використовуйте цю форму, щоб отримати платежі. Всі поля є <b>необов'язковими</b>.</translation> + </message> + <message> + <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source> + <translation>Необов'язкове поле для суми запиту. Залиште це поле пустим або впишіть нуль, щоб не надсилати у запиті конкретної суми.</translation> + </message> + <message> <source>Clear all fields of the form.</source> <translation>Очистити всі поля в формі</translation> </message> @@ -1136,6 +1664,30 @@ 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 the selected request (does the same as double clicking an entry)</source> + <translation>Показати вибраний запит (робить те ж саме, що й подвійний клік по запису)</translation> + </message> + <message> + <source>Show</source> + <translation>Показати</translation> + </message> + <message> + <source>Remove the selected entries from the list</source> + <translation>Вилучити вибрані записи зі списку</translation> + </message> + <message> + <source>Remove</source> + <translation>Вилучити</translation> + </message> + <message> <source>Copy label</source> <translation>Скопіювати мітку</translation> </message> @@ -1167,6 +1719,14 @@ Address: %4 <translation>&Зберегти зображення...</translation> </message> <message> + <source>Request payment to %1</source> + <translation>Запит платежу на %1</translation> + </message> + <message> + <source>Payment information</source> + <translation>Інформація про платіж</translation> + </message> + <message> <source>URI</source> <translation>URI</translation> </message> @@ -1217,7 +1777,15 @@ Address: %4 <source>(no label)</source> <translation>(немає назви)</translation> </message> - </context> + <message> + <source>(no message)</source> + <translation>(без повідомлення)</translation> + </message> + <message> + <source>(no amount)</source> + <translation>(без суми)</translation> + </message> +</context> <context> <name>SendCoinsDialog</name> <message> @@ -1225,12 +1793,32 @@ Address: %4 <translation>Відправити</translation> </message> <message> + <source>Coin Control Features</source> + <translation>Керування монетами</translation> + </message> + <message> + <source>Inputs...</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> + <message> <source>Amount:</source> - <translation>Кількість:</translation> + <translation>Сума:</translation> </message> <message> <source>Priority:</source> @@ -1249,6 +1837,86 @@ 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> + <message> + <source>Choose...</source> + <translation>Виберіть...</translation> + </message> + <message> + <source>collapse fee-settings</source> + <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> + </message> + <message> + <source>total at least</source> + <translation>всього щонайменше</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>Оплата тільки мінімальних зборів є прийнятною до тих пір, як обсяг транзакцій там є меншим аніж простору в блоках. Але майте на увазі, що це може анулювати транзакцію, якщо попит на Bitcoin транзакції стане значно більшим, ніж мережа зможе обробити.</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(читати підказки)</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Рекомендовано:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Змінено:</translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</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 as zero-fee transaction if possible</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> @@ -1261,6 +1929,10 @@ Address: %4 <translation>Очистити всі поля в формі</translation> </message> <message> + <source>Dust:</source> + <translation>Пил:</translation> + </message> + <message> <source>Clear &All</source> <translation>Очистити &все</translation> </message> @@ -1281,6 +1953,10 @@ Address: %4 <translation>Підтвердіть відправлення</translation> </message> <message> + <source>%1 to %2</source> + <translation>%1 на %2</translation> + </message> + <message> <source>Copy quantity</source> <translation>Копіювати кількість</translation> </message> @@ -1309,12 +1985,20 @@ Address: %4 <translation>Копіювати решту</translation> </message> <message> + <source>Total Amount %1 (= %2)</source> + <translation>Всього %1 (= %2)</translation> + </message> + <message> + <source>or</source> + <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> + <translation>Кількість монет для відправлення повинна бути більше 0.</translation> </message> <message> <source>The amount exceeds your balance.</source> @@ -1329,14 +2013,50 @@ Address: %4 <translation>Знайдено адресу що дублюється. Відправлення на кожну адресу дозволяється лише один раз на кожну операцію переказу.</translation> </message> <message> + <source>Transaction creation failed!</source> + <translation>Не вдалося створити транзакцію!</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>Транзакцію відхилено! Це може статись, якщо декілька монет з вашого гаманця вже використані, наприклад, якщо ви використовуєте одну копію гаманця (wallet.dat), а монети були використані з іншої копії, але не позначені як використані в цій.</translation> + </message> + <message> + <source>A fee higher than %1 is considered an insanely high fee.</source> + <translation>Плата вища, ніж %1 вважається шалено високою.</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> + </message> + <message> + <source>Warning: Invalid Bitcoin address</source> + <translation>Увага: Неправильна Bitcoin-адреса</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> - </context> + <message> + <source>added as transaction fee</source> + <translation>додано як комісія за транзакцію</translation> + </message> +</context> <context> <name>SendCoinsEntry</name> <message> @@ -1360,6 +2080,14 @@ Address: %4 <translation>Обрати ранiш використовувану адресу</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> @@ -1372,17 +2100,49 @@ Address: %4 <translation>Alt+P</translation> </message> <message> + <source>Remove this entry</source> + <translation>Видалити цей запис</translation> + </message> + <message> <source>Message:</source> <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> + <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>Повідомлення, що було додане до 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> + <message> <source>Memo:</source> <translation>Нотатка:</translation> </message> </context> <context> <name>ShutdownWindow</name> - </context> + <message> + <source>Bitcoin Core is shutting down...</source> + <translation>Bitcoin Core вимикається...</translation> + </message> + <message> + <source>Do not shut down the computer until this window disappears.</source> + <translation>Не вимикайте комп’ютер до зникнення цього вікна.</translation> + </message> +</context> <context> <name>SignVerifyMessageDialog</name> <message> @@ -1395,7 +2155,11 @@ Address: %4 </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> + <translation>Ви можете підписувати повідомлення зі своїми адресами, щоб довести, що ви є їх власником. Остерігайтеся підписувати будь-що незрозуміле, так як за допомогою фішинг-атаки вас можуть спробувати обдурити для отримання вашого підпису під чужими словами. Підписуйте тільки ті повідомлення, з якими ви повністю згодні.</translation> + </message> + <message> + <source>The Bitcoin address to sign the message with</source> + <translation>Адреса Bitcoin для підпису цього повідомлення</translation> </message> <message> <source>Choose previously used address</source> @@ -1447,7 +2211,11 @@ Address: %4 </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> + <translation>Введіть нижче адресу підпису, повідомлення (впевніться, що ви точно скопіювали символи завершення рядку, табуляцію, пробіли тощо) та підпис для перевірки повідомлення. Впевніться, що в підпис не було додано зайвих символів: це допоможе уникнути атак типу «людина посередині».</translation> + </message> + <message> + <source>The Bitcoin address the message was signed with</source> + <translation>Адреса Bitcoin, якою було підписано це повідомлення</translation> </message> <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> @@ -1475,11 +2243,11 @@ Address: %4 </message> <message> <source>The entered address does not refer to a key.</source> - <translation>Введений адреса не відноситься до ключа.</translation> + <translation>Введена адреса не відноситься до ключа.</translation> </message> <message> <source>Wallet unlock was cancelled.</source> - <translation>Розблокування Гаманець був скасований.</translation> + <translation>Розблокування гаманця було скасоване.</translation> </message> <message> <source>Private key for the entered address is not available.</source> @@ -1503,7 +2271,7 @@ Address: %4 </message> <message> <source>The signature did not match the message digest.</source> - <translation>Підпис не відповідає дайджест повідомлення.</translation> + <translation>Підпис не збігається з хешем повідомлення.</translation> </message> <message> <source>Message verification failed.</source> @@ -1518,7 +2286,11 @@ Address: %4 <name>SplashScreen</name> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Ядро</translation> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>The Bitcoin Core developers</source> + <translation>Розробники Bitcoin Core</translation> </message> <message> <source>[testnet]</source> @@ -1536,7 +2308,11 @@ Address: %4 <name>TransactionDesc</name> <message> <source>Open until %1</source> - <translation>Відкрити до %1</translation> + <translation>Відкрито до %1</translation> + </message> + <message> + <source>conflicted</source> + <translation>суперечить</translation> </message> <message> <source>%1/offline</source> @@ -1554,6 +2330,10 @@ 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> @@ -1579,6 +2359,10 @@ Address: %4 <translation>Власна адреса</translation> </message> <message> + <source>watch-only</source> + <translation>тільки спостереження</translation> + </message> + <message> <source>label</source> <translation>Мітка</translation> </message> @@ -1586,6 +2370,10 @@ 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> @@ -1595,6 +2383,14 @@ 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> @@ -1615,8 +2411,16 @@ Address: %4 <translation>ID транзакції</translation> </message> <message> + <source>Merchant</source> + <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> + <translation>Налагоджувальна інформація</translation> </message> <message> <source>Transaction</source> @@ -1642,6 +2446,10 @@ 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> @@ -1673,8 +2481,16 @@ Address: %4 <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> + <translation>Відкрито до %1</translation> </message> <message> <source>Confirmed (%1 confirmations)</source> @@ -1689,6 +2505,22 @@ Address: %4 <translation>Згенеровано, але не підтверджено</translation> </message> <message> + <source>Offline</source> + <translation>Поза мережею</translation> + </message> + <message> + <source>Unconfirmed</source> + <translation>Не підтверджено</translation> + </message> + <message> + <source>Confirming (%1 of %2 recommended confirmations)</source> + <translation>Підтверджується (%1 з %2 рекомендованих підтверджень)</translation> + </message> + <message> + <source>Conflicted</source> + <translation>Суперечить</translation> + </message> + <message> <source>Received with</source> <translation>Отримані на</translation> </message> @@ -1709,6 +2541,10 @@ Address: %4 <translation>Добуті</translation> </message> <message> + <source>watch-only</source> + <translation>тільки спостереження</translation> + </message> + <message> <source>(n/a)</source> <translation>(недоступно)</translation> </message> @@ -1725,6 +2561,10 @@ Address: %4 <translation>Тип транзакції.</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Показує, чи було залучено адресу для спостереження в цій транзакції.</translation> + </message> + <message> <source>Destination address of transaction.</source> <translation>Адреса отримувача транзакції.</translation> </message> @@ -1816,8 +2656,32 @@ Address: %4 <translation>Показати деталі транзакції</translation> </message> <message> + <source>Export Transaction History</source> + <translation>Експортувати історію транзакцій</translation> + </message> + <message> + <source>Watch-only</source> + <translation>Для спостереження</translation> + </message> + <message> + <source>Exporting Failed</source> + <translation>Помилка експорту</translation> + </message> + <message> + <source>There was an error trying to save the transaction history to %1.</source> + <translation>Виникла помилка при спробі зберігання історії транзакцій до %1.</translation> + </message> + <message> + <source>Exporting Successful</source> + <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> + <translation>Значення, розділені комою (*.csv)</translation> </message> <message> <source>Confirmed</source> @@ -1854,10 +2718,18 @@ 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> - </context> + <message> + <source>No wallet has been loaded.</source> + <translation>Гаманець не завантажувався</translation> + </message> +</context> <context> <name>WalletModel</name> <message> @@ -1869,7 +2741,7 @@ Address: %4 <name>WalletView</name> <message> <source>&Export</source> - <translation>& Експорт</translation> + <translation>&Експорт</translation> </message> <message> <source>Export the data in the current tab to a file</source> @@ -1888,6 +2760,14 @@ 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> + <message> <source>Backup Successful</source> <translation>Успішне створення резервної копії</translation> </message> @@ -1899,26 +2779,10 @@ Address: %4 <translation>Параметри:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Вкажіть файл конфігурації (типово: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>Вкажіть pid-файл (типово: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Вкажіть робочий каталог</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>Чекати на з'єднання на <port> (типово: 8333 або тестова мережа: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>Підтримувати не більше <n> зв'язків з колегами (типово: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Підключитись до вузла, щоб отримати список адрес інших учасників та від'єднатись</translation> </message> @@ -1927,18 +2791,6 @@ Address: %4 <translation>Вкажіть вашу власну публічну адресу</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>Поріг відключення неправильно під'єднаних пірів (типово: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>Максимальній розмір вхідного буферу на одне з'єднання (типово: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>Прослуховувати <port> для JSON-RPC-з'єднань (типово: 8332 або тестова мережа: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>Приймати команди із командного рядка та команди JSON-RPC</translation> </message> @@ -1952,25 +2804,89 @@ Address: %4 </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> - <translation>Приймати з'єднання ззовні (за замовчуванням: 1, якщо ні-проксі або-з'єднання)</translation> + <translation>Приймати підключення ззовні (типово: 1 за відсутності -proxy чи -connect)</translation> + </message> + <message> + <source>%s, you must set a 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>%s, ви повинні встановити rpcpassword в файлі конфігурації: +%s +Рекомендується використати такий випадковий пароль: +rpcuser=bitcoinrpc +rpcpassword=%s +(ви не повинні пам'ятати цей пароль) +Ім’я користувача та пароль ПОВИННІ бути різними. +Якщо файлу не існує, створіть його, обмеживши доступ правом читання для власника. +Також рекомендується використовувати alertnotify для того, щоб отримувати сповіщення про проблеми; +наприклад: alertnotify=echo %%s | mail -s "Сповіщення Bitcoin" admin@foo.com +</translation> </message> <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> - <translation>Прив'язка до даного адресою і завжди слухати на ньому. Використовуйте [господаря]: позначення порту для IPv6</translation> + <translation>Прив'язатися до даної адреси та прослуховувати її. Використовуйте запис виду [хост]:порт для IPv6</translation> + </message> + <message> + <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> + <translation>Видалити всі транзакції гаманця та відновити ті, що будуть знайдені під час запуску за допомогою -rescan</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>Поширюється за ліцензією 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>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.</source> <translation>Помилка: транзакцію було відхилено. Це може статись, якщо декілька монет з вашого гаманця вже використані, наприклад, якщо ви використовуєте одну копію гаманця (wallet.dat), а монети були використані з іншої копії, але не позначені як використані в цій.</translation> </message> <message> + <source>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</source> + <translation>Помилка: Ця транзакція потребує додавання комісії щонайменше в %s через її розмір, складність, або внаслідок використання недавно отриманих коштів!</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> + </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>Встановити кількість потоків скрипту перевірки (від %u до %d, 0 = автоматично, <0 = вказує кількість вільних ядер, типово: %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>Це тест збірки попередньою версією - використовуйте на свій страх і ризик - не використовувати для гірничодобувних або торгових додатків</translation> + <translation>Це тестова збірка пре-релізної версії - використовуйте на свій страх і ризик - не застосовувати для добування монет або торгівлі</translation> + </message> + <message> + <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source> + <translation>Неможливо прив'язатися до %s на цьому комп'ютері. Можливо, Bitcoin Core вже запущено.</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> <message> + <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> + <translation>Увага: Частина мережі використовує інший головний ланцюжок! Деякі добувачі, можливо, зазнають проблем.</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>Увага: Наш ланцюжок блоків відрізняється від ланцюжків підключених учасників! Можливо, вам, або іншим вузлам, необхідно оновитися.</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>Увага: помилка читання wallet.dat! Всі ключі прочитано коректно, але дані транзакцій чи записи адресної книги можуть бути пропущені, або пошкоджені.</translation> </message> @@ -1979,6 +2895,18 @@ Address: %4 <translation>Увага: файл wallet.dat пошкоджено, дані врятовано! Оригінальний wallet.dat збережено як wallet.{timestamp}.bak до %s; якщо Ваш баланс чи транзакції неправильні, Ви можете відновити їх з резервної копії. </translation> </message> <message> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Додати учасників, що під'єднуються з заданої підмережі чи IP-адреси, в білий список. Можна вказувати декілька разів.</translation> + </message> + <message> + <source>(default: 1)</source> + <translation>(типово: 1)</translation> + </message> + <message> + <source><category> can be:</source> + <translation><category> може бути:</translation> + </message> + <message> <source>Attempt to recover private keys from a corrupt wallet.dat</source> <translation>Спроба відновити закриті ключі з пошкодженого wallet.dat</translation> </message> @@ -1991,22 +2919,38 @@ Address: %4 <translation>Підключитись лише до вказаного вузла</translation> </message> <message> + <source>Connection options:</source> + <translation>Параметри з'єднання:</translation> + </message> + <message> <source>Corrupted block database detected</source> <translation>Виявлено пошкоджений блок бази даних</translation> </message> <message> + <source>Debugging/Testing options:</source> + <translation>Параметри тестування/налагодження:</translation> + </message> + <message> <source>Discover own IP address (default: 1 when listening and no -externalip)</source> - <translation>Відкрийте власну IP-адресу (за замовчуванням: 1, коли не чує і-externalip)</translation> + <translation>Визначити власну IP-адресу (типово: 1 при прослуховуванні та за відсутності -externalip)</translation> + </message> + <message> + <source>Do not load the wallet and disable wallet RPC calls</source> + <translation>Не завантажувати гаманець та вимкнути звернення до нього через RPC</translation> </message> <message> <source>Do you want to rebuild the block database now?</source> - <translation>Ви хочете перебудувати базу даних блоку зараз?</translation> + <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> @@ -2015,6 +2959,10 @@ 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> @@ -2023,154 +2971,298 @@ Address: %4 <translation>Помилка: Гаманець заблокований, неможливо створити транзакцію!</translation> </message> <message> - <source>Error: system error: </source> - <translation>Помилка: системна помилка: </translation> + <source>Failed to listen on any port. Use -listen=0 if you want this.</source> + <translation>Не вдалося слухати на жодному порту. Використовуйте -listen=0, якщо ви хочете цього.</translation> </message> <message> - <source>Failed to listen on any port. Use -listen=0 if you want this.</source> - <translation>Не вдалося слухати на будь-якому порту. Використовуйте-слухати = 0, якщо ви хочете цього.</translation> + <source>If <category> is not supplied, output all debugging information.</source> + <translation>Якщо <category> не задано, виводить всю налагоджувальну інформацію.</translation> </message> <message> - <source>Failed to read block info</source> - <translation>Не вдалося розпізнати блок інформації </translation> + <source>Importing...</source> + <translation>Імпорт...</translation> </message> <message> - <source>Failed to read block</source> - <translation>Не вдалося розпізнати блок</translation> + <source>Incorrect or no genesis block found. Wrong datadir for network?</source> + <translation>Початковий блок некоректний/відсутній. Чи правильно вказано каталог даних для обраної мережі?</translation> </message> <message> - <source>Failed to sync block index</source> - <translation>Не вдалося синхронізувати індекс блоку </translation> + <source>Invalid -onion address: '%s'</source> + <translation>Помилка в адресі -onion: «%s»</translation> </message> <message> - <source>Failed to write block index</source> - <translation>Не вдалося записати індекс блоку</translation> + <source>Not enough file descriptors available.</source> + <translation>Бракує доступних дескрипторів файлів.</translation> </message> <message> - <source>Failed to write block info</source> - <translation>Не вдалося записати інформацію індекса</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>Підключити тільки до вузлів в мережі <net> (ipv4, ipv6 або onion)</translation> </message> <message> - <source>Failed to write block</source> - <translation>Не вдалося записати блок</translation> + <source>Rebuild block chain index from current blk000??.dat files</source> + <translation>Перебудувати індекс ланцюжка блоків з поточних файлів blk000??.dat</translation> </message> <message> - <source>Failed to write file info</source> - <translation>Не вдалося записати інформацію файла</translation> + <source>Set database cache size in megabytes (%d to %d, default: %d)</source> + <translation>Встановити розмір кешу бази даних в мегабайтах (від %d до %d, типово: %d)</translation> </message> <message> - <source>Failed to write to coin database</source> - <translation>Не вдалося записати до бази даних монет</translation> + <source>Set maximum block size in bytes (default: %d)</source> + <translation>Встановити максимальний розмір блоку у байтах (типово: %d)</translation> </message> <message> - <source>Failed to write transaction index</source> - <translation>Не вдалося записати індекс транзакції</translation> + <source>Specify wallet file (within data directory)</source> + <translation>Вкажіть файл гаманця (в межах каталогу даних)</translation> </message> <message> - <source>Failed to write undo data</source> - <translation>Не вдалося записати скасувати дані</translation> + <source>This is intended for regression testing tools and app development.</source> + <translation>Це призначено для інструментів регресивного тестування та розробки додатків.</translation> </message> <message> - <source>Generate coins (default: 0)</source> - <translation>Генерація монети (за замовчуванням: 0)</translation> + <source>Use UPnP to map the listening port (default: %u)</source> + <translation>Намагатись використовувати UPnP для відображення порту, що прослуховується, на роутері (типово: %u)</translation> </message> <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>Скільки блоків перевіряти під час запуску (типово: 288, 0 = всі)</translation> + <source>Verifying blocks...</source> + <translation>Перевірка блоків...</translation> </message> <message> - <source>Not enough file descriptors available.</source> - <translation>Бракує дескрипторів файлів, доступних.</translation> + <source>Verifying wallet...</source> + <translation>Перевірка гаманця... </translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>Встановити число потоків до дзвінків служба RPC (за замовчуванням: 4)</translation> + <source>Wallet %s resides outside data directory %s</source> + <translation>Гаманець %s знаходиться поза каталогом даних %s</translation> </message> <message> - <source>Verifying blocks...</source> - <translation>Перевірка блоків...</translation> + <source>Wallet options:</source> + <translation>Параметри гаманця:</translation> </message> <message> - <source>Verifying wallet...</source> - <translation>Перевірка гаманця... </translation> + <source>You need to rebuild the database using -reindex to change -txindex</source> + <translation>Вам необхідно перебудувати базу даних з використанням -reindex для того, щоб змінити -txindex</translation> </message> <message> <source>Imports blocks from external blk000??.dat file</source> <translation>Імпорт блоків з зовнішнього файлу 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>Дозволити підключення по протоколу JSON-RPC зі вказаного джерела. Правильною для <ip> є окрема IP-адреса (наприклад, 1.2.3.4), IP-адреса та маска підмережі (наприклад, 1.2.3.4/255.255.255.0) або CIDR-адреса (наприклад, 1.2.3.4/24). Цей параметр можна вказувати декілька разів.</translation> + </message> + <message> + <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> + <translation>Сталася помилка при спробі відкрити порт RPC-адреси %s:%u для прослуховування: %s</translation> + </message> + <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>Прив'язатися до даної адреси та вносити до білого списку учасників, що під'єднуються до неї. Використовуйте запис виду [хост]:порт для 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>Прив'язатися до даної адреси для прослуховування JSON-RPC підключень. Використовуйте запис виду [хост]:порт для IPv6. Цей параметр можна вказувати декілька разів (типово: прив'язуватися до всіх інтерфейсів)</translation> + </message> + <message> + <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> + <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>Error: Listening for incoming connections failed (listen returned error %s)</source> + <translation>Помилка: Не вдалося налаштувати прослуховування вхідних підключень (listen повернув помилку: %s)</translation> + </message> + <message> + <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Помилка: Параметр -socks не підтримується. Можливість вказувати версію SOCKS було видалено, так як підтримується лише 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>Виконати команду при надходженні важливого сповіщення або при спостереженні тривалого розгалуження ланцюжка (замість %s буде підставлено повідомлення)</translation> + </message> + <message> + <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> + <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>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>Максимальний розмір даних в транзакціях носіїв даних, що ми передаємо і добуваємо (за замовчуванням: %u)</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>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> + <translation>Встановити максимальний розмір транзакцій з високим пріоритетом та низькою комісією (в байтах) (типово: %d)</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>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> + <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>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>Учасники, що знаходяться в білому списку, не можуть бути заблоковані за DoS та їхні транзакції завжди ретранслюватимуться (навіть якщо вони є в пам'яті), що може бути корисним, наприклад, для шлюзу</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Не вдалося розпізнати адресу для -whitebind: «%s»</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 Розробники Bitcoin Core</translation> + </message> + <message> + <source>Could not parse -rpcbind value %s as network address</source> + <translation>Неможливо розпізнати мережеву адресу для параметру -rpcbind (%s)</translation> + </message> + <message> + <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> + <translation>Помилка при завантаженні wallet.dat: Гаманець потребує новішої версії Bitcoin Core</translation> + </message> + <message> + <source>Error: Unsupported argument -tor found, use -onion.</source> + <translation>Помилка: Параметр -tor не підтримується, використовуйте -onion</translation> + </message> + <message> + <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> + <translation>Комісія (в BTC/КБ), що додаватиметься до вихідних транзакцій (типово: %s)</translation> + </message> + <message> <source>Information</source> <translation>Інформація</translation> </message> <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>Підтримувати індекс повний транзакцій (за замовчуванням: 0)</translation> + <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>Вказано некоректну суму для параметру -minrelaytxfee: «%s»</translation> + </message> + <message> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>Вказано некоректну суму для параметру -mintxfee: «%s»</translation> + </message> + <message> + <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> + <translation>Вказано некоректну суму для параметру -paytxfee: «%s» (повинно бути щонайменше %s)</translation> + </message> + <message> + <source>Invalid netmask specified in -whitelist: '%s'</source> + <translation>Вказано неправильну маску підмережі для -whitelist: «%s»</translation> + </message> + <message> + <source>Keep at most <n> unconnectable blocks in memory (default: %u)</source> + <translation>Утримувати в пам'яті щонайбільше <n> блоків, не під'єднаних до основного ланцюжка (типово: %u)</translation> + </message> + <message> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Утримувати в пам'яті щонайбільше <n> транзакцій, що споживають невідомі входи (типово: %u)</translation> </message> <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>Максимальний буфер, <n>*1000 байт (типово: 5000)</translation> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>Необхідно вказати порт для -whitebind: «%s»</translation> </message> <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>Максимальній розмір вихідного буферу на одне з'єднання, <n>*1000 байт (типово: 1000)</translation> + <source>Node relay options:</source> + <translation>Параметри вузла ретрансляції:</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>Тільки приймати блок відповідності ланцюга вбудованих контрольно-пропускних пунктів (за замовчуванням: 1)</translation> + <source>Print block on startup, if found in block index</source> + <translation>Роздрукувати блок під час запуску (якщо він буде знайдений в індексі)</translation> </message> <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>Підключити тільки до вузлів в мережі <net> (IPv4, IPv6 або Tor)</translation> + <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> + <translation>Параметри RPC SSL: (див. Bitcoin Wiki для налаштування SSL)</translation> + </message> + <message> + <source>RPC server options:</source> + <translation>Параметри сервера RPC:</translation> + </message> + <message> + <source>Randomly drop 1 of every <n> network messages</source> + <translation>Випадковим чином відкидати 1 з <n> мережевих повідомлень</translation> + </message> + <message> + <source>Randomly fuzz 1 of every <n> network messages</source> + <translation>Випадковим чином пошкоджувати 1 з <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 minimum block size in bytes (default: 0)</source> - <translation>Встановити мінімальний розмір блоку у байтах (типово: 0)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Встановити операцію надсилання, як неоплатну операцію, якщо це можливо (за замовчуванням: %u)</translation> </message> <message> - <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> - <translation>Стискати файл debug.log під час старту клієнта (типово: 1 коли відсутутній параметр -debug)</translation> + <source>Show all debugging options (usage: --help -help-debug)</source> + <translation>Показати всі налагоджувальні параметри (використання: --help -help-debug)</translation> </message> <message> - <source>Signing transaction failed</source> - <translation>Підписання угоди не вдалося</translation> + <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> + <translation>Стискати файл debug.log під час старту клієнта (типово: 1 коли відсутній параметр -debug)</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>Вказати тайм-аут підключення у мілісекундах (типово: 5000)</translation> + <source>Signing transaction failed</source> + <translation>Підписання транзакції не вдалося</translation> </message> <message> - <source>System error: </source> - <translation>Системна помилка: </translation> + <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>Use UPnP to map the listening port (default: 0)</source> - <translation>Намагатись використовувати UPnP для відображення порту, що прослуховується на роутері (default: 0)</translation> + <source>Unable to bind to %s on this computer (bind returned error %s)</source> + <translation>Неможливо прив'язатися до %s на цьому комп'ютері (bind повернув помилку: %s)</translation> </message> <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Намагатись використовувати UPnP для відображення порту, що прослуховується на роутері (default: 1 when listening)</translation> + <translation>Намагатись використовувати UPnP для відображення порту, що прослуховується на роутері (типово: 1 коли прослуховується)</translation> </message> <message> <source>Username for JSON-RPC connections</source> <translation>Ім'я користувача для JSON-RPC-з'єднань</translation> </message> <message> + <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source> + <translation>Потрібно перезаписати гаманець: перезапустіть Bitcoin Core для завершення</translation> + </message> + <message> <source>Warning</source> <translation>Попередження</translation> </message> @@ -2179,6 +3271,22 @@ Address: %4 <translation>Увага: Поточна версія застаріла, необхідне оновлення!</translation> </message> <message> + <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Увага: Параметр -benchmark не підтримується та буде проігнорований, використовуйте -debug=bench.</translation> + </message> + <message> + <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Увага: Параметр -debugnet не підтримується та буде проігнорований, використовуйте -debug=net.</translation> + </message> + <message> + <source>Zapping all transactions from wallet...</source> + <translation>Видалення всіх транзакцій з гаманця...</translation> + </message> + <message> + <source>on startup</source> + <translation>під час запуску</translation> + </message> + <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat пошкоджено, відновлення не вдалося</translation> </message> @@ -2192,11 +3300,7 @@ Address: %4 </message> <message> <source>Upgrade wallet to latest format</source> - <translation>Модернізувати гаманець до останнього формату</translation> - </message> - <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>Встановити розмір пулу ключів <n> (типово: 100)</translation> + <translation>Модернізувати гаманець до найновішого формату</translation> </message> <message> <source>Rescan the block chain for missing wallet transactions</source> @@ -2207,14 +3311,6 @@ Address: %4 <translation>Використовувати OpenSSL (https) для JSON-RPC-з'єднань</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Файл сертифіката сервера (типово: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Закритий ключ сервера (типово: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Дана довідка</translation> </message> @@ -2231,18 +3327,190 @@ Address: %4 <translation>Помилка при завантаженні wallet.dat: Гаманець пошкоджено</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 = утримувати метадані транзакцій (до яких відноситься інформація про власника рахунку та запити платежів), 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>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source> + <translation>Якщо параметр paytxfee не встановлено, включити комісію, достатню для підтвердження транзакцій протягом n блоків (типово: %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> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Час в секундах, протягом якого відключені учасники з поганою поведінкою не зможуть підключитися (типово: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Виводити налагоджувальну інформацію (типово: %u, вказання <category> необов'язкове)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Використовувати окремий SOCKS5-проксі для з'єднання з учасниками через приховані сервіси Tor (типово: %s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(типово: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>Допустимі шифри (типово: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <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> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>Скільки блоків перевіряти під час запуску (типово: %u, 0 = всі)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Включити IP-адреси до налагоджувального виводу (типово: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <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> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Чекати на з'єднання на <port> (типово: %u, для тестової мережі: %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Підтримувати щонайбільше <n> з'єднань з учасниками (типово: %u)</translation> + </message> + <message> + <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> + <translation>Максимальний розмір вхідного буферу на одне з'єднання, <n>*1000 байтів (типово: %u)</translation> + </message> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <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> + <message> + <source>Print block tree on startup (default: %u)</source> + <translation>Роздрукувати дерево блоків під час запуску (типово: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Ретранслювати та створювати транзакції носіїв даних (типово: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <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> + <message> + <source>Server private key (default: %s)</source> + <translation>Закритий ключ сервера (типово: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Встановити розмір пулу ключів <n> (типово: %u)</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>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> + <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>Spend unconfirmed change when sending transactions (default: %u)</source> + <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> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Невідома мережа вказана в -onlynet: «%s»</translation> </message> <message> + <source>Cannot resolve -bind address: '%s'</source> + <translation>Не вдалося розпізнати адресу для -bind: «%s»</translation> + </message> + <message> + <source>Cannot resolve -externalip address: '%s'</source> + <translation>Не вдалося розпізнати адресу для -externalip: «%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_ur_PK.ts b/src/qt/locale/bitcoin_ur_PK.ts index ab9106ca03..86f3226269 100644 --- a/src/qt/locale/bitcoin_ur_PK.ts +++ b/src/qt/locale/bitcoin_ur_PK.ts @@ -1,4 +1,4 @@ -<TS language="ur_PK" version="2.1"> +<TS language="ur_PK" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -9,6 +9,34 @@ <source>Create a new address</source> <translation>نیا ایڈریس بنائیں</translation> </message> + <message> + <source>&New</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>&Export</source> + <translation>برآمد</translation> + </message> + <message> + <source>&Delete</source> + <translation>مٹا</translation> + </message> + <message> + <source>C&hoose</source> + <translation>چننا</translation> + </message> </context> <context> <name>AddressTableModel</name> @@ -73,10 +101,6 @@ <translation>رقم</translation> </message> <message> - <source>Address</source> - <translation> پتہ</translation> - </message> - <message> <source>Date</source> <translation>تاریخ</translation> </message> @@ -291,6 +315,10 @@ </context> <context> <name>WalletView</name> + <message> + <source>&Export</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 1a4d9f8108..54e649aede 100644 --- a/src/qt/locale/bitcoin_uz@Cyrl.ts +++ b/src/qt/locale/bitcoin_uz@Cyrl.ts @@ -1,4 +1,4 @@ -<TS language="uz@Cyrl" version="2.1"> +<TS language="uz@Cyrl" version="2.0"> <context> <name>AddressBookPage</name> <message> @@ -93,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> @@ -168,6 +172,10 @@ <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> + <message> <source>Warning: The Caps Lock key is on!</source> <translation>Диққат: Caps Lock тугмаси ёқилган!</translation> </message> @@ -207,10 +215,18 @@ <source>Wallet decryption failed</source> <translation>Ҳамённи коддан чиқариш амалга ошмади</translation> </message> - </context> + <message> + <source>Wallet passphrase was successfully changed.</source> + <translation>Ҳамён пароли муваффақиятли алмаштирилди.</translation> + </message> +</context> <context> <name>BitcoinGUI</name> <message> + <source>Sign &message...</source> + <translation>&Хабар ёзиш...</translation> + </message> + <message> <source>Synchronizing with network...</source> <translation>Тармоқ билан синхронланмоқда...</translation> </message> @@ -219,6 +235,10 @@ <translation>&Кўриб чиқиш</translation> </message> <message> + <source>Node</source> + <translation>Улам</translation> + </message> + <message> <source>Show general overview of wallet</source> <translation>Ҳамённинг умумий кўринишини кўрсатиш</translation> </message> @@ -239,10 +259,30 @@ <translation>Иловадан чиқиш</translation> </message> <message> + <source>About &Qt</source> + <translation>&Qt ҳақида</translation> + </message> + <message> + <source>Show information about Qt</source> + <translation>Qt ҳақидаги маълумотларни кўрсатиш</translation> + </message> + <message> <source>&Options...</source> <translation>&Мосламалар...</translation> </message> <message> + <source>&Encrypt Wallet...</source> + <translation>Ҳамённи &кодлаш...</translation> + </message> + <message> + <source>&Backup Wallet...</source> + <translation>Ҳамённи &заҳиралаш...</translation> + </message> + <message> + <source>&Change Passphrase...</source> + <translation>Махфий сўзни &ўзгартириш...</translation> + </message> + <message> <source>&Sending addresses...</source> <translation>&Жўнатилувчи манзиллар...</translation> </message> @@ -255,12 +295,88 @@ <translation>Интернет манзилни очиш</translation> </message> <message> + <source>Bitcoin Core client</source> + <translation>Bitcoin асос мижози</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>Тангаларни 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> + <message> <source>Change the passphrase used for wallet encryption</source> <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> + <message> + <source>Bitcoin</source> + <translation>Bitcoin</translation> + </message> + <message> + <source>Wallet</source> + <translation>Ҳамён</translation> + </message> + <message> + <source>&Send</source> + <translation>&Жўнатиш</translation> + </message> + <message> + <source>&Receive</source> + <translation>&Қабул қилиш</translation> + </message> + <message> + <source>Show information about Bitcoin Core</source> + <translation>Bitcoin Core ҳақидаги маълумотларни кўрсатиш</translation> + </message> + <message> + <source>&Show / Hide</source> + <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>Bitcoin манзилидан унинг эгаси эканлигингизни исботлаш учун хабарлар ёзинг</translation> + </message> + <message> + <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source> + <translation>Хабарларни махсус Bitcoin манзилларингиз билан ёзилганлигига ишонч ҳосил қилиш учун уларни тасдиқланг</translation> + </message> + <message> <source>&File</source> - <translation>& файл</translation> + <translation>&Файл</translation> </message> <message> <source>&Settings</source> @@ -275,16 +391,44 @@ <translation>Ички ойналар асбоблар панели</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>Request payments (generates QR codes and bitcoin: URIs)</source> + <translation>Тўловлар (QR кодлари ва bitcoin ёрдамида яратишлар: URI’лар) сўраш</translation> + </message> + <message> + <source>&About 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>Bitcoin’ни очиш: 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 буйруқлар матни мосламалари билан Bitcoin Core ёрдам хабарларини олиш рўйхатини кўрсатиш</translation> </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n та Bitcoin тармоғига фаол уланиш мавжуд</numerusform></translation> </message> <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>Ўтказма тарихи блоклари %1 та амалга оширилган. </translation> + <source>No block source available...</source> + <translation>Блок манбалари мавжуд эмас...</translation> </message> <message numerus="yes"> <source>%n hour(s)</source> @@ -307,10 +451,38 @@ <translation><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> <message> + <source>Catching up...</source> + <translation>Банд қилинмоқда...</translation> + </message> + <message> <source>Sent transaction</source> <translation>Жўнатилган операция</translation> </message> @@ -319,6 +491,18 @@ <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> @@ -329,30 +513,78 @@ </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> + <source>Amount:</source> + <translation>Миқдори:</translation> </message> <message> - <source>Address</source> - <translation>Манзил</translation> + <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>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>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> @@ -365,14 +597,138 @@ <translation>Кийматни нусхала</translation> </message> <message> + <source>Copy transaction ID</source> + <translation>Ўтказам рақамидан нусха олиш</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> + <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>Ҳар бир кирим +/- %1 сатоши(лар) билан ўзгариши мумкин.</translation> + </message> + <message> + <source>yes</source> + <translation>ҳа</translation> + </message> + <message> + <source>no</source> + <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> + <message> + <source>Can vary +/- 1 byte per input.</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>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> - </context> + <message> + <source>change from %1 (%2)</source> + <translation>%1 (%2)дан ўзгартириш</translation> + </message> + <message> + <source>(change)</source> + <translation>(ўзгартириш)</translation> + </message> +</context> <context> <name>EditAddressDialog</name> <message> @@ -384,6 +740,14 @@ <translation>&Ёрлик</translation> </message> <message> + <source>The label associated with this address list entry</source> + <translation>Ёрлиқ ушбу манзилар рўйхати ёзуви билан боғланган</translation> + </message> + <message> + <source>The address associated with this address list entry. This can only be modified for sending addresses.</source> + <translation>Манзил ушбу манзиллар рўйхати ёзуви билан боғланган. Уни фақат жўнатиладиган манзиллар учун ўзгартирса бўлади.</translation> + </message> + <message> <source>&Address</source> <translation>&Манзил</translation> </message> @@ -408,6 +772,10 @@ <translation>Киритилган "%1" манзили аллақачон манзил китобида.</translation> </message> <message> + <source>The entered address "%1" is not a valid Bitcoin address.</source> + <translation>Киритилган "%1" манзили тўғри Bitcoin манзили эмас.</translation> + </message> + <message> <source>Could not unlock wallet.</source> <translation>Ҳамён қулфдан чиқмади.</translation> </message> @@ -418,10 +786,38 @@ </context> <context> <name>FreespaceChecker</name> - </context> + <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> + <message> + <source>Path already exists, and is not a directory.</source> + <translation>Йўл аллақачон мавжуд. У директория эмас.</translation> + </message> + <message> + <source>Cannot create data directory here.</source> + <translation>Маълумотлар директориясини бу ерда яратиб бўлмайди..</translation> + </message> +</context> <context> <name>HelpMessageDialog</name> <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>version</source> + <translation>версияси</translation> + </message> + <message> <source>(%1-bit)</source> <translation>(%1-bit)</translation> </message> @@ -433,20 +829,216 @@ <source>Usage:</source> <translation>Фойдаланиш:</translation> </message> - </context> + <message> + <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> + <message> + <source>Welcome</source> + <translation>Хуш келибсиз</translation> + </message> + <message> + <source>Welcome to Bitcoin Core.</source> + <translation>"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>Биринчи марта дастур ишга тушгани каби сиз Bitcoin Core маълумотларини жойлаштирадиган жойни танлашингиз мумкин.</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 юклаб олинади ва Bitcoin блок занжири нусхаси жойлаштирилади. Камида %1GB маълумот ушбу директорияга жойлаштирилади ва вақт давомида ўсиб боради. Ҳамён ҳам ушбу директорияда жойлашади.</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>Bitcoin Core</translation> + </message> + <message> + <source>Error: Specified data directory "%1" cannot be created.</source> + <translation>Хато: кўрсатилган "%1" маълумотлар директориясини яратиб бўлмайди.</translation> + </message> + <message> + <source>Error</source> + <translation>Хатолик</translation> + </message> </context> <context> <name>OpenURIDialog</name> - </context> + <message> + <source>Open URI</source> + <translation>URI ни очиш</translation> + </message> + <message> + <source>Open payment request from URI or file</source> + <translation>URL файлдан тўлов сўровларини очиш</translation> + </message> + <message> + <source>URI:</source> + <translation>URI:</translation> + </message> + <message> + <source>Select payment request file</source> + <translation>Тўлов сўрови файлини танлаш</translation> + </message> + <message> + <source>Select payment request file to open</source> + <translation>Очиш учун тўлов сўрови файлини танлаш</translation> + </message> +</context> <context> <name>OptionsDialog</name> <message> <source>Options</source> <translation>Танламалар</translation> </message> - </context> + <message> + <source>&Main</source> + <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> + <message> + <source>MB</source> + <translation>МБ</translation> + </message> + <message> + <source>Number of script &verification threads</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>Proxy &IP:</source> + <translation>Прокси &IP рақами:</translation> + </message> + <message> + <source>&Port:</source> + <translation>&Порт:</translation> + </message> + <message> + <source>Port of the proxy (e.g. 9050)</source> + <translation>Прокси порти (e.g. 9050)</translation> + </message> + <message> + <source>&Window</source> + <translation>&Ойна</translation> + </message> + <message> + <source>Show only a tray icon after minimizing the window.</source> + <translation>Ойна йиғилгандан сўнг фақат трэй нишончаси кўрсатилсин.</translation> + </message> + <message> + <source>&Minimize to the tray instead of the taskbar</source> + <translation>Манзиллар панели ўрнига трэйни &йиғиш</translation> + </message> + <message> + <source>M&inimize on close</source> + <translation>Ёпишда й&иғиш</translation> + </message> + <message> + <source>&Display</source> + <translation>&Кўрсатиш</translation> + </message> + <message> + <source>User Interface &language:</source> + <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> + <message> + <source>&OK</source> + <translation>&OK</translation> + </message> + <message> + <source>&Cancel</source> + <translation>&Бекор қилиш</translation> + </message> + <message> + <source>default</source> + <translation>стандарт</translation> + </message> + <message> + <source>none</source> + <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>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> + <message> + <source>The supplied proxy address is invalid.</source> + <translation>Келтирилган прокси манзили ишламайди.</translation> + </message> +</context> <context> <name>OverviewPage</name> <message> @@ -454,8 +1046,60 @@ <translation>Шакл</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>Жорий утказмалар</b></translation> + <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>Кўрсатилган маълумот эскирган бўлиши мумкин. Ҳамёнингиз алоқа ўрнатилгандан сўнг Bitcoin тармоқ билан автоматик тарзда синхронланади, аммо жараён ҳалигача тугалланмади.</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>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</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> + <message> + <source>Total:</source> + <translation>Жами:</translation> + </message> + <message> + <source>Your current total balance</source> + <translation>Жорий умумий балансингиз</translation> + </message> + <message> + <source>Your current balance in watch-only addresses</source> + <translation>Жорий балансингиз фақат кўринадиган манзилларда</translation> + </message> + <message> + <source>Spendable:</source> + <translation>Сарфланадиган:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Сўнгги пул ўтказмалари</translation> </message> </context> <context> @@ -463,35 +1107,291 @@ </context> <context> <name>PeerTableModel</name> - </context> + <message> + <source>Ping Time</source> + <translation>Ping вақти</translation> + </message> +</context> <context> <name>QObject</name> <message> <source>Amount</source> <translation>Миқдори</translation> </message> - </context> + <message> + <source>%1 m</source> + <translation>%1 д</translation> + </message> + <message> + <source>%1 s</source> + <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> + <message> + <source>N/A</source> + <translation>Тўғри келмайди</translation> + </message> + <message> + <source>%1 ms</source> + <translation>%1 мс</translation> + </message> +</context> <context> <name>QRImageWidget</name> - </context> + <message> + <source>&Save Image...</source> + <translation>Расмни &сақлаш</translation> + </message> + <message> + <source>&Copy Image</source> + <translation>Расмдан &нусха олиш</translation> + </message> + <message> + <source>Save QR Code</source> + <translation>QR кодни сақлаш</translation> + </message> + <message> + <source>PNG Image (*.png)</source> + <translation>PNG расм (*.png)</translation> + </message> +</context> <context> <name>RPCConsole</name> <message> + <source>Client name</source> + <translation>Мижоз номи</translation> + </message> + <message> + <source>N/A</source> + <translation>Тўғри келмайди</translation> + </message> + <message> + <source>Client version</source> + <translation>Мижоз номи</translation> + </message> + <message> + <source>&Information</source> + <translation>&Маълумот</translation> + </message> + <message> + <source>Debug window</source> + <translation>Тузатиш ойнаси</translation> + </message> + <message> <source>General</source> <translation>Асосий</translation> </message> <message> + <source>Using OpenSSL version</source> + <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> + <message> <source>Name</source> <translation>Ном</translation> </message> - </context> + <message> + <source>&Peers</source> + <translation>&Уламлар</translation> + </message> + <message> + <source>Select a peer to view detailed information.</source> + <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>Жўнатилган байтлар</translation> + </message> + <message> + <source>Bytes Received</source> + <translation>Қабул қилинган байтлар</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Ping вақти</translation> + </message> + <message> + <source>Last block time</source> + <translation>Сўнгги блок вақти</translation> + </message> + <message> + <source>&Open</source> + <translation>&Очиш</translation> + </message> + <message> + <source>&Console</source> + <translation>&Терминал</translation> + </message> + <message> + <source>&Network Traffic</source> + <translation>&Тармоқ трафиги</translation> + </message> + <message> + <source>&Clear</source> + <translation>&Тозалаш</translation> + </message> + <message> + <source>Totals</source> + <translation>Жами</translation> + </message> + <message> + <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>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> + <message> + <source>Type <b>help</b> for an overview of available commands.</source> + <translation>Мавжуд буйруқларни кўриш учун <b>help</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>Unknown</source> + <translation>Номаълум</translation> + </message> + <message> + <source>Fetching...</source> + <translation>Олинмоқда...</translation> + </message> +</context> <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>&Миқдор:</translation> + </message> + <message> <source>&Label:</source> <translation>&Ёрлиқ:</translation> </message> <message> + <source>&Message:</source> + <translation>&Хабар:</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>Олдинги фойдаланилган қабул қилинган манзиллардан биридан қайта фойдаланилсин. Хавсизлик ва махфийлик муаммолар мавжуд манзиллардан қайта фойдаланилмоқда. Бундан тўлов сўров қайта яратилмагунича фойдаланманг.</translation> + </message> + <message> + <source>An optional label to associate with the new receiving address.</source> + <translation>Янги қабул қилинаётган манзил билан боғланган танланадиган ёрлиқ.</translation> + </message> + <message> + <source>Use this form to request payments. All fields are <b>optional</b>.</source> + <translation>Ушбу сўровдан тўловларни сўраш учун фойдаланинг. Барча майдонлар <b>мажбурий эмас</b>.</translation> + </message> + <message> + <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source> + <translation>Хоҳланган миқдор сўрови. Кўрсатилган миқдорни сўраш учун буни бўш ёки ноль қолдиринг.</translation> + </message> + <message> + <source>Clear all fields of the form.</source> + <translation>Шаклнинг барча майдончаларини тозалаш</translation> + </message> + <message> + <source>Clear</source> + <translation>Тозалаш</translation> + </message> + <message> + <source>Requested payments history</source> + <translation>Сўралган тўлов тарихи</translation> + </message> + <message> <source>Copy label</source> <translation>Ёрликни нусхала</translation> </message> @@ -507,6 +1407,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>&Save Image...</source> + <translation>Расмни &сақлаш</translation> + </message> + <message> <source>Address</source> <translation>Манзил</translation> </message> @@ -545,14 +1449,54 @@ <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>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>Send to multiple recipients at once</source> <translation>Бирданига бир нечта қабул қилувчиларга жўнатиш</translation> </message> <message> + <source>Clear all fields of the form.</source> + <translation>Шаклнинг барча майдончаларини тозалаш</translation> + </message> + <message> + <source>Dust:</source> + <translation>Ахлат қутиси:</translation> + </message> + <message> <source>Balance:</source> <translation>Баланс</translation> </message> @@ -565,18 +1509,62 @@ <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>The amount to pay must be larger than 0.</source> <translation>Тўлов миқдори 0. дан катта бўлиши керак. </translation> </message> <message> + <source>Warning: Invalid Bitcoin address</source> + <translation>Диққат: Нотўғр Bitcoin манзили</translation> + </message> + <message> <source>(no label)</source> <translation>(Ёрлик мавжуд эмас)</translation> </message> - </context> + <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> + </message> +</context> <context> <name>SendCoinsEntry</name> <message> @@ -625,10 +1613,18 @@ <source>Alt+P</source> <translation>Alt+P</translation> </message> + <message> + <source>Signature</source> + <translation>Имзо</translation> + </message> </context> <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> @@ -828,6 +1824,10 @@ <translation>Кийматни нусхала</translation> </message> <message> + <source>Copy transaction ID</source> + <translation>Ўтказам рақамидан нусха олиш</translation> + </message> + <message> <source>Edit label</source> <translation>Ёрликни тахрирлаш</translation> </message> @@ -903,14 +1903,6 @@ <translation>Танламалар:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>Мослаш файлини кўрсатинг (default: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>pid файлини кўрсатинг (default: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>Маълумотлар директориясини кўрсатинг</translation> </message> @@ -927,10 +1919,18 @@ <translation>Синов тармоғидан фойдаланинг</translation> </message> <message> + <source>Information</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> @@ -939,14 +1939,6 @@ <translation>JSON-RPC уланишлари учун OpenSSL (https)дан фойдаланиш</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>Сервер сертификат файли (default: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>Сервер махфий калити (бирламчи: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>Бу ёрдам хабари</translation> </message> @@ -970,5 +1962,9 @@ <source>Done loading</source> <translation>Юклаш тайёр</translation> </message> - </context> + <message> + <source>Error</source> + <translation>Хатолик</translation> + </message> +</context> </TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_vi.ts b/src/qt/locale/bitcoin_vi.ts index e03349b383..3ca5605883 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> @@ -53,10 +53,6 @@ <translation>Số lượng</translation> </message> <message> - <source>Address</source> - <translation>Địa chỉ</translation> - </message> - <message> <source>(no label)</source> <translation>(chưa có nhãn)</translation> </message> diff --git a/src/qt/locale/bitcoin_vi_VN.ts b/src/qt/locale/bitcoin_vi_VN.ts index 20ebd7b594..bf76c8638a 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> diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index cd0caf53a1..94d0675bfd 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> @@ -387,10 +387,6 @@ <translation>分页工具栏</translation> </message> <message> - <source>[testnet]</source> - <translation>[测试网络]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>比特币核心</translation> </message> @@ -430,10 +426,6 @@ <source>No block source available...</source> <translation>沒有可用的区块来源...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>已处理 %1 个交易历史数据块。</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n 小时</numerusform></translation> @@ -525,10 +517,6 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>选择交易源地址</translation> - </message> - <message> <source>Quantity:</source> <translation>总量:</translation> </message> @@ -577,10 +565,6 @@ Address: %4 <translation>金额</translation> </message> <message> - <source>Address</source> - <translation>地址</translation> - </message> - <message> <source>Date</source> <translation>日期</translation> </message> @@ -905,15 +889,7 @@ Address: %4 <source>Error</source> <translation>错误</translation> </message> - <message> - <source>GB of free space available</source> - <translation>可用空间(GB)</translation> - </message> - <message> - <source>(of %1GB needed)</source> - <translation>(需要 %1GB)</translation> - </message> -</context> + </context> <context> <name>OpenURIDialog</name> <message> @@ -948,14 +924,6 @@ Address: %4 <translation>主要(&M)</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>可选的每 kB 交易费,这有助于您的交易被更快的处理。大多数交易都是 1 kB。</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>支付交易费用(&F)</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>登录系统后自动开启比特币客户端</translation> </message> @@ -984,14 +952,6 @@ Address: %4 <translation>允许流入连接</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>通过 SOCKS 代理连接到比特币网络。</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>通过 SO&CKS 代理连接 (默认代理):</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> @@ -1155,10 +1115,6 @@ Address: %4 <translation>现在显示的消息可能是过期的. 在连接上比特币网络节点后,您的钱包将自动与网络同步,但是这个过程还没有完成。</translation> </message> <message> - <source>Wallet</source> - <translation>钱包</translation> - </message> - <message> <source>Watch-only:</source> <translation>查看-只有:</translation> </message> @@ -1195,10 +1151,6 @@ Address: %4 <translation>您当前的总余额</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>最近交易记录</b></translation> - </message> - <message> <source>out of sync</source> <translation>数据同步中</translation> </message> @@ -1438,10 +1390,6 @@ Address: %4 <translation>服务</translation> </message> <message> - <source>Sync Node</source> - <translation>同步节点</translation> - </message> - <message> <source>Starting Height</source> <translation>开始高度</translation> </message> @@ -1570,14 +1518,6 @@ Address: %4 <translation>传出</translation> </message> <message> - <source>Yes</source> - <translation>是</translation> - </message> - <message> - <source>No</source> - <translation>否</translation> - </message> - <message> <source>Unknown</source> <translation>未知</translation> </message> @@ -2609,29 +2549,11 @@ Address: %4 </translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>指定配置文件 (默认为 bitcoin.conf) -</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>指定 pid 文件 (默认为 bitcoind.pid) -</translation> - </message> - <message> <source>Specify data directory</source> <translation>指定数据目录 </translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>监听端口连接 <port>(缺省: 8333 或测试网络: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>最大连接数 <n> (缺省: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>连接一个节点并获取对端地址,然后断开连接</translation> </message> @@ -2640,18 +2562,6 @@ Address: %4 <translation>指定您的公共地址</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>断开行为不端对端阀值(缺省: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>重新连接异常节点的秒数(缺省: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>JSON-RPC连接监听端口<port> (缺省:8332 testnet:18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>接受命令行和 JSON-RPC 命令 </translation> @@ -2696,18 +2606,10 @@ rpcpassword=%s </translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>可接受的密码(默认:TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>绑定指定的IP地址开始监听。IPv6地址请使用[host]:port 格式</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>自由交易不断的速率限制为<n>*1000 字节每分钟(默认值:15)</translation> - </message> - <message> <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> <translation>进入回归测试模式,它采用一种特殊的可立即解决的区块链模拟情况。</translation> </message> @@ -2724,14 +2626,6 @@ rpcpassword=%s <translation>当最佳区块变化时执行命令 (命令行中的 %s 会被替换成区块哈希值)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>从缓冲池清理磁盘数据库活动日志每<n>兆字节 (默认值: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>如何有效的验证checkblocks区块(0-4, 默认值: 3)</translation> - </message> - <message> <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> <translation>在-genproclimit这种模式下控制产出多少区块</translation> </message> @@ -2740,10 +2634,6 @@ rpcpassword=%s <translation>设置脚本验证的程序 (%u 到 %d, 0 = 自动, <0 = 保留自由的核心, 默认值: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>设置处理器生成的限制 (-1 = 无限, 默认值: -1)</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>这是测试用的预发布版本 - 请谨慎使用 - 不要用来挖矿,或者在正式商用环境下使用</translation> </message> @@ -2752,10 +2642,6 @@ rpcpassword=%s <translation>无法 %s的绑定到电脑上,比特币核心钱包可能已经在运行。</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>连接至 Tor隐藏服务器时 使用不同的SOCKS5代理 (缺省: -proxy) </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> @@ -2780,10 +2666,6 @@ rpcpassword=%s <translation>(默认值: 1)</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(默认: wallet.dat)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> 可能是:</translation> </message> @@ -2812,10 +2694,6 @@ rpcpassword=%s <translation>调试/测试选项:</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>禁止使用安全模式,重新写入一个真正的安全模式日志(默认值: 0)</translation> - </message> - <message> <source>Discover own IP address (default: 1 when listening and no -externalip)</source> <translation>发现自己的IP地址(缺省:不带 -externalip 参数监听时设置为1)</translation> </message> @@ -2852,66 +2730,10 @@ rpcpassword=%s <translation>错误:钱包被锁定,无法创建交易!</translation> </message> <message> - <source>Error: system error: </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>Failed to read block info</source> - <translation>无法读取数据块信息</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>读取数据块失败</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>无法同步数据块索引</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>无法写入数据块索引</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>无法写入数据块信息</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>无法写数据块</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>无法写入文件信息</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>无法写入coin数据库</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>无法写入交易索引</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>无法写入回滚信息</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>强制安全模式(默认值: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>生成比特币(默认为 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>启动时检测多少个数据块(缺省:288,0=所有)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>如果<category>未提供,将输出所有调试信息。</translation> </message> @@ -2932,10 +2754,6 @@ rpcpassword=%s <translation>没有足够的文件描述符可用。</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>调试信息输出时,前面加上时间戳 (缺省: 1)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files</source> <translation>重新为当前的blk000??.dat文件建立索引</translation> </message> @@ -2948,18 +2766,10 @@ rpcpassword=%s <translation>设置最大区块大小 (默认: %d,单位字节)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>设置使用调用服务 RPC 的线程数量(默认:4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>指定钱包文件(数据目录内)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>付款时允许使用未确认的零钱 (缺省: 1)</translation> - </message> - <message> <source>This is intended for regression testing tools and app development.</source> <translation>这是用于回归测试和应用开发目的。</translation> </message> @@ -2996,10 +2806,6 @@ rpcpassword=%s <translation>当收到相关提醒或者我们看到一个长分叉时执行命令(%s 将替换为消息)</translation> </message> <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>输出调试信息(默认为0,提供 <category> 是可选的)</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> @@ -3008,10 +2814,6 @@ rpcpassword=%s <translation>设置 高优先级/低交易费 交易的最大字节 (缺省: %d)</translation> </message> <message> - <source>Always query for peer addresses via DNS lookup (default: 0)</source> - <translation>始终通过 DNS 查询对等端地址 (默认: 0)</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>无法解析 -whitebind 地址: '%s'</translation> </message> @@ -3036,10 +2838,6 @@ rpcpassword=%s <translation>错误:发现了不支持的参数 -tor,请使用 -onion。</translation> </message> <message> - <source>Include IP addresses in debug output (default: 0)</source> - <translation>在调试输出中包含IP地址 (默认: 0)</translation> - </message> - <message> <source>Information</source> <translation>信息</translation> </message> @@ -3064,26 +2862,6 @@ rpcpassword=%s <translation>-whitelist: '%s' 指定的网络掩码无效</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>签名缓冲大小限制每<n> 条目 (默认值: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>开采区块时,日志优先级和手续费每KB (默认值: 0)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>维护一份完整的交易索引(缺省:0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>每个连接的最大接收缓存,<n>*1000 字节(缺省:5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>每个连接的最大发送缓存,<n>*1000 字节(缺省:1000)</translation> - </message> - <message> <source>Need to specify a port with -whitebind: '%s'</source> <translation>-whitebind: '%s' 需要指定一个端口</translation> </message> @@ -3092,22 +2870,10 @@ rpcpassword=%s <translation>节点中继选项:</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>仅接受符合客户端检查点设置的数据块文件</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>仅连接至指定网络的节点<net>(IPv4, IPv6 或者 Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>如果在搜索区块中找到,请启动打印区块</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>启动时打印区块树 (默认值: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>RPC SSL选项:(见有关比特币设置用于SSL说明的维基百科)</translation> </message> @@ -3124,26 +2890,10 @@ rpcpassword=%s <translation>随机每1个模拟测试<n>网络信息</translation> </message> <message> - <source>Relay non-P2SH multisig (default: 1)</source> - <translation>中转non-P2SH multisig (默认值: 1)</translation> - </message> - <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>运行一个程序,定时清理钱包 (默认值:1)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>跟踪/调试信息输出到控制台,不输出到 debug.log 文件</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>设置最小数据块大小(缺省:0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>设置DB_PRIVATE钱包标志DB环境 (默认值: 1)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>显示所有调试选项 (用法: --帮助 -帮助调试)</translation> </message> @@ -3156,14 +2906,6 @@ rpcpassword=%s <translation>签署交易失败</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>设置连接超时时间(缺省:5000毫秒)</translation> - </message> - <message> - <source>System error: </source> - <translation>系统错误:</translation> - </message> - <message> <source>This is experimental software.</source> <translation>这是实验性的软件。</translation> </message> @@ -3184,10 +2926,6 @@ rpcpassword=%s <translation>无法在此计算机上绑定 %s (绑定返回错误 %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>使用UPnP映射监听端口 (缺省: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>使用UPnp映射监听端口(缺省: 监听状态设为1)</translation> </message> @@ -3241,11 +2979,6 @@ rpcpassword=%s <translation>将钱包升级到最新的格式</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>设置密钥池大小为 <n> (缺省: 100) -</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>重新扫描区块链以查找遗漏的钱包交易</translation> </message> @@ -3254,16 +2987,6 @@ rpcpassword=%s <translation>为 JSON-RPC 连接使用 OpenSSL (https) 连接</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>服务器证书 (默认为 server.cert) -</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>服务器私钥 (默认为 server.pem) -</translation> - </message> - <message> <source>This help message</source> <translation>本帮助信息 </translation> 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 51c0780ab0..56d598fc64 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> @@ -7,7 +7,7 @@ </message> <message> <source>Create a new address</source> - <translation>製造新的位址</translation> + <translation>新增新的位址</translation> </message> <message> <source>&New</source> @@ -391,10 +391,6 @@ <translation>分頁工具列</translation> </message> <message> - <source>[testnet]</source> - <translation>[testnet]</translation> - </message> - <message> <source>Bitcoin Core</source> <translation>位元幣核心</translation> </message> @@ -434,10 +430,6 @@ <source>No block source available...</source> <translation>沒有可用的區塊來源...</translation> </message> - <message> - <source>Processed %1 blocks of transaction history.</source> - <translation>已處理了 %1 個區塊的交易紀錄。</translation> - </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n 個小時</numerusform></translation> @@ -486,6 +478,10 @@ <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> @@ -529,8 +525,8 @@ Address: %4 <context> <name>CoinControlDialog</name> <message> - <source>Coin Control Address Selection</source> - <translation>錢幣控制的位址選擇</translation> + <source>Coin Selection</source> + <translation>選擇錢幣</translation> </message> <message> <source>Quantity:</source> @@ -581,10 +577,6 @@ Address: %4 <translation>金額</translation> </message> <message> - <source>Address</source> - <translation>位址</translation> - </message> - <message> <source>Date</source> <translation>日期</translation> </message> @@ -916,13 +908,13 @@ Address: %4 <source>Error</source> <translation>錯誤</translation> </message> - <message> - <source>GB of free space available</source> - <translation>GB 可用空間</translation> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>可用空間尚存 %n GB</numerusform></translation> </message> - <message> - <source>(of %1GB needed)</source> - <translation>(需要 %1GB)</translation> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(需要 %n GB)</numerusform></translation> </message> </context> <context> @@ -959,14 +951,6 @@ Address: %4 <translation>主要</translation> </message> <message> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>每一千位元組(kB)要付的交易手續費,如果有付可以加速網路處理你的交易。大部份交易資料的大小是 1 kB.</translation> - </message> - <message> - <source>Pay transaction &fee</source> - <translation>付交易手續費</translation> - </message> - <message> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>在登入系統後自動啓動位元幣軟體。</translation> </message> @@ -995,14 +979,6 @@ Address: %4 <translation>接受外來連線</translation> </message> <message> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation>透過 SOCKS 代理伺服器來連線到位元幣網路。</translation> - </message> - <message> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation>透過 SOCKS 代理伺服器連線(預設代理伺服器):</translation> - </message> - <message> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation>代理伺服器的網際網路位址(像是 IPv4 的 127.0.0.1 或 IPv6 的 ::1)</translation> </message> @@ -1063,6 +1039,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> @@ -1166,10 +1150,6 @@ Address: %4 <translation>顯示的資訊可能是過期的。跟位元幣網路的連線建立後,你的錢包會自動和網路同步,但是這個步驟還沒完成。</translation> </message> <message> - <source>Wallet</source> - <translation>錢包</translation> - </message> - <message> <source>Watch-only:</source> <translation>只能看:</translation> </message> @@ -1198,6 +1178,10 @@ Address: %4 <translation>還沒成熟的開採金額</translation> </message> <message> + <source>Balances</source> + <translation>餘額</translation> + </message> + <message> <source>Total:</source> <translation>總金額:</translation> </message> @@ -1210,6 +1194,14 @@ Address: %4 <translation>所有只能看位址的目前餘額</translation> </message> <message> + <source>Spendable:</source> + <translation>可支配:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>最近的交易</translation> + </message> + <message> <source>Unconfirmed transactions to watch-only addresses</source> <translation>所有只能看位址還沒確認的交易</translation> </message> @@ -1222,10 +1214,6 @@ Address: %4 <translation>所有只能看位址的目前全部餘額</translation> </message> <message> - <source><b>Recent transactions</b></source> - <translation><b>最近交易</b></translation> - </message> - <message> <source>out of sync</source> <translation>還沒同步</translation> </message> @@ -1485,10 +1473,6 @@ Address: %4 <translation>服務</translation> </message> <message> - <source>Sync Node</source> - <translation>同步節點</translation> - </message> - <message> <source>Starting Height</source> <translation>起始高度</translation> </message> @@ -1617,14 +1601,6 @@ Address: %4 <translation>出去</translation> </message> <message> - <source>Yes</source> - <translation>是</translation> - </message> - <message> - <source>No</source> - <translation>否</translation> - </message> - <message> <source>Unknown</source> <translation>不明</translation> </message> @@ -1861,6 +1837,38 @@ Address: %4 <translation>自定找零位址</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>交易手續費:</translation> + </message> + <message> + <source>Choose...</source> + <translation>選擇...</translation> + </message> + <message> + <source>collapse fee-settings</source> + <translation>展開手續費設定</translation> + </message> + <message> + <source>Minimize</source> + <translation>最小化</translation> + </message> + <message> + <source>per kilobyte</source> + <translation>每千位元組</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(請看提示)</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>確認時間:</translation> + </message> + <message> + <source>Send as zero-fee transaction if possible</source> + <translation>盡可能送不用付手續費的交易</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>一次付給多個收款人</translation> </message> @@ -2473,6 +2481,10 @@ Address: %4 <translation>開採所得</translation> </message> <message> + <source>watch-only</source> + <translation>只能看</translation> + </message> + <message> <source>(n/a)</source> <translation>(不適用)</translation> </message> @@ -2489,6 +2501,10 @@ Address: %4 <translation>交易的種類。</translation> </message> <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>不論如何有一個只能觀看的地只有參與這次的交易</translation> + </message> + <message> <source>Destination address of transaction.</source> <translation>交易的目的地位址。</translation> </message> @@ -2584,6 +2600,10 @@ Address: %4 <translation>匯出交易記錄</translation> </message> <message> + <source>Watch-only</source> + <translation>只能觀看的</translation> + </message> + <message> <source>Exporting Failed</source> <translation>匯出失敗</translation> </message> @@ -2699,26 +2719,10 @@ Address: %4 <translation>選項:</translation> </message> <message> - <source>Specify configuration file (default: bitcoin.conf)</source> - <translation>指定設定檔(預設值: bitcoin.conf)</translation> - </message> - <message> - <source>Specify pid file (default: bitcoind.pid)</source> - <translation>指定行程識別碼(PID)檔(預設值: bitcoind.pid)</translation> - </message> - <message> <source>Specify data directory</source> <translation>指定資料目錄</translation> </message> <message> - <source>Listen for connections on <port> (default: 8333 or testnet: 18333)</source> - <translation>在通訊埠 <port> 聽候連線(預設值: 8333, 或若是測試網路: 18333)</translation> - </message> - <message> - <source>Maintain at most <n> connections to peers (default: 125)</source> - <translation>維持連線節點數的上限為 <n> 個(預設值: 125)</translation> - </message> - <message> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>連線到某個節點來取得其它節點的位址,然後斷線</translation> </message> @@ -2727,18 +2731,6 @@ Address: %4 <translation>指定自己的公開位址</translation> </message> <message> - <source>Threshold for disconnecting misbehaving peers (default: 100)</source> - <translation>把異常節點斷線的臨界值(預設值: 100)</translation> - </message> - <message> - <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> - <translation>拒絕跟異常節點連線的秒數(預設值: 86400)</translation> - </message> - <message> - <source>Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)</source> - <translation>在通訊埠 <port> 聽候 JSON-RPC 連線(預設值: 8332, 或若是測試網路: 18332)</translation> - </message> - <message> <source>Accept command line and JSON-RPC commands</source> <translation>接受指令列和 JSON-RPC 指令 </translation> @@ -2780,22 +2772,18 @@ rpcpassword=%s alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> </message> <message> - <source>Acceptable ciphers (default: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</source> - <translation>可接受的加密演算法 (預設值: TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)</translation> - </message> - <message> <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> <translation>和指定的位址繫結,並且一直在指定位址聽候連線。IPv6 請用 [主機]:通訊埠 這種格式</translation> </message> <message> - <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)</source> - <translation>對沒付手續費的交易持續限制一分鐘內最多只能有 <n> 千位元組 (預設值: 15)</translation> - </message> - <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> <translation>清掉錢包裡的所有交易,並且在下次啟動時,使用 -rescan 來從區塊鏈中復原回來。</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>這套軟體是依據 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> @@ -2812,14 +2800,6 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>當錢包有交易改變時要執行的指令(指令中的 %s 會被取代成交易識別碼)</translation> </message> <message> - <source>Flush database activity from memory pool to disk log every <n> megabytes (default: 100)</source> - <translation>每當累積到 <n> 百萬位元組(MB)時,才將資料庫的變動從記憶體暫存池中寫進磁碟紀錄檔 (預設值: 100)</translation> - </message> - <message> - <source>How thorough the block verification of -checkblocks is (0-4, default: 3)</source> - <translation>使用 -checkblocks 檢查區塊的仔細程度 (0 到 4,預設值: 3)</translation> - </message> - <message> <source>In this mode -genproclimit controls how many blocks are generated immediately.</source> <translation>在這個運作模式下,-genproclimit 選項控制立刻產生出的區塊數目。</translation> </message> @@ -2828,10 +2808,6 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>設定指令碼驗證的執行緒數目 (%u 到 %d,0 表示程式自動決定,小於 0 表示保留處理器核心不用的數目,預設值: %d)</translation> </message> <message> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: -1)</source> - <translation>當生產位元幣打開時,設定處理器使用數目限制 (-1 表示不限制,預設值: -1)</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>這是個還沒發表的測試版本 - 使用請自負風險 - 請不要用來開採或商業應用</translation> </message> @@ -2840,10 +2816,6 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>沒辦法繫結在這台電腦上的 %s 。位元幣核心可能已經在執行了。</translation> </message> <message> - <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)</source> - <translation>使用另外的 SOCK5 代理伺服器,來透過 Tor 隱藏服務跟節點聯繫(預設值: 同 -proxy)</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> @@ -2864,12 +2836,12 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>警告: 錢包檔 wallet.dat 壞掉,但資料被拯救回來了!原來的 wallet.dat 會改儲存在 %s, 檔名是 wallet.{timestamp}.bak. 如果餘額或交易資料有誤,你應該要用備份資料復原回來。</translation> </message> <message> - <source>(default: 1)</source> - <translation>(預設值: 1)</translation> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>把來自指定網域或位址的節點放進白名單。這個選項可以設定多次。</translation> </message> <message> - <source>(default: wallet.dat)</source> - <translation>(預設值: wallet.dat)</translation> + <source>(default: 1)</source> + <translation>(預設值: 1)</translation> </message> <message> <source><category> can be:</source> @@ -2900,16 +2872,12 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>除錯與測試選項</translation> </message> <message> - <source>Disable safemode, override a real safe mode event (default: 0)</source> - <translation>不進入安全模式,用在真的發生需要進入安全模式的事件時,強制不進入 (預設值: 0)</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> + <translation>不要載入錢包,並且拿掉錢包相關的 RPC 功能請求。</translation> </message> <message> <source>Do you want to rebuild the block database now?</source> @@ -2932,6 +2900,10 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <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> @@ -2940,66 +2912,10 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>錯誤: 錢包被上鎖了,沒辦法製造新的交易!</translation> </message> <message> - <source>Error: system error: </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>Failed to read block info</source> - <translation>讀取區塊資訊失敗</translation> - </message> - <message> - <source>Failed to read block</source> - <translation>讀取區塊失敗</translation> - </message> - <message> - <source>Failed to sync block index</source> - <translation>同步區塊索引失敗</translation> - </message> - <message> - <source>Failed to write block index</source> - <translation>把區塊索引寫進去失敗了</translation> - </message> - <message> - <source>Failed to write block info</source> - <translation>把區塊資訊寫進去失敗了</translation> - </message> - <message> - <source>Failed to write block</source> - <translation>把區塊資料寫進去失敗了</translation> - </message> - <message> - <source>Failed to write file info</source> - <translation>把檔案資訊寫進去失敗了</translation> - </message> - <message> - <source>Failed to write to coin database</source> - <translation>寫進錢幣資料庫失敗了</translation> - </message> - <message> - <source>Failed to write transaction index</source> - <translation>把交易索引寫進去失敗了</translation> - </message> - <message> - <source>Failed to write undo data</source> - <translation>把回復資料寫進去失敗了</translation> - </message> - <message> - <source>Force safe mode (default: 0)</source> - <translation>強制進入安全模式 (預設值: 0)</translation> - </message> - <message> - <source>Generate coins (default: 0)</source> - <translation>生產位元幣(預設值: 0)</translation> - </message> - <message> - <source>How many blocks to check at startup (default: 288, 0 = all)</source> - <translation>啓動時檢查的區塊數(預設值: 288, 指定 0 表示全部)</translation> - </message> - <message> <source>If <category> is not supplied, output all debugging information.</source> <translation>如果沒有提供 <category> 就會輸出所有的除錯資訊。</translation> </message> @@ -3020,8 +2936,8 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>檔案描述元不足。</translation> </message> <message> - <source>Prepend debug output with timestamp (default: 1)</source> - <translation>在除錯輸出內容前附加時間(預設值: 1)</translation> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>只有連接到網絡節點 <net> (IPv4,IPv6或onion)</translation> </message> <message> <source>Rebuild block chain index from current blk000??.dat files</source> @@ -3036,22 +2952,10 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>設定區塊大小上限成多少位元組(預設值: %d)</translation> </message> <message> - <source>Set the number of threads to service RPC calls (default: 4)</source> - <translation>設定處理 RPC 服務請求的執行緒數目(預設值: 4)</translation> - </message> - <message> <source>Specify wallet file (within data directory)</source> <translation>指定錢包檔(會在資料目錄中)</translation> </message> <message> - <source>Spend unconfirmed change when sending transactions (default: 1)</source> - <translation>傳送交易時可以花還沒確認的零錢(預設值: 1)</translation> - </message> - <message> - <source>Stop running after importing blocks from disk (default: 0)</source> - <translation>從磁碟匯入區塊資料後停止執行(預設值: 0)</translation> - </message> - <message> <source>This is intended for regression testing tools and app development.</source> <translation>這是設計用來給回歸測試工具和應用程式開發用的。</translation> </message> @@ -3080,10 +2984,6 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>從其它來源的 blk000??.dat 檔匯入區塊</translation> </message> <message> - <source>(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> - <translation>(預設值: 1。1 表示保留交易描述資料,像是帳戶使用者和付款請求資訊;2 表示丟掉交易描述資料)</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>允許指定的來源建立 JSON-RPC 連線。<ip> 的有效值可以是一個單獨位址(像是 1.2.3.4),一個網段/網段罩遮值(像是 1.2.3.4/255.255.255.0),或是網段/CIDR值(像是 1.2.3.4/24)。這個選項可以設定多次。</translation> </message> @@ -3104,12 +3004,12 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>沒辦法鎖定資料目錄 %s。位元幣核心可能已經在執行了。</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> + <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source> + <translation>對沒付手續費的交易持續限制每分鐘內最多只能有 <n>*1000 個位元組(預設值: %u)</translation> </message> <message> - <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> - <translation>這套軟體是依據 MIT/X11 軟體授權條款散布,詳情請見附帶的 COPYING 檔案,或是以下網站: <http://www.opensource.org/licenses/mit-license.php>.</translation> + <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>Error: Listening for incoming connections failed (listen returned error %s)</source> @@ -3120,10 +3020,6 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>錯誤: 找到不再支援的 -socks 參數。現在只支援 SOCKS5 協定的代理伺服器了,因為不再能夠指定 SOCKS 協定版本。</translation> </message> <message> - <source>Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)</source> - <translation>當發現網路上有重複花用錢包裡的交易輸入時所要執行的指令(指令中的 %s 會被取代為重複花用的交易代碼,%t 會被取代為錢包中的交易代碼)</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>當收到相關警示,或發現相當長的分支時,所要執行的指令(指令中的 %s 會被取代成警示訊息)</translation> </message> @@ -3136,12 +3032,8 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>當製造交易時,如果每千位元組(Kb)的手續費比這個值低,就視為沒付手續費 (預設值: %s)</translation> </message> <message> - <source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: 1)</source> - <translation>當沒有設定 paytxfee 時,自動包含可以讓交易能在平均 n 個區塊內確認的手續費 (預設值: 1)</translation> - </message> - <message> - <source>Output debugging information (default: 0, supplying <category> is optional)</source> - <translation>輸出除錯資訊(預設值: 0, 可以不指定 <category>)</translation> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>轉發和開採時,對只帶資料的交易的大小上限(預設值: %u)</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> @@ -3152,6 +3044,10 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>設定高優先度或低手續費的交易資料大小上限成多少位元組(預設值: %d)</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>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> @@ -3160,18 +3056,10 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>警告: 請檢查電腦日期和時間是否正確!位元幣核心沒辦法在時鐘不準的情況下正常運作。</translation> </message> <message> - <source>Whitelist peers connecting from the given netmask or ip. Can be specified multiple times.</source> - <translation>把來自指定網域或位址的節點放進白名單。這個選項可以設定多次。</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>在白名單中的節點不會因為偵測到阻斷服務攻擊而被停用。來自這些節點的交易也一定會被轉發,即使說交易本來就在記憶池裡了也一樣。適用於像是閘道伺服器。</translation> </message> <message> - <source>Always query for peer addresses via DNS lookup (default: 0)</source> - <translation>是否一定要用域名查詢來搜尋節點 (預設值: 0)</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>沒辦法解析 -whitebind 指定的位址: '%s'</translation> </message> @@ -3200,10 +3088,6 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>交易付款時每千位元組(kB)的交易手續費 (預設值: %s)</translation> </message> <message> - <source>Include IP addresses in debug output (default: 0)</source> - <translation>在除錯輸出內容中包含網際網路位址(預設值: 0)</translation> - </message> - <message> <source>Information</source> <translation>資訊</translation> </message> @@ -3232,24 +3116,8 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>在記憶體中保存最多 <n> 個不和其他區塊相連結的區塊(預設值 : %u)</translation> </message> <message> - <source>Limit size of signature cache to <n> entries (default: 50000)</source> - <translation>限制簽章快取大小為 <n> 筆 (預設值: 50000)</translation> - </message> - <message> - <source>Log transaction priority and fee per kB when mining blocks (default: 0)</source> - <translation>開採區塊的時候紀錄交易的優先度以及每千位元組(kB)的手續費 (預設值: 0)</translation> - </message> - <message> - <source>Maintain a full transaction index (default: 0)</source> - <translation>維護全部交易的索引(預設值: 0)</translation> - </message> - <message> - <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)</source> - <translation>每個連線的接收緩衝區大小上限為 <n>*1000 個位元組(預設值: 5000)</translation> - </message> - <message> - <source>Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)</source> - <translation>每個連線的傳送緩衝區大小上限為 <n>*1000 位元組(預設值: 1000)</translation> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>保持最多 <n> 無法連結的交易在記憶體 (預設: %u)</translation> </message> <message> <source>Need to specify a port with -whitebind: '%s'</source> @@ -3260,22 +3128,10 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>節點轉發選項:</translation> </message> <message> - <source>Only accept block chain matching built-in checkpoints (default: 1)</source> - <translation>只接受跟內建的檢查段點吻合的區塊鏈(預設值: 1)</translation> - </message> - <message> - <source>Only connect to nodes in network <net> (IPv4, IPv6 or Tor)</source> - <translation>只和 <net> 網路上的節點連線(IPv4, IPv6, 或 Tor)</translation> - </message> - <message> <source>Print block on startup, if found in block index</source> <translation>啟動時輸出指定的區塊內容,如果有在區塊索引中找到的話</translation> </message> <message> - <source>Print block tree on startup (default: 0)</source> - <translation>啟動時輸出區塊樹 (預設值: 0)</translation> - </message> - <message> <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> <translation>RPC SSL 選項: (SSL 設定程序請見 Bitcoin Wiki)</translation> </message> @@ -3292,28 +3148,12 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>隨機亂動 <n> 分之一的網路訊息裡的資料</translation> </message> <message> - <source>Relay and mine data carrier transactions (default: 1)</source> - <translation>允許轉發和開採只帶資料的交易 (預設值: 1)</translation> - </message> - <message> - <source>Relay non-P2SH multisig (default: 1)</source> - <translation>允許轉發非 P2SH 的多簽章交易 (預設值: 1)</translation> - </message> - <message> - <source>Run a thread to flush wallet periodically (default: 1)</source> - <translation>啟用定期將變動寫入錢包檔的執行緒 (預設值: 1)</translation> - </message> - <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>在終端機顯示追蹤或除錯資訊,而不是寫到檔案 debug.log 中</translation> </message> <message> - <source>Set minimum block size in bytes (default: 0)</source> - <translation>設定區塊大小下限成多少位元組(預設值: 0)</translation> - </message> - <message> - <source>Sets the DB_PRIVATE flag in the wallet db environment (default: 1)</source> - <translation>在錢包資料庫環境變數設定 DB_PRIVATE 旗標 (預設值: 1)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>盡可能送出不用付手續費的交易(預設值: %u)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> @@ -3328,14 +3168,6 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>簽署交易失敗</translation> </message> <message> - <source>Specify connection timeout in milliseconds (default: 5000)</source> - <translation>指定連線在幾毫秒後逾時(預設值: 5000)</translation> - </message> - <message> - <source>System error: </source> - <translation>系統錯誤:</translation> - </message> - <message> <source>This is experimental software.</source> <translation>這套軟體屬於實驗性質。</translation> </message> @@ -3356,10 +3188,6 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>無法和這台電腦上的 %s 繫結(回傳錯誤 %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 0)</source> - <translation>是否要使用「通用即插即用」協定(UPnP),來設定聽候連線的通訊埠的對應(預設值: 0)</translation> - </message> - <message> <source>Use UPnP to map the listening port (default: 1 when listening)</source> <translation>是否要使用「通用即插即用」協定(UPnP),來設定聽候連線的通訊埠的對應(預設值: 當有聽候連線時為 1)</translation> </message> @@ -3412,10 +3240,6 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>把錢包檔案升級成最新的格式</translation> </message> <message> - <source>Set key pool size to <n> (default: 100)</source> - <translation>設定密鑰池大小成 <n> (預設值: 100)</translation> - </message> - <message> <source>Rescan the block chain for missing wallet transactions</source> <translation>重新掃描區塊鏈,來尋找錢包可能漏掉的交易。</translation> </message> @@ -3424,14 +3248,6 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>在 JSON-RPC 連線使用 OpenSSL (https)</translation> </message> <message> - <source>Server certificate file (default: server.cert)</source> - <translation>伺服器憑證檔(預設值: server.cert)</translation> - </message> - <message> - <source>Server private key (default: server.pem)</source> - <translation>伺服器私鑰檔(預設值: server.pem)</translation> - </message> - <message> <source>This help message</source> <translation>這些說明訊息</translation> </message> @@ -3448,14 +3264,178 @@ alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> <translation>載入檔案 wallet.dat 時發生錯誤: 錢包損毀了</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 表示保留交易描述資料,像是帳戶使用者和付款請求資訊;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>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source> + <translation>當沒有設定 paytxfee 時,自動包含可以讓交易能在平均 n 個區塊內確認的手續費(預設值: %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> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>避免與亂搞的節點連線的秒數(預設: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>輸出除錯資訊(預設值: %u, 不一定要指定 <category>)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>使用另外的 SOCK5 代理伺服器,來透過 Tor 隱藏服務跟節點聯繫(預設值: %s)</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(預設值: %s)</translation> + </message> + <message> + <source>Acceptable ciphers (default: %s)</source> + <translation>可以接受的加密演算法(預設值: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <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> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>啓動時檢查的區塊數(預設值: %u, 指定 0 表示全部)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>在除錯輸出內容中包含網際網路位址(預設值: %u)</translation> + </message> + <message> <source>Invalid -proxy address: '%s'</source> <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> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>在通訊埠 <port> 聽候連線(預設值: %u, 或若為測試網路: %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>維持與節點連線數的上限為 <n> 個(預設值: %u)</translation> + </message> + <message> + <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> + <translation>每個連線的接收緩衝區大小上限為 <n>*1000 個位元組(預設值: %u)</translation> + </message> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <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> + <message> + <source>Print block tree on startup (default: %u)</source> + <translation>啟動時輸出區塊樹(預設值: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>允許轉發和開採只帶資料的交易(預設值: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <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> + <message> + <source>Server private key (default: %s)</source> + <translation>伺服器密鑰檔(預設值: %s)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>設定密鑰池大小為 <n> (預設值: %u)</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>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> + <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>指定行程識別碼檔案(預設值: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <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> + <message> <source>Unknown network specified in -onlynet: '%s'</source> <translation>在 -onlynet 指定了不明的網路別: '%s'</translation> </message> diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index b21a61cb07..1217bd8e88 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 MACDOCKICONHANDLER_H -#define MACDOCKICONHANDLER_H +#ifndef BITCOIN_QT_MACDOCKICONHANDLER_H +#define BITCOIN_QT_MACDOCKICONHANDLER_H #include <QMainWindow> #include <QObject> @@ -48,4 +48,4 @@ private: QMainWindow *mainWindow; }; -#endif // MACDOCKICONCLICKHANDLER_H +#endif // BITCOIN_QT_MACDOCKICONHANDLER_H diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index a2ff148d9d..e7b58b9cc0 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "macdockiconhandler.h" diff --git a/src/qt/macnotificationhandler.h b/src/qt/macnotificationhandler.h index bc335edede..bd66b96b21 100644 --- a/src/qt/macnotificationhandler.h +++ b/src/qt/macnotificationhandler.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 MACNOTIFICATIONHANDLER_H -#define MACNOTIFICATIONHANDLER_H +#ifndef BITCOIN_QT_MACNOTIFICATIONHANDLER_H +#define BITCOIN_QT_MACNOTIFICATIONHANDLER_H #include <QObject> @@ -27,4 +27,4 @@ public: }; -#endif // MACNOTIFICATIONHANDLER_H +#endif // BITCOIN_QT_MACNOTIFICATIONHANDLER_H diff --git a/src/qt/macnotificationhandler.mm b/src/qt/macnotificationhandler.mm index 8a4c94cc5c..dd3f622818 100644 --- a/src/qt/macnotificationhandler.mm +++ b/src/qt/macnotificationhandler.mm @@ -1,12 +1,25 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "macnotificationhandler.h" #undef slots +#import <objc/runtime.h> #include <Cocoa/Cocoa.h> +// Add an obj-c category (extension) to return the expected bundle identifier +@implementation NSBundle(returnCorrectIdentifier) +- (NSString *)__bundleIdentifier +{ + if (self == [NSBundle mainBundle]) { + return @"org.bitcoinfoundation.Bitcoin-Qt"; + } else { + return [self __bundleIdentifier]; + } +} +@end + void MacNotificationHandler::showNotification(const QString &title, const QString &text) { // check if users OS has support for NSUserNotification @@ -63,7 +76,16 @@ bool MacNotificationHandler::hasUserNotificationCenterSupport(void) MacNotificationHandler *MacNotificationHandler::instance() { static MacNotificationHandler *s_instance = NULL; - if (!s_instance) + if (!s_instance) { s_instance = new MacNotificationHandler(); + + Class aPossibleClass = objc_getClass("NSBundle"); + if (aPossibleClass) { + // change NSBundle -bundleIdentifier method to return a correct bundle identifier + // a bundle identifier is required to use OSXs User Notification Center + method_exchangeImplementations(class_getInstanceMethod(aPossibleClass, @selector(bundleIdentifier)), + class_getInstanceMethod(aPossibleClass, @selector(__bundleIdentifier))); + } + } return s_instance; } diff --git a/src/qt/monitoreddatamapper.cpp b/src/qt/monitoreddatamapper.cpp deleted file mode 100644 index 5931c53872..0000000000 --- a/src/qt/monitoreddatamapper.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "monitoreddatamapper.h" - -#include <QMetaObject> -#include <QMetaProperty> -#include <QWidget> - -MonitoredDataMapper::MonitoredDataMapper(QObject *parent) : - QDataWidgetMapper(parent) -{ -} - -void MonitoredDataMapper::addMapping(QWidget *widget, int section) -{ - QDataWidgetMapper::addMapping(widget, section); - addChangeMonitor(widget); -} - -void MonitoredDataMapper::addMapping(QWidget *widget, int section, const QByteArray &propertyName) -{ - QDataWidgetMapper::addMapping(widget, section, propertyName); - addChangeMonitor(widget); -} - -void MonitoredDataMapper::addChangeMonitor(QWidget *widget) -{ - // Watch user property of widget for changes, and connect - // the signal to our viewModified signal. - QMetaProperty prop = widget->metaObject()->userProperty(); - int signal = prop.notifySignalIndex(); - int method = this->metaObject()->indexOfMethod("viewModified()"); - if(signal != -1 && method != -1) - { - QMetaObject::connect(widget, signal, this, method); - } -} diff --git a/src/qt/monitoreddatamapper.h b/src/qt/monitoreddatamapper.h deleted file mode 100644 index b3237d3e09..0000000000 --- a/src/qt/monitoreddatamapper.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef MONITOREDDATAMAPPER_H -#define MONITOREDDATAMAPPER_H - -#include <QDataWidgetMapper> - -QT_BEGIN_NAMESPACE -class QWidget; -QT_END_NAMESPACE - -/** Data to Widget mapper that watches for edits and notifies listeners when a field is edited. - This can be used, for example, to enable a commit/apply button in a configuration dialog. - */ -class MonitoredDataMapper : public QDataWidgetMapper -{ - Q_OBJECT - -public: - explicit MonitoredDataMapper(QObject *parent=0); - - void addMapping(QWidget *widget, int section); - void addMapping(QWidget *widget, int section, const QByteArray &propertyName); - -private: - void addChangeMonitor(QWidget *widget); - -signals: - void viewModified(); -}; - -#endif // MONITOREDDATAMAPPER_H diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp new file mode 100644 index 0000000000..e28f903b2e --- /dev/null +++ b/src/qt/networkstyle.cpp @@ -0,0 +1,97 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "networkstyle.h" + +#include "guiconstants.h" +#include "scicon.h" + +#include <QApplication> + +static const struct { + const char *networkId; + const char *appName; + const int iconColorHueShift; + const int iconColorSaturationReduction; + const char *titleAddText; +} network_styles[] = { + {"main", QAPP_APP_NAME_DEFAULT, 0, 0, ""}, + {"test", QAPP_APP_NAME_TESTNET, 70, 30, QT_TRANSLATE_NOOP("SplashScreen", "[testnet]")}, + {"regtest", QAPP_APP_NAME_TESTNET, 160, 30, "[regtest]"} +}; +static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles); + +// titleAddText needs to be const char* for tr() +NetworkStyle::NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText): + appName(appName), + titleAddText(qApp->translate("SplashScreen", titleAddText)) +{ + // load pixmap + QPixmap pixmap(":/icons/bitcoin"); + + if(iconColorHueShift != 0 && iconColorSaturationReduction != 0) + { + // generate QImage from QPixmap + QImage img = pixmap.toImage(); + + int h,s,l,a; + + // traverse though lines + for(int y=0;y<img.height();y++) + { + QRgb *scL = reinterpret_cast< QRgb *>( img.scanLine( y ) ); + + // loop through pixels + for(int x=0;x<img.width();x++) + { + // preserve alpha because QColor::getHsl doesen't return the alpha value + a = qAlpha(scL[x]); + QColor col(scL[x]); + + // get hue value + col.getHsl(&h,&s,&l); + + // rotate color on RGB color circle + // 70° should end up with the typical "testnet" green + h+=iconColorHueShift; + + // change saturation value + if(s>iconColorSaturationReduction) + { + s -= iconColorSaturationReduction; + } + col.setHsl(h,s,l,a); + + // set the pixel + scL[x] = col.rgba(); + } + } + + //convert back to QPixmap +#if QT_VERSION >= 0x040700 + pixmap.convertFromImage(img); +#else + pixmap = QPixmap::fromImage(img); +#endif + } + + appIcon = QIcon(pixmap); + trayAndWindowIcon = QIcon(pixmap.scaled(QSize(256,256))); +} + +const NetworkStyle *NetworkStyle::instantiate(const QString &networkId) +{ + for (unsigned x=0; x<network_styles_count; ++x) + { + if (networkId == network_styles[x].networkId) + { + return new NetworkStyle( + network_styles[x].appName, + network_styles[x].iconColorHueShift, + network_styles[x].iconColorSaturationReduction, + network_styles[x].titleAddText); + } + } + return 0; +} diff --git a/src/qt/networkstyle.h b/src/qt/networkstyle.h new file mode 100644 index 0000000000..b78a9f5948 --- /dev/null +++ b/src/qt/networkstyle.h @@ -0,0 +1,33 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_NETWORKSTYLE_H +#define BITCOIN_QT_NETWORKSTYLE_H + +#include <QIcon> +#include <QPixmap> +#include <QString> + +/* Coin network-specific GUI style information */ +class NetworkStyle +{ +public: + /** Get style associated with provided BIP70 network id, or 0 if not known */ + static const NetworkStyle *instantiate(const QString &networkId); + + const QString &getAppName() const { return appName; } + const QIcon &getAppIcon() const { return appIcon; } + const QIcon &getTrayAndWindowIcon() const { return trayAndWindowIcon; } + const QString &getTitleAddText() const { return titleAddText; } + +private: + NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText); + + QString appName; + QIcon appIcon; + QIcon trayAndWindowIcon; + QString titleAddText; +}; + +#endif // BITCOIN_QT_NETWORKSTYLE_H diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index 3d588cd317..5a564248ec 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "notificator.h" diff --git a/src/qt/notificator.h b/src/qt/notificator.h index 3395e64350..182e948c7d 100644 --- a/src/qt/notificator.h +++ b/src/qt/notificator.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 NOTIFICATOR_H -#define NOTIFICATOR_H +#ifndef BITCOIN_QT_NOTIFICATOR_H +#define BITCOIN_QT_NOTIFICATOR_H #if defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" @@ -77,4 +77,4 @@ private: #endif }; -#endif // NOTIFICATOR_H +#endif // BITCOIN_QT_NOTIFICATOR_H diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp index 06189aeaf3..1c843aecb1 100644 --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "openuridialog.h" diff --git a/src/qt/openuridialog.h b/src/qt/openuridialog.h index 67a5f167d1..d5c434ba9c 100644 --- a/src/qt/openuridialog.h +++ b/src/qt/openuridialog.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 OPENURIDIALOG_H -#define OPENURIDIALOG_H +#ifndef BITCOIN_QT_OPENURIDIALOG_H +#define BITCOIN_QT_OPENURIDIALOG_H #include <QDialog> @@ -31,4 +31,4 @@ private: Ui::OpenURIDialog *ui; }; -#endif // OPENURIDIALOG_H +#endif // BITCOIN_QT_OPENURIDIALOG_H diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 279467129f..a0f3993e69 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #if defined(HAVE_CONFIG_H) @@ -11,7 +11,6 @@ #include "bitcoinunits.h" #include "guiutil.h" -#include "monitoreddatamapper.h" #include "optionsmodel.h" #include "main.h" // for MAX_SCRIPTCHECK_THREADS @@ -24,13 +23,14 @@ #include <boost/thread.hpp> +#include <QDataWidgetMapper> #include <QDir> #include <QIntValidator> #include <QLocale> #include <QMessageBox> #include <QTimer> -OptionsDialog::OptionsDialog(QWidget *parent) : +OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : QDialog(parent), ui(new Ui::OptionsDialog), model(0), @@ -66,6 +66,11 @@ OptionsDialog::OptionsDialog(QWidget *parent) : ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWindow)); #endif + /* remove Wallet tab in case of -disablewallet */ + if (!enableWallet) { + ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWallet)); + } + /* Display elements init */ QDir translations(":translations"); ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant("")); @@ -100,12 +105,9 @@ OptionsDialog::OptionsDialog(QWidget *parent) : #endif ui->unit->setModel(new BitcoinUnits(this)); -#ifdef ENABLE_WALLET - ui->transactionFee->setSingleStep(CWallet::minTxFee.GetFeePerK()); -#endif /* Widget-to-option mapper */ - mapper = new MonitoredDataMapper(this); + mapper = new QDataWidgetMapper(this); mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); mapper->setOrientation(Qt::Vertical); @@ -134,16 +136,11 @@ void OptionsDialog::setModel(OptionsModel *model) strLabel = tr("none"); ui->overriddenByCommandLineLabel->setText(strLabel); - connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); - mapper->setModel(model); setMapper(); mapper->toFirst(); } - /* update the display unit, to not use the default ("BTC") */ - updateDisplayUnit(); - /* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */ /* Main */ @@ -167,7 +164,6 @@ void OptionsDialog::setMapper() mapper->addMapping(ui->databaseCache, OptionsModel::DatabaseCache); /* Wallet */ - mapper->addMapping(ui->transactionFee, OptionsModel::Fee); mapper->addMapping(ui->spendZeroConfChange, OptionsModel::SpendZeroConfChange); mapper->addMapping(ui->coinControlFeatures, OptionsModel::CoinControlFeatures); @@ -259,15 +255,6 @@ void OptionsDialog::clearStatusLabel() ui->statusLabel->clear(); } -void OptionsDialog::updateDisplayUnit() -{ - if(model) - { - /* Update transactionFee with the current unit */ - ui->transactionFee->setDisplayUnit(model->getDisplayUnit()); - } -} - void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort) { Q_UNUSED(nProxyPort); diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index 6b62069660..f4e5157595 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -1,16 +1,19 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 OPTIONSDIALOG_H -#define OPTIONSDIALOG_H +#ifndef BITCOIN_QT_OPTIONSDIALOG_H +#define BITCOIN_QT_OPTIONSDIALOG_H #include <QDialog> -class MonitoredDataMapper; class OptionsModel; class QValidatedLineEdit; +QT_BEGIN_NAMESPACE +class QDataWidgetMapper; +QT_END_NAMESPACE + namespace Ui { class OptionsDialog; } @@ -21,7 +24,7 @@ class OptionsDialog : public QDialog Q_OBJECT public: - explicit OptionsDialog(QWidget *parent); + explicit OptionsDialog(QWidget *parent, bool enableWallet); ~OptionsDialog(); void setModel(OptionsModel *model); @@ -43,7 +46,6 @@ private slots: void showRestartWarning(bool fPersistent = false); void clearStatusLabel(); - void updateDisplayUnit(); void doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort); signals: @@ -52,8 +54,8 @@ signals: private: Ui::OptionsDialog *ui; OptionsModel *model; - MonitoredDataMapper *mapper; + QDataWidgetMapper *mapper; bool fProxyIpValid; }; -#endif // OPTIONSDIALOG_H +#endif // BITCOIN_QT_OPTIONSDIALOG_H diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index bd747faeb6..7d2dbd96de 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #if defined(HAVE_CONFIG_H) @@ -11,6 +11,7 @@ #include "bitcoinunits.h" #include "guiutil.h" +#include "amount.h" #include "init.h" #include "main.h" #include "net.h" @@ -89,12 +90,6 @@ void OptionsModel::Init() // Wallet #ifdef ENABLE_WALLET - if (!settings.contains("nTransactionFee")) - settings.setValue("nTransactionFee", (qint64)DEFAULT_TRANSACTION_FEE); - payTxFee = CFeeRate(settings.value("nTransactionFee").toLongLong()); // if -paytxfee is set, this will be overridden later in init.cpp - if (mapArgs.count("-paytxfee")) - addOverriddenOption("-paytxfee"); - if (!settings.contains("bSpendZeroConfChange")) settings.setValue("bSpendZeroConfChange", true); if (!SoftSetBoolArg("-spendzeroconfchange", settings.value("bSpendZeroConfChange").toBool())) @@ -119,6 +114,8 @@ void OptionsModel::Init() // Only try to set -proxy, if user has enabled fUseProxy if (settings.value("fUseProxy").toBool() && !SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString())) addOverriddenOption("-proxy"); + else if(!settings.value("fUseProxy").toBool() && !GetArg("-proxy", "").empty()) + addOverriddenOption("-proxy"); // Display if (!settings.contains("language")) @@ -182,16 +179,6 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const } #ifdef ENABLE_WALLET - case Fee: { - // Attention: Init() is called before payTxFee is set in AppInit2()! - // To ensure we can change the fee on-the-fly update our QSetting when - // opening OptionsDialog, which queries Fee via the mapper. - if (!(payTxFee == CFeeRate(settings.value("nTransactionFee").toLongLong(), 1000))) - settings.setValue("nTransactionFee", (qint64)payTxFee.GetFeePerK()); - // Todo: Consider to revert back to use just payTxFee here, if we don't want - // -paytxfee to update our QSettings! - return settings.value("nTransactionFee"); - } case SpendZeroConfChange: return settings.value("bSpendZeroConfChange"); #endif @@ -273,14 +260,6 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in } break; #ifdef ENABLE_WALLET - case Fee: { // core option - can be changed on-the-fly - // Todo: Add is valid check and warn via message, if not - qint64 nTransactionFee = value.toLongLong(); - payTxFee = CFeeRate(nTransactionFee, 1000); - settings.setValue("nTransactionFee", nTransactionFee); - emit transactionFeeChanged(nTransactionFee); - break; - } case SpendZeroConfChange: if (settings.value("bSpendZeroConfChange") != value) { settings.setValue("bSpendZeroConfChange", value); diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 80adab89c8..bf892768ed 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -1,9 +1,11 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 OPTIONSMODEL_H -#define OPTIONSMODEL_H +#ifndef BITCOIN_QT_OPTIONSMODEL_H +#define BITCOIN_QT_OPTIONSMODEL_H + +#include "amount.h" #include <QAbstractListModel> @@ -32,7 +34,6 @@ public: ProxyUse, // bool ProxyIP, // QString ProxyPort, // int - Fee, // qint64 DisplayUnit, // BitcoinUnits::Unit ThirdPartyTxUrls, // QString Language, // QString @@ -82,8 +83,7 @@ private: signals: void displayUnitChanged(int unit); - void transactionFeeChanged(qint64); void coinControlFeaturesChanged(bool); }; -#endif // OPTIONSMODEL_H +#endif // BITCOIN_QT_OPTIONSMODEL_H diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 90762bea5d..4fa15db9c6 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "overviewpage.h" @@ -10,6 +10,7 @@ #include "guiconstants.h" #include "guiutil.h" #include "optionsmodel.h" +#include "scicon.h" #include "transactionfilterproxy.h" #include "transactiontablemodel.h" #include "walletmodel.h" @@ -34,7 +35,7 @@ public: { painter->save(); - QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole)); + QIcon icon = qvariant_cast<QIcon>(index.data(TransactionTableModel::RawDecorationRole)); QRect mainRect = option.rect; QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE)); int xspace = DECORATION_SIZE + 8; @@ -42,6 +43,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.paint(painter, decorationRect); QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime(); @@ -146,7 +148,7 @@ OverviewPage::~OverviewPage() delete ui; } -void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance, qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance) +void OverviewPage::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance) { int unit = walletModel->getOptionsModel()->getDisplayUnit(); currentBalance = balance; @@ -220,7 +222,7 @@ void OverviewPage::setWalletModel(WalletModel *model) // Keep up to date with wallet setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance()); - connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64, qint64, qint64, qint64))); + connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount))); connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index f46374efba..64cb1dc4e0 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -1,9 +1,11 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 OVERVIEWPAGE_H -#define OVERVIEWPAGE_H +#ifndef BITCOIN_QT_OVERVIEWPAGE_H +#define BITCOIN_QT_OVERVIEWPAGE_H + +#include "amount.h" #include <QWidget> @@ -34,8 +36,8 @@ public: void showOutOfSyncWarning(bool fShow); public slots: - void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance, - qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance); + void setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, + const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance); signals: void transactionClicked(const QModelIndex &index); @@ -44,12 +46,12 @@ private: Ui::OverviewPage *ui; ClientModel *clientModel; WalletModel *walletModel; - qint64 currentBalance; - qint64 currentUnconfirmedBalance; - qint64 currentImmatureBalance; - qint64 currentWatchOnlyBalance; - qint64 currentWatchUnconfBalance; - qint64 currentWatchImmatureBalance; + CAmount currentBalance; + CAmount currentUnconfirmedBalance; + CAmount currentImmatureBalance; + CAmount currentWatchOnlyBalance; + CAmount currentWatchUnconfBalance; + CAmount currentWatchImmatureBalance; TxViewDelegate *txdelegate; TransactionFilterProxy *filter; @@ -61,4 +63,4 @@ private slots: void updateWatchOnlyLabels(bool showWatchOnly); }; -#endif // OVERVIEWPAGE_H +#endif // BITCOIN_QT_OVERVIEWPAGE_H diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 7b7de49831..35846bc153 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. // @@ -181,8 +181,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c } // TODO: detect EV certificates and set merchant = business name instead of unfriendly NID_commonName ? } - catch (SSLVerifyError& err) - { + catch (const SSLVerifyError& err) { fResult = false; qWarning() << "PaymentRequestPlus::getMerchant : SSL error: " << err.what(); } @@ -196,9 +195,9 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c return fResult; } -QList<std::pair<CScript,qint64> > PaymentRequestPlus::getPayTo() const +QList<std::pair<CScript,CAmount> > PaymentRequestPlus::getPayTo() const { - QList<std::pair<CScript,qint64> > result; + QList<std::pair<CScript,CAmount> > result; for (int i = 0; i < details.outputs_size(); i++) { const unsigned char* scriptStr = (const unsigned char*)details.outputs(i).script().data(); diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h index 3c4861a4d4..fbc3a09265 100644 --- a/src/qt/paymentrequestplus.h +++ b/src/qt/paymentrequestplus.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2011-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 PAYMENTREQUESTPLUS_H -#define PAYMENTREQUESTPLUS_H +#ifndef BITCOIN_QT_PAYMENTREQUESTPLUS_H +#define BITCOIN_QT_PAYMENTREQUESTPLUS_H #include "paymentrequest.pb.h" @@ -33,7 +33,7 @@ public: bool getMerchant(X509_STORE* certStore, QString& merchant) const; // Returns list of outputs, amount - QList<std::pair<CScript,qint64> > getPayTo() const; + QList<std::pair<CScript,CAmount> > getPayTo() const; const payments::PaymentDetails& getDetails() const { return details; } @@ -42,5 +42,4 @@ private: payments::PaymentDetails details; }; -#endif // PAYMENTREQUESTPLUS_H - +#endif // BITCOIN_QT_PAYMENTREQUESTPLUS_H diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index cc4478f39f..3f8e89535e 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -1,11 +1,10 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "paymentserver.h" #include "bitcoinunits.h" -#include "guiconstants.h" #include "guiutil.h" #include "optionsmodel.h" @@ -19,6 +18,7 @@ #include <openssl/x509.h> #include <openssl/x509_vfy.h> + #include <QApplication> #include <QByteArray> #include <QDataStream> @@ -46,14 +46,20 @@ #include <QUrlQuery> #endif -using namespace std; using namespace boost; +using namespace std; const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds const QString BITCOIN_IPC_PREFIX("bitcoin:"); -const char* BITCOIN_REQUEST_MIMETYPE = "application/bitcoin-paymentrequest"; -const char* BITCOIN_PAYMENTACK_MIMETYPE = "application/bitcoin-paymentack"; -const char* BITCOIN_PAYMENTACK_CONTENTTYPE = "application/bitcoin-payment"; +// BIP70 payment protocol messages +const char* BIP70_MESSAGE_PAYMENTACK = "PaymentACK"; +const char* BIP70_MESSAGE_PAYMENTREQUEST = "PaymentRequest"; +// BIP71 payment protocol media types +const char* BIP71_MIMETYPE_PAYMENT = "application/bitcoin-payment"; +const char* BIP71_MIMETYPE_PAYMENTACK = "application/bitcoin-paymentack"; +const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/bitcoin-paymentrequest"; +// BIP70 max payment request size in bytes (DoS protection) +const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000; X509_STORE* PaymentServer::certStore = NULL; void PaymentServer::freeCertStore() @@ -184,7 +190,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) // Warning: ipcSendCommandLine() is called early in init, // so don't use "emit message()", but "QMessageBox::"! // -bool PaymentServer::ipcParseCommandLine(int argc, char* argv[]) +void PaymentServer::ipcParseCommandLine(int argc, char* argv[]) { for (int i = 1; i < argc; i++) { @@ -192,6 +198,10 @@ bool PaymentServer::ipcParseCommandLine(int argc, char* argv[]) if (arg.startsWith("-")) continue; + // If the bitcoin: URI contains a payment request, we are not able to detect the + // network as that would require fetching and parsing the payment request. + // That means clicking such an URI which contains a testnet payment request + // will start a mainnet instance and throw a "wrong network" error. if (arg.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: URI { savedPaymentRequests.append(arg); @@ -216,7 +226,7 @@ bool PaymentServer::ipcParseCommandLine(int argc, char* argv[]) savedPaymentRequests.append(arg); PaymentRequestPlus request; - if (readPaymentRequest(arg, request)) + if (readPaymentRequestFromFile(arg, request)) { if (request.getDetails().network() == "main") { @@ -235,7 +245,6 @@ bool PaymentServer::ipcParseCommandLine(int argc, char* argv[]) qWarning() << "PaymentServer::ipcSendCommandLine : Payment request file does not exist: " << arg; } } - return true; } // @@ -254,6 +263,7 @@ bool PaymentServer::ipcSendCommandLine() if (!socket->waitForConnected(BITCOIN_IPC_CONNECT_TIMEOUT)) { delete socket; + socket = NULL; return false; } @@ -262,12 +272,14 @@ bool PaymentServer::ipcSendCommandLine() out.setVersion(QDataStream::Qt_4_0); out << r; out.device()->seek(0); + socket->write(block); socket->flush(); - socket->waitForBytesWritten(BITCOIN_IPC_CONNECT_TIMEOUT); socket->disconnectFromServer(); + delete socket; + socket = NULL; fResult = true; } @@ -440,7 +452,7 @@ void PaymentServer::handleURIOrFile(const QString& s) { PaymentRequestPlus request; SendCoinsRecipient recipient; - if (!readPaymentRequest(s, request)) + if (!readPaymentRequestFromFile(s, request)) { emit message(tr("Payment request file handling"), tr("Payment request file cannot be read! This can be caused by an invalid payment request file."), @@ -474,18 +486,25 @@ void PaymentServer::handleURIConnection() handleURIOrFile(msg); } -bool PaymentServer::readPaymentRequest(const QString& filename, PaymentRequestPlus& request) +// +// Warning: readPaymentRequestFromFile() is used in ipcSendCommandLine() +// so don't use "emit message()", but "QMessageBox::"! +// +bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request) { QFile f(filename); - if (!f.open(QIODevice::ReadOnly)) - { - qWarning() << "PaymentServer::readPaymentRequest : Failed to open " << filename; + if (!f.open(QIODevice::ReadOnly)) { + qWarning() << QString("PaymentServer::%1: Failed to open %2").arg(__func__).arg(filename); return false; } - if (f.size() > MAX_PAYMENT_REQUEST_SIZE) - { - qWarning() << "PaymentServer::readPaymentRequest : " << filename << " too large"; + // 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); return false; } @@ -532,10 +551,10 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins request.getMerchant(PaymentServer::certStore, recipient.authenticatedMerchant); - QList<std::pair<CScript, qint64> > sendingTos = request.getPayTo(); + QList<std::pair<CScript, CAmount> > sendingTos = request.getPayTo(); QStringList addresses; - foreach(const PAIRTYPE(CScript, qint64)& sendingTo, sendingTos) { + foreach(const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { // Extract and check destination addresses CTxDestination dest; if (ExtractDestination(sendingTo.first, dest)) { @@ -580,10 +599,10 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins void PaymentServer::fetchRequest(const QUrl& url) { QNetworkRequest netRequest; - netRequest.setAttribute(QNetworkRequest::User, "PaymentRequest"); + netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTREQUEST); netRequest.setUrl(url); netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str()); - netRequest.setRawHeader("Accept", BITCOIN_REQUEST_MIMETYPE); + netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTREQUEST); netManager->get(netRequest); } @@ -594,11 +613,11 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien return; QNetworkRequest netRequest; - netRequest.setAttribute(QNetworkRequest::User, "PaymentACK"); + netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTACK); netRequest.setUrl(QString::fromStdString(details.payment_url())); - netRequest.setHeader(QNetworkRequest::ContentTypeHeader, BITCOIN_PAYMENTACK_CONTENTTYPE); + netRequest.setHeader(QNetworkRequest::ContentTypeHeader, BIP71_MIMETYPE_PAYMENT); netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str()); - netRequest.setRawHeader("Accept", BITCOIN_PAYMENTACK_MIMETYPE); + netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTACK); payments::Payment payment; payment.set_merchant_data(details.merchant_data()); @@ -616,7 +635,6 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien else { CPubKey newKey; if (wallet->GetKeyFromPool(newKey)) { - LOCK(wallet->cs_wallet); // SetAddressBook CKeyID keyID = newKey.GetID(); wallet->SetAddressBook(keyID, strAccount, "refund"); @@ -646,13 +664,26 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien void PaymentServer::netRequestFinished(QNetworkReply* reply) { reply->deleteLater(); - if (reply->error() != QNetworkReply::NoError) - { + + // BIP70 DoS protection + if (reply->size() > BIP70_MAX_PAYMENTREQUEST_SIZE) { + QString msg = tr("Payment request %2 is too large (%3 bytes, allowed %4 bytes).") + .arg(__func__) + .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); + return; + } + + if (reply->error() != QNetworkReply::NoError) { QString msg = tr("Error communicating with %1: %2") .arg(reply->request().url().toString()) .arg(reply->errorString()); - qWarning() << "PaymentServer::netRequestFinished : " << msg; + qWarning() << "PaymentServer::netRequestFinished: " << msg; emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); return; } @@ -660,7 +691,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) QByteArray data = reply->readAll(); QString requestType = reply->request().attribute(QNetworkRequest::User).toString(); - if (requestType == "PaymentRequest") + if (requestType == BIP70_MESSAGE_PAYMENTREQUEST) { PaymentRequestPlus request; SendCoinsRecipient recipient; @@ -676,7 +707,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) return; } - else if (requestType == "PaymentACK") + else if (requestType == BIP70_MESSAGE_PAYMENTACK) { payments::PaymentACK paymentACK; if (!paymentACK.ParseFromArray(data.data(), data.size())) diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index d84d09c57d..2fc24395f6 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -1,9 +1,10 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. -#ifndef PAYMENTSERVER_H -#define PAYMENTSERVER_H +#ifndef BITCOIN_QT_PAYMENTSERVER_H +#define BITCOIN_QT_PAYMENTSERVER_H + // This class handles payment requests from clicking on // bitcoin: URIs // @@ -39,6 +40,8 @@ class OptionsModel; +class CWallet; + QT_BEGIN_NAMESPACE class QApplication; class QByteArray; @@ -49,7 +52,8 @@ class QSslError; class QUrl; QT_END_NAMESPACE -class CWallet; +// BIP70 max payment request size in bytes (DoS protection) +extern const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE; class PaymentServer : public QObject { @@ -58,7 +62,7 @@ class PaymentServer : public QObject public: // Parse URIs on command line // Returns false on error - static bool ipcParseCommandLine(int argc, char *argv[]); + static void ipcParseCommandLine(int argc, char *argv[]); // Returns true if there were URIs on the command line // which were successfully sent to an already-running @@ -84,6 +88,9 @@ 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); + signals: // Fired when a valid payment request is received void receivedPaymentRequest(SendCoinsRecipient); @@ -117,7 +124,6 @@ protected: bool eventFilter(QObject *object, QEvent *event); private: - static bool readPaymentRequest(const QString& filename, PaymentRequestPlus& request); bool processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient); void fetchRequest(const QUrl& url); @@ -135,4 +141,4 @@ private: OptionsModel *optionsModel; }; -#endif // PAYMENTSERVER_H +#endif // BITCOIN_QT_PAYMENTSERVER_H diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index cfa05300cf..dfb7a623af 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "peertablemodel.h" diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h index 38f2662f89..bff7bb824e 100644 --- a/src/qt/peertablemodel.h +++ b/src/qt/peertablemodel.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 PEERTABLEMODEL_H -#define PEERTABLEMODEL_H +#ifndef BITCOIN_QT_PEERTABLEMODEL_H +#define BITCOIN_QT_PEERTABLEMODEL_H #include "main.h" #include "net.h" @@ -78,4 +78,4 @@ private: QTimer *timer; }; -#endif // PEERTABLEMODEL_H +#endif // BITCOIN_QT_PEERTABLEMODEL_H diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp index c2567835c9..346369392c 100644 --- a/src/qt/qvalidatedlineedit.cpp +++ b/src/qt/qvalidatedlineedit.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "qvalidatedlineedit.h" diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h index c2a4817e65..f63568d27f 100644 --- a/src/qt/qvalidatedlineedit.h +++ b/src/qt/qvalidatedlineedit.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 QVALIDATEDLINEEDIT_H -#define QVALIDATEDLINEEDIT_H +#ifndef BITCOIN_QT_QVALIDATEDLINEEDIT_H +#define BITCOIN_QT_QVALIDATEDLINEEDIT_H #include <QLineEdit> @@ -36,4 +36,4 @@ private slots: void checkValidity(); }; -#endif // QVALIDATEDLINEEDIT_H +#endif // BITCOIN_QT_QVALIDATEDLINEEDIT_H diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp index ad083f6357..f73268c958 100644 --- a/src/qt/qvaluecombobox.cpp +++ b/src/qt/qvaluecombobox.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "qvaluecombobox.h" diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h index 5f2182913c..dc85d64cb5 100644 --- a/src/qt/qvaluecombobox.h +++ b/src/qt/qvaluecombobox.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 QVALUECOMBOBOX_H -#define QVALUECOMBOBOX_H +#ifndef BITCOIN_QT_QVALUECOMBOBOX_H +#define BITCOIN_QT_QVALUECOMBOBOX_H #include <QComboBox> #include <QVariant> @@ -34,4 +34,4 @@ private slots: void handleSelectionChanged(int idx); }; -#endif // QVALUECOMBOBOX_H +#endif // BITCOIN_QT_QVALUECOMBOBOX_H diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index f2c76c8355..28cbd3abed 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "receivecoinsdialog.h" @@ -12,6 +12,7 @@ #include "optionsmodel.h" #include "receiverequestdialog.h" #include "recentrequeststablemodel.h" +#include "scicon.h" #include "walletmodel.h" #include <QAction> @@ -33,6 +34,11 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget *parent) : 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 // context menu actions diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index 7a7e38e25e..70a1842fa2 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. -#ifndef RECEIVECOINSDIALOG_H -#define RECEIVECOINSDIALOG_H +#ifndef BITCOIN_QT_RECEIVECOINSDIALOG_H +#define BITCOIN_QT_RECEIVECOINSDIALOG_H #include "guiutil.h" @@ -73,4 +73,4 @@ private slots: void copyAmount(); }; -#endif // RECEIVECOINSDIALOG_H +#endif // BITCOIN_QT_RECEIVECOINSDIALOG_H diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index cc2f00916f..0c4a20cf92 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "receiverequestdialog.h" diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 9b78e495c3..3e5f897be6 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 QRCODEDIALOG_H -#define QRCODEDIALOG_H +#ifndef BITCOIN_QT_RECEIVEREQUESTDIALOG_H +#define BITCOIN_QT_RECEIVEREQUESTDIALOG_H #include "walletmodel.h" @@ -67,4 +67,4 @@ private: SendCoinsRecipient info; }; -#endif // QRCODEDIALOG_H +#endif // BITCOIN_QT_RECEIVEREQUESTDIALOG_H diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 0e5802922c..5221ec3e24 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -1,12 +1,14 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "recentrequeststablemodel.h" #include "bitcoinunits.h" +#include "clientversion.h" #include "guiutil.h" #include "optionsmodel.h" +#include "streams.h" #include <boost/foreach.hpp> diff --git a/src/qt/recentrequeststablemodel.h b/src/qt/recentrequeststablemodel.h index 3df5971823..85bad126db 100644 --- a/src/qt/recentrequeststablemodel.h +++ b/src/qt/recentrequeststablemodel.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. -#ifndef RECENTREQUESTSTABLEMODEL_H -#define RECENTREQUESTSTABLEMODEL_H +#ifndef BITCOIN_QT_RECENTREQUESTSTABLEMODEL_H +#define BITCOIN_QT_RECENTREQUESTSTABLEMODEL_H #include "walletmodel.h" @@ -105,4 +105,4 @@ private: QString getAmountTitle(); }; -#endif +#endif // BITCOIN_QT_RECENTREQUESTSTABLEMODEL_H diff --git a/src/qt/res/bitcoin-qt-res.rc b/src/qt/res/bitcoin-qt-res.rc index 809235be5f..c0f3e2fb39 100644 --- a/src/qt/res/bitcoin-qt-res.rc +++ b/src/qt/res/bitcoin-qt-res.rc @@ -1,5 +1,4 @@ IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico" -IDI_ICON2 ICON DISCARDABLE "icons/bitcoin_testnet.ico" #include <windows.h> // needed for VERSIONINFO #include "../../clientversion.h" // holds the needed client version information @@ -24,7 +23,7 @@ BEGIN VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "bitcoin-qt" VALUE "LegalCopyright", COPYRIGHT_STR - VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." + VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." VALUE "OriginalFilename", "bitcoin-qt.exe" VALUE "ProductName", "Bitcoin Core" VALUE "ProductVersion", VER_PRODUCTVERSION_STR diff --git a/src/qt/res/icons/about.png b/src/qt/res/icons/about.png Binary files differnew file mode 100644 index 0000000000..eeef943355 --- /dev/null +++ b/src/qt/res/icons/about.png diff --git a/src/qt/res/icons/about_qt.png b/src/qt/res/icons/about_qt.png Binary files differnew file mode 100644 index 0000000000..d3665e9892 --- /dev/null +++ b/src/qt/res/icons/about_qt.png diff --git a/src/qt/res/icons/add.png b/src/qt/res/icons/add.png Binary files differindex ea53fc3493..ef995cc0b5 100644 --- a/src/qt/res/icons/add.png +++ b/src/qt/res/icons/add.png diff --git a/src/qt/res/icons/address-book.png b/src/qt/res/icons/address-book.png Binary files differindex 33a2d91754..0c9238c18e 100644 --- a/src/qt/res/icons/address-book.png +++ b/src/qt/res/icons/address-book.png diff --git a/src/qt/res/icons/bitcoin.png b/src/qt/res/icons/bitcoin.png Binary files differindex ce5fbb0c2c..705a20260a 100644 --- a/src/qt/res/icons/bitcoin.png +++ b/src/qt/res/icons/bitcoin.png diff --git a/src/qt/res/icons/bitcoin_testnet.ico b/src/qt/res/icons/bitcoin_testnet.ico Binary files differdeleted file mode 100755 index d67d9d5ce5..0000000000 --- a/src/qt/res/icons/bitcoin_testnet.ico +++ /dev/null diff --git a/src/qt/res/icons/bitcoin_testnet.png b/src/qt/res/icons/bitcoin_testnet.png Binary files differdeleted file mode 100644 index 1202021f53..0000000000 --- a/src/qt/res/icons/bitcoin_testnet.png +++ /dev/null diff --git a/src/qt/res/icons/clock1.png b/src/qt/res/icons/clock1.png Binary files differindex 9f0aa5db29..65adba5e21 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 bad00ccc63..196a79ce4a 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 7314d5302b..3d04655ed9 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 07f5bfab5f..c3210c5af1 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 27e9630eb5..84a9fa2842 100644 --- a/src/qt/res/icons/clock5.png +++ b/src/qt/res/icons/clock5.png diff --git a/src/qt/res/icons/configure.png b/src/qt/res/icons/configure.png Binary files differindex a1bd70aa4e..fe9c6ec5ec 100644 --- a/src/qt/res/icons/configure.png +++ b/src/qt/res/icons/configure.png diff --git a/src/qt/res/icons/connect0.png b/src/qt/res/icons/connect0.png Binary files differnew file mode 100644 index 0000000000..99bb2575d6 --- /dev/null +++ b/src/qt/res/icons/connect0.png diff --git a/src/qt/res/icons/connect0_16.png b/src/qt/res/icons/connect0_16.png Binary files differdeleted file mode 100644 index a397e7e6a7..0000000000 --- a/src/qt/res/icons/connect0_16.png +++ /dev/null diff --git a/src/qt/res/icons/connect1.png b/src/qt/res/icons/connect1.png Binary files differnew file mode 100644 index 0000000000..dffc692c76 --- /dev/null +++ b/src/qt/res/icons/connect1.png diff --git a/src/qt/res/icons/connect1_16.png b/src/qt/res/icons/connect1_16.png Binary files differdeleted file mode 100644 index 199fb44c53..0000000000 --- a/src/qt/res/icons/connect1_16.png +++ /dev/null diff --git a/src/qt/res/icons/connect2.png b/src/qt/res/icons/connect2.png Binary files differnew file mode 100644 index 0000000000..3594fb117c --- /dev/null +++ b/src/qt/res/icons/connect2.png diff --git a/src/qt/res/icons/connect2_16.png b/src/qt/res/icons/connect2_16.png Binary files differdeleted file mode 100644 index 2a85ba50d7..0000000000 --- a/src/qt/res/icons/connect2_16.png +++ /dev/null diff --git a/src/qt/res/icons/connect3.png b/src/qt/res/icons/connect3.png Binary files differnew file mode 100644 index 0000000000..3594fb117c --- /dev/null +++ b/src/qt/res/icons/connect3.png diff --git a/src/qt/res/icons/connect3_16.png b/src/qt/res/icons/connect3_16.png Binary files differdeleted file mode 100644 index d4b35ecc5f..0000000000 --- a/src/qt/res/icons/connect3_16.png +++ /dev/null diff --git a/src/qt/res/icons/connect4.png b/src/qt/res/icons/connect4.png Binary files differnew file mode 100644 index 0000000000..0c667c7e06 --- /dev/null +++ b/src/qt/res/icons/connect4.png diff --git a/src/qt/res/icons/connect4_16.png b/src/qt/res/icons/connect4_16.png Binary files differdeleted file mode 100644 index 0376443b1c..0000000000 --- a/src/qt/res/icons/connect4_16.png +++ /dev/null diff --git a/src/qt/res/icons/debugwindow.png b/src/qt/res/icons/debugwindow.png Binary files differindex 767d0bb9f0..576e57ab03 100644 --- a/src/qt/res/icons/debugwindow.png +++ b/src/qt/res/icons/debugwindow.png diff --git a/src/qt/res/icons/edit.png b/src/qt/res/icons/edit.png Binary files differindex 49e2ee3fc1..4df2229e98 100644 --- a/src/qt/res/icons/edit.png +++ b/src/qt/res/icons/edit.png diff --git a/src/qt/res/icons/editcopy.png b/src/qt/res/icons/editcopy.png Binary files differindex 7807c59a88..db0c51772c 100644 --- a/src/qt/res/icons/editcopy.png +++ b/src/qt/res/icons/editcopy.png diff --git a/src/qt/res/icons/editpaste.png b/src/qt/res/icons/editpaste.png Binary files differindex e217e308ea..be8634674d 100644 --- a/src/qt/res/icons/editpaste.png +++ b/src/qt/res/icons/editpaste.png diff --git a/src/qt/res/icons/export.png b/src/qt/res/icons/export.png Binary files differindex 5c1f519054..18d0596194 100644 --- a/src/qt/res/icons/export.png +++ b/src/qt/res/icons/export.png diff --git a/src/qt/res/icons/eye.png b/src/qt/res/icons/eye.png Binary files differindex c4d182adbf..7036708de5 100644 --- a/src/qt/res/icons/eye.png +++ b/src/qt/res/icons/eye.png diff --git a/src/qt/res/icons/eye_minus.png b/src/qt/res/icons/eye_minus.png Binary files differindex 08b048eae3..bdbe073627 100644 --- a/src/qt/res/icons/eye_minus.png +++ b/src/qt/res/icons/eye_minus.png diff --git a/src/qt/res/icons/eye_plus.png b/src/qt/res/icons/eye_plus.png Binary files differindex 4ad653156f..2ba5e68c76 100644 --- a/src/qt/res/icons/eye_plus.png +++ b/src/qt/res/icons/eye_plus.png diff --git a/src/qt/res/icons/filesave.png b/src/qt/res/icons/filesave.png Binary files differindex 02e78b931a..a53390f594 100644 --- a/src/qt/res/icons/filesave.png +++ b/src/qt/res/icons/filesave.png diff --git a/src/qt/res/icons/history.png b/src/qt/res/icons/history.png Binary files differindex ac955c7291..cb723abc5f 100644 --- a/src/qt/res/icons/history.png +++ b/src/qt/res/icons/history.png diff --git a/src/qt/res/icons/info.png b/src/qt/res/icons/info.png Binary files differnew file mode 100644 index 0000000000..085fa8ea73 --- /dev/null +++ b/src/qt/res/icons/info.png diff --git a/src/qt/res/icons/key.png b/src/qt/res/icons/key.png Binary files differindex 2638b4f231..d21f81364d 100644 --- a/src/qt/res/icons/key.png +++ b/src/qt/res/icons/key.png diff --git a/src/qt/res/icons/lock_closed.png b/src/qt/res/icons/lock_closed.png Binary files differindex 6de207db7d..77914ab2ce 100644 --- a/src/qt/res/icons/lock_closed.png +++ b/src/qt/res/icons/lock_closed.png diff --git a/src/qt/res/icons/lock_open.png b/src/qt/res/icons/lock_open.png Binary files differindex 23ce3243aa..50615b7336 100644 --- a/src/qt/res/icons/lock_open.png +++ b/src/qt/res/icons/lock_open.png diff --git a/src/qt/res/icons/open.png b/src/qt/res/icons/open.png Binary files differnew file mode 100644 index 0000000000..390d3dab64 --- /dev/null +++ b/src/qt/res/icons/open.png diff --git a/src/qt/res/icons/overview.png b/src/qt/res/icons/overview.png Binary files differindex a274f0c488..36e1003c3c 100644 --- a/src/qt/res/icons/overview.png +++ b/src/qt/res/icons/overview.png diff --git a/src/qt/res/icons/qrcode.png b/src/qt/res/icons/qrcode.png Binary files differdeleted file mode 100644 index ee61aff2f0..0000000000 --- a/src/qt/res/icons/qrcode.png +++ /dev/null diff --git a/src/qt/res/icons/quit.png b/src/qt/res/icons/quit.png Binary files differindex bd73baee20..6e44a2d329 100644 --- a/src/qt/res/icons/quit.png +++ b/src/qt/res/icons/quit.png diff --git a/src/qt/res/icons/receive.png b/src/qt/res/icons/receive.png Binary files differindex 8ed337ca1a..a53390f594 100644 --- a/src/qt/res/icons/receive.png +++ b/src/qt/res/icons/receive.png diff --git a/src/qt/res/icons/remove.png b/src/qt/res/icons/remove.png Binary files differindex 224d2c20c3..3849cdd6d8 100644 --- a/src/qt/res/icons/remove.png +++ b/src/qt/res/icons/remove.png diff --git a/src/qt/res/icons/send.png b/src/qt/res/icons/send.png Binary files differindex 43c3d7922c..18d0596194 100644 --- a/src/qt/res/icons/send.png +++ b/src/qt/res/icons/send.png diff --git a/src/qt/res/icons/synced.png b/src/qt/res/icons/synced.png Binary files differindex 9fad384768..d33914f0b4 100644 --- a/src/qt/res/icons/synced.png +++ b/src/qt/res/icons/synced.png diff --git a/src/qt/res/icons/transaction0.png b/src/qt/res/icons/transaction0.png Binary files differindex cfe1a1c8b8..fd41da0680 100644 --- a/src/qt/res/icons/transaction0.png +++ b/src/qt/res/icons/transaction0.png diff --git a/src/qt/res/icons/transaction2.png b/src/qt/res/icons/transaction2.png Binary files differindex 8a804b05ac..d33914f0b4 100644 --- a/src/qt/res/icons/transaction2.png +++ b/src/qt/res/icons/transaction2.png diff --git a/src/qt/res/icons/transaction_conflicted.png b/src/qt/res/icons/transaction_conflicted.png Binary files differindex 51fff649ab..6e44a2d329 100644 --- a/src/qt/res/icons/transaction_conflicted.png +++ b/src/qt/res/icons/transaction_conflicted.png diff --git a/src/qt/res/icons/tx_inout.png b/src/qt/res/icons/tx_inout.png Binary files differindex f1a7f7bbc3..cecd332ad1 100644 --- a/src/qt/res/icons/tx_inout.png +++ b/src/qt/res/icons/tx_inout.png diff --git a/src/qt/res/icons/tx_input.png b/src/qt/res/icons/tx_input.png Binary files differindex a2d324ee34..1b4cfd967c 100644 --- a/src/qt/res/icons/tx_input.png +++ b/src/qt/res/icons/tx_input.png diff --git a/src/qt/res/icons/tx_mined.png b/src/qt/res/icons/tx_mined.png Binary files differindex a7acc6cf7b..421a9cf639 100644 --- a/src/qt/res/icons/tx_mined.png +++ b/src/qt/res/icons/tx_mined.png diff --git a/src/qt/res/icons/tx_output.png b/src/qt/res/icons/tx_output.png Binary files differindex a7c5ebf56b..06d9d0adf2 100644 --- a/src/qt/res/icons/tx_output.png +++ b/src/qt/res/icons/tx_output.png diff --git a/src/qt/res/icons/unit_btc.png b/src/qt/res/icons/unit_btc.png Binary files differindex ec3497435c..f3246fa999 100644 --- a/src/qt/res/icons/unit_btc.png +++ b/src/qt/res/icons/unit_btc.png diff --git a/src/qt/res/icons/unit_mbtc.png b/src/qt/res/icons/unit_mbtc.png Binary files differindex 32bf2f2ca0..4e82b65274 100644 --- a/src/qt/res/icons/unit_mbtc.png +++ b/src/qt/res/icons/unit_mbtc.png diff --git a/src/qt/res/icons/unit_ubtc.png b/src/qt/res/icons/unit_ubtc.png Binary files differindex d5a154882b..96b254770d 100644 --- a/src/qt/res/icons/unit_ubtc.png +++ b/src/qt/res/icons/unit_ubtc.png diff --git a/src/qt/res/icons/verify.png b/src/qt/res/icons/verify.png Binary files differnew file mode 100644 index 0000000000..9ff35c2793 --- /dev/null +++ b/src/qt/res/icons/verify.png diff --git a/src/qt/res/images/splash.png b/src/qt/res/images/splash.png Binary files differdeleted file mode 100644 index 3f2b2fb2bf..0000000000 --- a/src/qt/res/images/splash.png +++ /dev/null diff --git a/src/qt/res/images/splash_testnet.png b/src/qt/res/images/splash_testnet.png Binary files differdeleted file mode 100644 index 786dc9c3bb..0000000000 --- a/src/qt/res/images/splash_testnet.png +++ /dev/null diff --git a/src/qt/res/movies/makespinner.sh b/src/qt/res/movies/makespinner.sh new file mode 100755 index 0000000000..625fb17173 --- /dev/null +++ b/src/qt/res/movies/makespinner.sh @@ -0,0 +1,6 @@ +for i in {1..35} +do + value=$(printf "%03d" $i) + angle=$(($i * 10)) + convert spinner-000.png -background "rgba(0,0,0,0.0)" -distort SRT $angle spinner-$value.png +done diff --git a/src/qt/res/movies/spinner-000.png b/src/qt/res/movies/spinner-000.png Binary files differindex 1f4fb732ef..b296a58481 100644 --- a/src/qt/res/movies/spinner-000.png +++ b/src/qt/res/movies/spinner-000.png diff --git a/src/qt/res/movies/spinner-001.png b/src/qt/res/movies/spinner-001.png Binary files differindex e6ca67a1b0..4f6f9a487b 100644 --- a/src/qt/res/movies/spinner-001.png +++ b/src/qt/res/movies/spinner-001.png diff --git a/src/qt/res/movies/spinner-002.png b/src/qt/res/movies/spinner-002.png Binary files differindex 2360467aff..4f14e3ca93 100644 --- a/src/qt/res/movies/spinner-002.png +++ b/src/qt/res/movies/spinner-002.png diff --git a/src/qt/res/movies/spinner-003.png b/src/qt/res/movies/spinner-003.png Binary files differindex 52bed62566..d7756e73bf 100644 --- a/src/qt/res/movies/spinner-003.png +++ b/src/qt/res/movies/spinner-003.png diff --git a/src/qt/res/movies/spinner-004.png b/src/qt/res/movies/spinner-004.png Binary files differindex de5c88a56f..4b381b81b2 100644 --- a/src/qt/res/movies/spinner-004.png +++ b/src/qt/res/movies/spinner-004.png diff --git a/src/qt/res/movies/spinner-005.png b/src/qt/res/movies/spinner-005.png Binary files differindex 27b30336a1..cbdb5b5797 100644 --- a/src/qt/res/movies/spinner-005.png +++ b/src/qt/res/movies/spinner-005.png diff --git a/src/qt/res/movies/spinner-006.png b/src/qt/res/movies/spinner-006.png Binary files differindex 1fa6b0e242..55d4540c92 100644 --- a/src/qt/res/movies/spinner-006.png +++ b/src/qt/res/movies/spinner-006.png diff --git a/src/qt/res/movies/spinner-007.png b/src/qt/res/movies/spinner-007.png Binary files differindex f54fa8775e..b25f59a445 100644 --- a/src/qt/res/movies/spinner-007.png +++ b/src/qt/res/movies/spinner-007.png diff --git a/src/qt/res/movies/spinner-008.png b/src/qt/res/movies/spinner-008.png Binary files differindex d25aa5300f..6493184a7a 100644 --- a/src/qt/res/movies/spinner-008.png +++ b/src/qt/res/movies/spinner-008.png diff --git a/src/qt/res/movies/spinner-009.png b/src/qt/res/movies/spinner-009.png Binary files differindex 1349b87586..938c49f9d3 100644 --- a/src/qt/res/movies/spinner-009.png +++ b/src/qt/res/movies/spinner-009.png diff --git a/src/qt/res/movies/spinner-010.png b/src/qt/res/movies/spinner-010.png Binary files differindex 6020e275f1..7eb645eda5 100644 --- a/src/qt/res/movies/spinner-010.png +++ b/src/qt/res/movies/spinner-010.png diff --git a/src/qt/res/movies/spinner-011.png b/src/qt/res/movies/spinner-011.png Binary files differindex 0d0e811ea7..fd4b63ca5a 100644 --- a/src/qt/res/movies/spinner-011.png +++ b/src/qt/res/movies/spinner-011.png diff --git a/src/qt/res/movies/spinner-012.png b/src/qt/res/movies/spinner-012.png Binary files differindex 937afb6be2..10d26a3a53 100644 --- a/src/qt/res/movies/spinner-012.png +++ b/src/qt/res/movies/spinner-012.png diff --git a/src/qt/res/movies/spinner-013.png b/src/qt/res/movies/spinner-013.png Binary files differindex 4ae5a671a3..863a9d2908 100644 --- a/src/qt/res/movies/spinner-013.png +++ b/src/qt/res/movies/spinner-013.png diff --git a/src/qt/res/movies/spinner-014.png b/src/qt/res/movies/spinner-014.png Binary files differindex c3a81add0e..d01086cb98 100644 --- a/src/qt/res/movies/spinner-014.png +++ b/src/qt/res/movies/spinner-014.png diff --git a/src/qt/res/movies/spinner-015.png b/src/qt/res/movies/spinner-015.png Binary files differindex 184a9fe424..402dbea693 100644 --- a/src/qt/res/movies/spinner-015.png +++ b/src/qt/res/movies/spinner-015.png diff --git a/src/qt/res/movies/spinner-016.png b/src/qt/res/movies/spinner-016.png Binary files differindex 2da9b9dc72..1db20e6078 100644 --- a/src/qt/res/movies/spinner-016.png +++ b/src/qt/res/movies/spinner-016.png diff --git a/src/qt/res/movies/spinner-017.png b/src/qt/res/movies/spinner-017.png Binary files differindex ada83fbe84..e2c2e2ef78 100644 --- a/src/qt/res/movies/spinner-017.png +++ b/src/qt/res/movies/spinner-017.png diff --git a/src/qt/res/movies/spinner-018.png b/src/qt/res/movies/spinner-018.png Binary files differindex cc436ba8cb..6f1fe73756 100644 --- a/src/qt/res/movies/spinner-018.png +++ b/src/qt/res/movies/spinner-018.png diff --git a/src/qt/res/movies/spinner-019.png b/src/qt/res/movies/spinner-019.png Binary files differindex 03da25bc2a..5f18f65608 100644 --- a/src/qt/res/movies/spinner-019.png +++ b/src/qt/res/movies/spinner-019.png diff --git a/src/qt/res/movies/spinner-020.png b/src/qt/res/movies/spinner-020.png Binary files differindex e7f2ac78e8..c12ae20016 100644 --- a/src/qt/res/movies/spinner-020.png +++ b/src/qt/res/movies/spinner-020.png diff --git a/src/qt/res/movies/spinner-021.png b/src/qt/res/movies/spinner-021.png Binary files differindex dc9e580bf3..d81ceade23 100644 --- a/src/qt/res/movies/spinner-021.png +++ b/src/qt/res/movies/spinner-021.png diff --git a/src/qt/res/movies/spinner-022.png b/src/qt/res/movies/spinner-022.png Binary files differindex 6e236c805e..69c6657942 100644 --- a/src/qt/res/movies/spinner-022.png +++ b/src/qt/res/movies/spinner-022.png diff --git a/src/qt/res/movies/spinner-023.png b/src/qt/res/movies/spinner-023.png Binary files differindex f1c3228485..7bed5bae85 100644 --- a/src/qt/res/movies/spinner-023.png +++ b/src/qt/res/movies/spinner-023.png diff --git a/src/qt/res/movies/spinner-024.png b/src/qt/res/movies/spinner-024.png Binary files differindex d8cf21f178..b3be8d3e8e 100644 --- a/src/qt/res/movies/spinner-024.png +++ b/src/qt/res/movies/spinner-024.png diff --git a/src/qt/res/movies/spinner-025.png b/src/qt/res/movies/spinner-025.png Binary files differindex 2b5ede3293..3a7fa9ab0d 100644 --- a/src/qt/res/movies/spinner-025.png +++ b/src/qt/res/movies/spinner-025.png diff --git a/src/qt/res/movies/spinner-026.png b/src/qt/res/movies/spinner-026.png Binary files differindex 5ee3d2fa8e..dd92fc4fc1 100644 --- a/src/qt/res/movies/spinner-026.png +++ b/src/qt/res/movies/spinner-026.png diff --git a/src/qt/res/movies/spinner-027.png b/src/qt/res/movies/spinner-027.png Binary files differindex c2ee8082bd..9adefee268 100644 --- a/src/qt/res/movies/spinner-027.png +++ b/src/qt/res/movies/spinner-027.png diff --git a/src/qt/res/movies/spinner-028.png b/src/qt/res/movies/spinner-028.png Binary files differindex f70d3531ad..83e7cdd583 100644 --- a/src/qt/res/movies/spinner-028.png +++ b/src/qt/res/movies/spinner-028.png diff --git a/src/qt/res/movies/spinner-029.png b/src/qt/res/movies/spinner-029.png Binary files differindex 02b97207a9..6cbdbb0fe1 100644 --- a/src/qt/res/movies/spinner-029.png +++ b/src/qt/res/movies/spinner-029.png diff --git a/src/qt/res/movies/spinner-030.png b/src/qt/res/movies/spinner-030.png Binary files differindex 0c74e82c6f..e4a09a44bc 100644 --- a/src/qt/res/movies/spinner-030.png +++ b/src/qt/res/movies/spinner-030.png diff --git a/src/qt/res/movies/spinner-031.png b/src/qt/res/movies/spinner-031.png Binary files differindex c5e29bcec7..3c3d505741 100644 --- a/src/qt/res/movies/spinner-031.png +++ b/src/qt/res/movies/spinner-031.png diff --git a/src/qt/res/movies/spinner-032.png b/src/qt/res/movies/spinner-032.png Binary files differindex d72c9bf0dd..7460f80da3 100644 --- a/src/qt/res/movies/spinner-032.png +++ b/src/qt/res/movies/spinner-032.png diff --git a/src/qt/res/movies/spinner-033.png b/src/qt/res/movies/spinner-033.png Binary files differindex a8b822bfaf..d327e8fb08 100644 --- a/src/qt/res/movies/spinner-033.png +++ b/src/qt/res/movies/spinner-033.png diff --git a/src/qt/res/movies/spinner-034.png b/src/qt/res/movies/spinner-034.png Binary files differindex 684aa385e0..d8432751da 100644 --- a/src/qt/res/movies/spinner-034.png +++ b/src/qt/res/movies/spinner-034.png diff --git a/src/qt/res/movies/spinner-035.png b/src/qt/res/movies/spinner-035.png Binary files differnew file mode 100644 index 0000000000..c89c959c94 --- /dev/null +++ b/src/qt/res/movies/spinner-035.png diff --git a/src/qt/res/spinner.png b/src/qt/res/spinner.png Binary files differnew file mode 100644 index 0000000000..b296a58481 --- /dev/null +++ b/src/qt/res/spinner.png diff --git a/src/qt/res/src/clock1.svg b/src/qt/res/src/clock1.svg deleted file mode 100644 index 793dc7f91c..0000000000 --- a/src/qt/res/src/clock1.svg +++ /dev/null @@ -1,261 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<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" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="16px" - height="16px" - id="svg2987" - version="1.1" - inkscape:version="0.48.0 r9654" - sodipodi:docname="clock0.svg"> - <defs - id="defs2989"> - <linearGradient - id="linearGradient4465"> - <stop - id="stop4467" - offset="0" - style="stop-color:#c1c1c1;stop-opacity:1;" /> - <stop - id="stop4469" - offset="1" - style="stop-color:#8c8c8c;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient4424"> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="0" - id="stop4426" /> - <stop - style="stop-color:#b3b3b3;stop-opacity:1;" - offset="1" - id="stop4428" /> - </linearGradient> - <linearGradient - id="linearGradient4357"> - <stop - id="stop4359" - offset="0" - style="stop-color:#ffffff;stop-opacity:1;" /> - <stop - style="stop-color:#ff84a6;stop-opacity:0.49803922;" - offset="0.36363637" - id="stop4473" /> - <stop - id="stop4361" - offset="1" - style="stop-color:#ff0a4d;stop-opacity:0;" /> - </linearGradient> - <linearGradient - id="linearGradient4347"> - <stop - id="stop4349" - offset="0" - style="stop-color:#909090;stop-opacity:1;" /> - <stop - id="stop4351" - offset="1" - style="stop-color:#3c3c3c;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient3767"> - <stop - style="stop-color:#ff8282;stop-opacity:1;" - offset="0" - id="stop3769" /> - <stop - style="stop-color:#ff1919;stop-opacity:1;" - offset="1" - id="stop3771" /> - </linearGradient> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4347" - id="linearGradient3779" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" - gradientUnits="userSpaceOnUse" /> - <filter - inkscape:collect="always" - id="filter4339"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="0.3240906" - id="feGaussianBlur4341" /> - </filter> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3767" - id="linearGradient4345" - gradientUnits="userSpaceOnUse" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4424" - id="linearGradient4430" - x1="10.740074" - y1="16.148634" - x2="6.3055735" - y2="-1.2798394" - gradientUnits="userSpaceOnUse" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient4357" - id="radialGradient4440" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)" - cx="8.1975746" - cy="-0.080271922" - fx="8.1975746" - fy="-0.080271922" - r="7.7781744" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4465" - id="linearGradient4471" - gradientUnits="userSpaceOnUse" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" /> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="1" - inkscape:cx="0.31530906" - inkscape:cy="12.478576" - inkscape:current-layer="layer4" - showgrid="true" - inkscape:grid-bbox="true" - inkscape:document-units="px" - inkscape:window-width="1920" - inkscape:window-height="1127" - inkscape:window-x="0" - inkscape:window-y="25" - inkscape:window-maximized="1" - showguides="true" - inkscape:guide-bbox="true" /> - <metadata - id="metadata2992"> - <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 - inkscape:groupmode="layer" - id="layer4" - inkscape:label="Shadow" - style="display:inline"> - <path - sodipodi:type="arc" - style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)" - id="path2997" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.7781744" - sodipodi:ry="7.7781744" - d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" - transform="translate(0,-0.08838835)" /> - </g> - <g - id="layer1" - inkscape:label="Clock" - inkscape:groupmode="layer" - style="display:inline" - sodipodi:insensitive="true"> - <path - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" - d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" - sodipodi:ry="7.7781744" - sodipodi:rx="7.7781744" - sodipodi:cy="8.1334372" - sodipodi:cx="8.0433397" - id="path4343" - style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none" - sodipodi:type="arc" /> - </g> - <g - inkscape:groupmode="layer" - id="layer5" - inkscape:label="Block" - sodipodi:insensitive="true" - style="display:inline"> - <path - sodipodi:type="arc" - style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline" - id="path4462" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.7781744" - sodipodi:ry="7.7781744" - d="M 14.4287,3.6919089 A 7.7781744,7.7781744 0 1 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z" - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" - sodipodi:start="5.675432" - sodipodi:end="10.999096" /> - </g> - <g - inkscape:groupmode="layer" - id="layer2" - inkscape:label="Ticks" - style="display:inline" - sodipodi:insensitive="true"> - <path - id="use4309" - transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)" - style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none" - d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="m 7.875,2.8017767 0,5.25" - id="path4436" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 7.7781746,7.4629419 10.783378,7.6397186" - id="path4438" - inkscape:connector-curvature="0" /> - </g> - <g - inkscape:groupmode="layer" - id="layer3" - inkscape:label="Shine" - style="display:inline" - sodipodi:insensitive="true"> - <path - sodipodi:type="arc" - style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none" - id="path4353" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.3686199" - sodipodi:ry="7.4368792" - d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z" - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" /> - </g> -</svg> diff --git a/src/qt/res/src/clock2.svg b/src/qt/res/src/clock2.svg deleted file mode 100644 index 6a78adf700..0000000000 --- a/src/qt/res/src/clock2.svg +++ /dev/null @@ -1,262 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<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" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="16px" - height="16px" - id="svg2987" - version="1.1" - inkscape:version="0.48.0 r9654" - sodipodi:docname="clock0.svg"> - <defs - id="defs2989"> - <linearGradient - id="linearGradient4465"> - <stop - id="stop4467" - offset="0" - style="stop-color:#c1c1c1;stop-opacity:1;" /> - <stop - id="stop4469" - offset="1" - style="stop-color:#8c8c8c;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient4424"> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="0" - id="stop4426" /> - <stop - style="stop-color:#b3b3b3;stop-opacity:1;" - offset="1" - id="stop4428" /> - </linearGradient> - <linearGradient - id="linearGradient4357"> - <stop - id="stop4359" - offset="0" - style="stop-color:#ffffff;stop-opacity:1;" /> - <stop - style="stop-color:#ff848d;stop-opacity:0.49803922;" - offset="0.36363637" - id="stop4473" /> - <stop - id="stop4361" - offset="1" - style="stop-color:#ff0a1b;stop-opacity:0;" /> - </linearGradient> - <linearGradient - id="linearGradient4347"> - <stop - id="stop4349" - offset="0" - style="stop-color:#909090;stop-opacity:1;" /> - <stop - id="stop4351" - offset="1" - style="stop-color:#3c3c3c;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient3767"> - <stop - style="stop-color:#ffae82;stop-opacity:1;" - offset="0" - id="stop3769" /> - <stop - style="stop-color:#ff6a19;stop-opacity:1;" - offset="1" - id="stop3771" /> - </linearGradient> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4347" - id="linearGradient3779" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" - gradientUnits="userSpaceOnUse" /> - <filter - inkscape:collect="always" - id="filter4339"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="0.3240906" - id="feGaussianBlur4341" /> - </filter> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3767" - id="linearGradient4345" - gradientUnits="userSpaceOnUse" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4424" - id="linearGradient4430" - x1="10.740074" - y1="16.148634" - x2="6.3055735" - y2="-1.2798394" - gradientUnits="userSpaceOnUse" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient4357" - id="radialGradient4440" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)" - cx="8.1975746" - cy="-0.080271922" - fx="8.1975746" - fy="-0.080271922" - r="7.7781744" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4465" - id="linearGradient4471" - gradientUnits="userSpaceOnUse" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" /> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="1" - inkscape:cx="10.569917" - inkscape:cy="10.828475" - inkscape:current-layer="layer5" - showgrid="true" - inkscape:grid-bbox="true" - inkscape:document-units="px" - inkscape:window-width="1920" - inkscape:window-height="1127" - inkscape:window-x="0" - inkscape:window-y="25" - inkscape:window-maximized="1" - showguides="true" - inkscape:guide-bbox="true" /> - <metadata - id="metadata2992"> - <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 - inkscape:groupmode="layer" - id="layer4" - inkscape:label="Shadow" - style="display:inline" - sodipodi:insensitive="true"> - <path - sodipodi:type="arc" - style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)" - id="path2997" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.7781744" - sodipodi:ry="7.7781744" - d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" - transform="translate(0,-0.08838835)" /> - </g> - <g - id="layer1" - inkscape:label="Clock" - inkscape:groupmode="layer" - style="display:inline" - sodipodi:insensitive="true"> - <path - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" - d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" - sodipodi:ry="7.7781744" - sodipodi:rx="7.7781744" - sodipodi:cy="8.1334372" - sodipodi:cx="8.0433397" - id="path4343" - style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none" - sodipodi:type="arc" /> - </g> - <g - inkscape:groupmode="layer" - id="layer5" - inkscape:label="Block" - style="display:inline" - sodipodi:insensitive="true"> - <path - sodipodi:type="arc" - style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline" - id="path4462" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.7781744" - sodipodi:ry="7.7781744" - d="M 15.197954,11.184912 A 7.7781744,7.7781744 0 1 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z" - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" - sodipodi:start="0.4031442" - sodipodi:end="4.7159107" /> - </g> - <g - inkscape:groupmode="layer" - id="layer2" - inkscape:label="Ticks" - style="display:inline" - sodipodi:insensitive="true"> - <path - id="use4309" - transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)" - style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none" - d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="m 7.875,2.8017767 0,5.25" - id="path4436" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 7.7781746,7.4629419 10.783378,7.6397186" - id="path4438" - inkscape:connector-curvature="0" /> - </g> - <g - inkscape:groupmode="layer" - id="layer3" - inkscape:label="Shine" - style="display:inline" - sodipodi:insensitive="true"> - <path - sodipodi:type="arc" - style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none" - id="path4353" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.3686199" - sodipodi:ry="7.4368792" - d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z" - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" /> - </g> -</svg> diff --git a/src/qt/res/src/clock3.svg b/src/qt/res/src/clock3.svg deleted file mode 100644 index 09ccc2549f..0000000000 --- a/src/qt/res/src/clock3.svg +++ /dev/null @@ -1,261 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<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" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="16px" - height="16px" - id="svg2987" - version="1.1" - inkscape:version="0.48.0 r9654" - sodipodi:docname="clock1.svg"> - <defs - id="defs2989"> - <linearGradient - id="linearGradient4465"> - <stop - id="stop4467" - offset="0" - style="stop-color:#c1c1c1;stop-opacity:1;" /> - <stop - id="stop4469" - offset="1" - style="stop-color:#8c8c8c;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient4424"> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="0" - id="stop4426" /> - <stop - style="stop-color:#b3b3b3;stop-opacity:1;" - offset="1" - id="stop4428" /> - </linearGradient> - <linearGradient - id="linearGradient4357"> - <stop - id="stop4359" - offset="0" - style="stop-color:#ffffff;stop-opacity:1;" /> - <stop - style="stop-color:#ffa184;stop-opacity:0.49803922;" - offset="0.36363637" - id="stop4473" /> - <stop - id="stop4361" - offset="1" - style="stop-color:#ff440a;stop-opacity:0;" /> - </linearGradient> - <linearGradient - id="linearGradient4347"> - <stop - id="stop4349" - offset="0" - style="stop-color:#909090;stop-opacity:1;" /> - <stop - id="stop4351" - offset="1" - style="stop-color:#3c3c3c;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient3767"> - <stop - style="stop-color:#ffda82;stop-opacity:1;" - offset="0" - id="stop3769" /> - <stop - style="stop-color:#ffbb19;stop-opacity:1;" - offset="1" - id="stop3771" /> - </linearGradient> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4347" - id="linearGradient3779" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" - gradientUnits="userSpaceOnUse" /> - <filter - inkscape:collect="always" - id="filter4339"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="0.3240906" - id="feGaussianBlur4341" /> - </filter> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3767" - id="linearGradient4345" - gradientUnits="userSpaceOnUse" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4424" - id="linearGradient4430" - x1="10.740074" - y1="16.148634" - x2="6.3055735" - y2="-1.2798394" - gradientUnits="userSpaceOnUse" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient4357" - id="radialGradient4440" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)" - cx="8.1975746" - cy="-0.080271922" - fx="8.1975746" - fy="-0.080271922" - r="7.7781744" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4465" - id="linearGradient4471" - gradientUnits="userSpaceOnUse" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" /> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="23.894737" - inkscape:cx="16" - inkscape:cy="-1" - inkscape:current-layer="layer5" - showgrid="true" - inkscape:grid-bbox="true" - inkscape:document-units="px" - inkscape:window-width="1920" - inkscape:window-height="1127" - inkscape:window-x="0" - inkscape:window-y="25" - inkscape:window-maximized="1" - showguides="true" - inkscape:guide-bbox="true" /> - <metadata - id="metadata2992"> - <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 - inkscape:groupmode="layer" - id="layer4" - inkscape:label="Shadow" - style="display:inline" - sodipodi:insensitive="true"> - <path - sodipodi:type="arc" - style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)" - id="path2997" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.7781744" - sodipodi:ry="7.7781744" - d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" - transform="translate(0,-0.08838835)" /> - </g> - <g - id="layer1" - inkscape:label="Clock" - inkscape:groupmode="layer" - style="display:inline" - sodipodi:insensitive="true"> - <path - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" - d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" - sodipodi:ry="7.7781744" - sodipodi:rx="7.7781744" - sodipodi:cy="8.1334372" - sodipodi:cx="8.0433397" - id="path4343" - style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none" - sodipodi:type="arc" /> - </g> - <g - inkscape:groupmode="layer" - id="layer5" - inkscape:label="Block" - style="display:inline"> - <path - sodipodi:type="arc" - style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline" - id="path4462" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.7781744" - sodipodi:ry="7.7781744" - d="M 8.2135533,15.909749 A 7.7781744,7.7781744 0 1 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z" - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" - sodipodi:start="1.5489111" - sodipodi:end="4.7159107" /> - </g> - <g - inkscape:groupmode="layer" - id="layer2" - inkscape:label="Ticks" - style="display:inline" - sodipodi:insensitive="true"> - <path - id="use4309" - transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)" - style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none" - d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="m 7.875,2.8017767 0,5.25" - id="path4436" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 7.7781746,7.4629419 10.783378,7.6397186" - id="path4438" - inkscape:connector-curvature="0" /> - </g> - <g - inkscape:groupmode="layer" - id="layer3" - inkscape:label="Shine" - style="display:inline" - sodipodi:insensitive="true"> - <path - sodipodi:type="arc" - style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none" - id="path4353" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.3686199" - sodipodi:ry="7.4368792" - d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z" - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" /> - </g> -</svg> diff --git a/src/qt/res/src/clock4.svg b/src/qt/res/src/clock4.svg deleted file mode 100644 index 7d9dc37acb..0000000000 --- a/src/qt/res/src/clock4.svg +++ /dev/null @@ -1,261 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<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" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="16px" - height="16px" - id="svg2987" - version="1.1" - inkscape:version="0.48.0 r9654" - sodipodi:docname="clock2.svg"> - <defs - id="defs2989"> - <linearGradient - id="linearGradient4465"> - <stop - id="stop4467" - offset="0" - style="stop-color:#c1c1c1;stop-opacity:1;" /> - <stop - id="stop4469" - offset="1" - style="stop-color:#8c8c8c;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient4424"> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="0" - id="stop4426" /> - <stop - style="stop-color:#b3b3b3;stop-opacity:1;" - offset="1" - id="stop4428" /> - </linearGradient> - <linearGradient - id="linearGradient4357"> - <stop - id="stop4359" - offset="0" - style="stop-color:#ffffff;stop-opacity:1;" /> - <stop - style="stop-color:#ffcc84;stop-opacity:0.49803922;" - offset="0.36363637" - id="stop4473" /> - <stop - id="stop4361" - offset="1" - style="stop-color:#ff9a0a;stop-opacity:0;" /> - </linearGradient> - <linearGradient - id="linearGradient4347"> - <stop - id="stop4349" - offset="0" - style="stop-color:#909090;stop-opacity:1;" /> - <stop - id="stop4351" - offset="1" - style="stop-color:#3c3c3c;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient3767"> - <stop - style="stop-color:#f8ff82;stop-opacity:1;" - offset="0" - id="stop3769" /> - <stop - style="stop-color:#f1ff19;stop-opacity:1;" - offset="1" - id="stop3771" /> - </linearGradient> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4347" - id="linearGradient3779" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" - gradientUnits="userSpaceOnUse" /> - <filter - inkscape:collect="always" - id="filter4339"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="0.3240906" - id="feGaussianBlur4341" /> - </filter> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3767" - id="linearGradient4345" - gradientUnits="userSpaceOnUse" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4424" - id="linearGradient4430" - x1="10.740074" - y1="16.148634" - x2="6.3055735" - y2="-1.2798394" - gradientUnits="userSpaceOnUse" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient4357" - id="radialGradient4440" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)" - cx="8.1975746" - cy="-0.080271922" - fx="8.1975746" - fy="-0.080271922" - r="7.7781744" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4465" - id="linearGradient4471" - gradientUnits="userSpaceOnUse" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" /> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="16" - inkscape:cx="8.6111742" - inkscape:cy="6.6684704" - inkscape:current-layer="layer5" - showgrid="true" - inkscape:grid-bbox="true" - inkscape:document-units="px" - inkscape:window-width="1920" - inkscape:window-height="1127" - inkscape:window-x="0" - inkscape:window-y="25" - inkscape:window-maximized="1" - showguides="true" - inkscape:guide-bbox="true" /> - <metadata - id="metadata2992"> - <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 - inkscape:groupmode="layer" - id="layer4" - inkscape:label="Shadow" - style="display:inline" - sodipodi:insensitive="true"> - <path - sodipodi:type="arc" - style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)" - id="path2997" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.7781744" - sodipodi:ry="7.7781744" - d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" - transform="translate(0,-0.08838835)" /> - </g> - <g - id="layer1" - inkscape:label="Clock" - inkscape:groupmode="layer" - style="display:inline" - sodipodi:insensitive="true"> - <path - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" - d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" - sodipodi:ry="7.7781744" - sodipodi:rx="7.7781744" - sodipodi:cy="8.1334372" - sodipodi:cx="8.0433397" - id="path4343" - style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none" - sodipodi:type="arc" /> - </g> - <g - inkscape:groupmode="layer" - id="layer5" - inkscape:label="Block" - style="display:inline"> - <path - sodipodi:type="arc" - style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline" - id="path4462" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.7781744" - sodipodi:ry="7.7781744" - d="M 1.7005474,12.635546 A 7.7781744,7.7781744 0 0 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z" - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" - sodipodi:start="2.5243203" - sodipodi:end="4.7159107" /> - </g> - <g - inkscape:groupmode="layer" - id="layer2" - inkscape:label="Ticks" - style="display:inline" - sodipodi:insensitive="true"> - <path - id="use4309" - transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)" - style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none" - d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="m 7.875,2.8017767 0,5.25" - id="path4436" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 7.7781746,7.4629419 10.783378,7.6397186" - id="path4438" - inkscape:connector-curvature="0" /> - </g> - <g - inkscape:groupmode="layer" - id="layer3" - inkscape:label="Shine" - style="display:inline" - sodipodi:insensitive="true"> - <path - sodipodi:type="arc" - style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none" - id="path4353" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.3686199" - sodipodi:ry="7.4368792" - d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z" - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" /> - </g> -</svg> diff --git a/src/qt/res/src/clock5.svg b/src/qt/res/src/clock5.svg deleted file mode 100644 index 9fd58d9d97..0000000000 --- a/src/qt/res/src/clock5.svg +++ /dev/null @@ -1,262 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<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" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="16px" - height="16px" - id="svg2987" - version="1.1" - inkscape:version="0.48.0 r9654" - sodipodi:docname="clock3.svg"> - <defs - id="defs2989"> - <linearGradient - id="linearGradient4465"> - <stop - id="stop4467" - offset="0" - style="stop-color:#c1c1c1;stop-opacity:1;" /> - <stop - id="stop4469" - offset="1" - style="stop-color:#8c8c8c;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient4424"> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="0" - id="stop4426" /> - <stop - style="stop-color:#b3b3b3;stop-opacity:1;" - offset="1" - id="stop4428" /> - </linearGradient> - <linearGradient - id="linearGradient4357"> - <stop - id="stop4359" - offset="0" - style="stop-color:#ffffff;stop-opacity:1;" /> - <stop - style="stop-color:#fff884;stop-opacity:0.49803922;" - offset="0.36363637" - id="stop4473" /> - <stop - id="stop4361" - offset="1" - style="stop-color:#fff10a;stop-opacity:0;" /> - </linearGradient> - <linearGradient - id="linearGradient4347"> - <stop - id="stop4349" - offset="0" - style="stop-color:#909090;stop-opacity:1;" /> - <stop - id="stop4351" - offset="1" - style="stop-color:#3c3c3c;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient3767"> - <stop - style="stop-color:#ccff82;stop-opacity:1;" - offset="0" - id="stop3769" /> - <stop - style="stop-color:#a0ff19;stop-opacity:1;" - offset="1" - id="stop3771" /> - </linearGradient> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4347" - id="linearGradient3779" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" - gradientUnits="userSpaceOnUse" /> - <filter - inkscape:collect="always" - id="filter4339"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="0.3240906" - id="feGaussianBlur4341" /> - </filter> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3767" - id="linearGradient4345" - gradientUnits="userSpaceOnUse" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4424" - id="linearGradient4430" - x1="10.740074" - y1="16.148634" - x2="6.3055735" - y2="-1.2798394" - gradientUnits="userSpaceOnUse" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient4357" - id="radialGradient4440" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)" - cx="8.1975746" - cy="-0.080271922" - fx="8.1975746" - fy="-0.080271922" - r="7.7781744" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4465" - id="linearGradient4471" - gradientUnits="userSpaceOnUse" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" /> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="16" - inkscape:cx="8.6111742" - inkscape:cy="6.6684704" - inkscape:current-layer="layer3" - showgrid="true" - inkscape:grid-bbox="true" - inkscape:document-units="px" - inkscape:window-width="1920" - inkscape:window-height="1127" - inkscape:window-x="0" - inkscape:window-y="25" - inkscape:window-maximized="1" - showguides="true" - inkscape:guide-bbox="true" /> - <metadata - id="metadata2992"> - <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 - inkscape:groupmode="layer" - id="layer4" - inkscape:label="Shadow" - style="display:inline" - sodipodi:insensitive="true"> - <path - sodipodi:type="arc" - style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)" - id="path2997" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.7781744" - sodipodi:ry="7.7781744" - d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" - transform="translate(0,-0.08838835)" /> - </g> - <g - id="layer1" - inkscape:label="Clock" - inkscape:groupmode="layer" - style="display:inline" - sodipodi:insensitive="true"> - <path - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" - d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" - sodipodi:ry="7.7781744" - sodipodi:rx="7.7781744" - sodipodi:cy="8.1334372" - sodipodi:cx="8.0433397" - id="path4343" - style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none" - sodipodi:type="arc" /> - </g> - <g - inkscape:groupmode="layer" - id="layer5" - inkscape:label="Block" - style="display:inline" - sodipodi:insensitive="true"> - <path - sodipodi:type="arc" - style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline" - id="path4462" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.7781744" - sodipodi:ry="7.7781744" - d="M 1.0968082,4.6340519 A 7.7781744,7.7781744 0 0 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z" - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" - sodipodi:start="3.6082438" - sodipodi:end="4.7159107" /> - </g> - <g - inkscape:groupmode="layer" - id="layer2" - inkscape:label="Ticks" - style="display:inline" - sodipodi:insensitive="true"> - <path - id="use4309" - transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)" - style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none" - d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="m 7.875,2.8017767 0,5.25" - id="path4436" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 7.7781746,7.4629419 10.783378,7.6397186" - id="path4438" - inkscape:connector-curvature="0" /> - </g> - <g - inkscape:groupmode="layer" - id="layer3" - inkscape:label="Shine" - style="display:inline" - sodipodi:insensitive="true"> - <path - sodipodi:type="arc" - style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none" - id="path4353" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.3686199" - sodipodi:ry="7.4368792" - d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z" - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" /> - </g> -</svg> diff --git a/src/qt/res/src/clock_0.svg b/src/qt/res/src/clock_0.svg new file mode 100644 index 0000000000..2a4ae02355 --- /dev/null +++ b/src/qt/res/src/clock_0.svg @@ -0,0 +1,14 @@ +<?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>
+<path fill="#000000" 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>
diff --git a/src/qt/res/src/clock_1.svg b/src/qt/res/src/clock_1.svg new file mode 100644 index 0000000000..4e49772d26 --- /dev/null +++ b/src/qt/res/src/clock_1.svg @@ -0,0 +1,13 @@ +<?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="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+</svg>
diff --git a/src/qt/res/src/clock_2.svg b/src/qt/res/src/clock_2.svg new file mode 100644 index 0000000000..995446e46e --- /dev/null +++ b/src/qt/res/src/clock_2.svg @@ -0,0 +1,14 @@ +<?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="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 "/>
+</svg>
diff --git a/src/qt/res/src/clock_3.svg b/src/qt/res/src/clock_3.svg new file mode 100644 index 0000000000..ea47a84730 --- /dev/null +++ b/src/qt/res/src/clock_3.svg @@ -0,0 +1,15 @@ +<?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="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 "/>
+</svg>
diff --git a/src/qt/res/src/clock_4.svg b/src/qt/res/src/clock_4.svg new file mode 100644 index 0000000000..43160288d8 --- /dev/null +++ b/src/qt/res/src/clock_4.svg @@ -0,0 +1,18 @@ +<?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>
diff --git a/src/qt/res/src/clock_green.svg b/src/qt/res/src/clock_green.svg deleted file mode 100644 index e31f0e7995..0000000000 --- a/src/qt/res/src/clock_green.svg +++ /dev/null @@ -1,262 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<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" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="16px" - height="16px" - id="svg2987" - version="1.1" - inkscape:version="0.48.0 r9654" - sodipodi:docname="clock_green.svg"> - <defs - id="defs2989"> - <linearGradient - id="linearGradient4465"> - <stop - id="stop4467" - offset="0" - style="stop-color:#c1c1c1;stop-opacity:1;" /> - <stop - id="stop4469" - offset="1" - style="stop-color:#8c8c8c;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient4424"> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="0" - id="stop4426" /> - <stop - style="stop-color:#b3b3b3;stop-opacity:1;" - offset="1" - id="stop4428" /> - </linearGradient> - <linearGradient - id="linearGradient4357"> - <stop - id="stop4359" - offset="0" - style="stop-color:#ffffff;stop-opacity:1;" /> - <stop - style="stop-color:#baff84;stop-opacity:0.49803922;" - offset="0.36363637" - id="stop4473" /> - <stop - id="stop4361" - offset="1" - style="stop-color:#76ff0a;stop-opacity:0;" /> - </linearGradient> - <linearGradient - id="linearGradient4347"> - <stop - id="stop4349" - offset="0" - style="stop-color:#c1c1c1;stop-opacity:1;" /> - <stop - id="stop4351" - offset="1" - style="stop-color:#8c8c8c;stop-opacity:1;" /> - </linearGradient> - <linearGradient - id="linearGradient3767"> - <stop - style="stop-color:#82ff82;stop-opacity:1;" - offset="0" - id="stop3769" /> - <stop - style="stop-color:#19ff19;stop-opacity:1;" - offset="1" - id="stop3771" /> - </linearGradient> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4347" - id="linearGradient3779" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" - gradientUnits="userSpaceOnUse" /> - <filter - inkscape:collect="always" - id="filter4339"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="0.3240906" - id="feGaussianBlur4341" /> - </filter> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3767" - id="linearGradient4345" - gradientUnits="userSpaceOnUse" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4424" - id="linearGradient4430" - x1="10.740074" - y1="16.148634" - x2="6.3055735" - y2="-1.2798394" - gradientUnits="userSpaceOnUse" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient4357" - id="radialGradient4440" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)" - cx="8.1975746" - cy="-0.080271922" - fx="8.1975746" - fy="-0.080271922" - r="7.7781744" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4465" - id="linearGradient4471" - gradientUnits="userSpaceOnUse" - x1="2.224874" - y1="2.8301363" - x2="14.038582" - y2="13.171574" /> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="8" - inkscape:cx="9.1870806" - inkscape:cy="14.089546" - inkscape:current-layer="layer3" - showgrid="true" - inkscape:grid-bbox="true" - inkscape:document-units="px" - inkscape:window-width="1920" - inkscape:window-height="1127" - inkscape:window-x="0" - inkscape:window-y="25" - inkscape:window-maximized="1" - showguides="true" - inkscape:guide-bbox="true" /> - <metadata - id="metadata2992"> - <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 - inkscape:groupmode="layer" - id="layer4" - inkscape:label="Shadow" - style="display:inline" - sodipodi:insensitive="true"> - <path - sodipodi:type="arc" - style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)" - id="path2997" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.7781744" - sodipodi:ry="7.7781744" - d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" - transform="translate(0,-0.08838835)" /> - </g> - <g - id="layer1" - inkscape:label="Clock" - inkscape:groupmode="layer" - style="display:inline" - sodipodi:insensitive="true"> - <path - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" - d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" - sodipodi:ry="7.7781744" - sodipodi:rx="7.7781744" - sodipodi:cy="8.1334372" - sodipodi:cx="8.0433397" - id="path4343" - style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none" - sodipodi:type="arc" /> - </g> - <g - inkscape:groupmode="layer" - id="layer5" - inkscape:label="Block" - sodipodi:insensitive="true" - style="display:inline"> - <path - sodipodi:type="arc" - style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline" - id="path4462" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.7781744" - sodipodi:ry="7.7781744" - d="M 14.4287,3.6919089 A 7.7781744,7.7781744 0 1 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z" - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" - sodipodi:start="5.675432" - sodipodi:end="10.999096" /> - </g> - <g - inkscape:groupmode="layer" - id="layer2" - inkscape:label="Ticks" - style="display:inline" - sodipodi:insensitive="true"> - <path - id="use4309" - transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)" - style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none" - d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="m 7.875,2.8017767 0,5.25" - id="path4436" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - d="M 7.7781746,7.4629419 10.783378,7.6397186" - id="path4438" - inkscape:connector-curvature="0" /> - </g> - <g - inkscape:groupmode="layer" - id="layer3" - inkscape:label="Shine" - style="display:inline" - sodipodi:insensitive="true"> - <path - sodipodi:type="arc" - style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none" - id="path4353" - sodipodi:cx="8.0433397" - sodipodi:cy="8.1334372" - sodipodi:rx="7.3686199" - sodipodi:ry="7.4368792" - d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z" - transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" /> - </g> -</svg> diff --git a/src/qt/res/src/connect-0.svg b/src/qt/res/src/connect-0.svg new file mode 100644 index 0000000000..bedbec7777 --- /dev/null +++ b/src/qt/res/src/connect-0.svg @@ -0,0 +1,11 @@ +<?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>
diff --git a/src/qt/res/src/connect-1.svg b/src/qt/res/src/connect-1.svg new file mode 100644 index 0000000000..d3d4e46a41 --- /dev/null +++ b/src/qt/res/src/connect-1.svg @@ -0,0 +1,21 @@ +<?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>
diff --git a/src/qt/res/src/connect-2.svg b/src/qt/res/src/connect-2.svg new file mode 100644 index 0000000000..d5becc52b7 --- /dev/null +++ b/src/qt/res/src/connect-2.svg @@ -0,0 +1,22 @@ +<?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>
diff --git a/src/qt/res/src/connect-3.svg b/src/qt/res/src/connect-3.svg new file mode 100644 index 0000000000..9bfa04721f --- /dev/null +++ b/src/qt/res/src/connect-3.svg @@ -0,0 +1,16 @@ +<?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>
diff --git a/src/qt/res/src/inout.svg b/src/qt/res/src/inout.svg deleted file mode 100644 index bfab8ef6ab..0000000000 --- a/src/qt/res/src/inout.svg +++ /dev/null @@ -1,122 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<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" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - id="svg3039" - version="1.1" - inkscape:version="0.48.0 r9654" - width="120" - height="120" - sodipodi:docname="inout3.svg" - inkscape:export-filename="/home/orion/projects2/bitcoin/tx_mined.png" - inkscape:export-xdpi="12" - inkscape:export-ydpi="12" - style="display:inline"> - <metadata - id="metadata3045"> - <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="defs3043" /> - <sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="1920" - inkscape:window-height="1127" - id="namedview3041" - showgrid="false" - inkscape:zoom="1" - inkscape:cx="87.12655" - inkscape:cy="67.287943" - inkscape:window-x="0" - inkscape:window-y="25" - inkscape:window-maximized="1" - inkscape:current-layer="layer7" /> - <g - inkscape:groupmode="layer" - id="layer2" - inkscape:label="base" - style="display:none"> - <path - style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#afafaf;fill-opacity:1;stroke:none;stroke-width:7;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" - d="m 45.375,17 c -13.984022,0.241082 -24.968241,3.28976 -37.4375,9.59375 -8.9920665,21.871558 -6.680947,46.393002 -1.96875,69 26.190925,13.15317 55.594909,12.97748 81.75,-0.21875 3.852144,-9.729509 1.599587,-12.800015 2.375,-23.15625 C 83.917272,72.423868 77.129905,67.688094 74.1875,75.25 72.702487,79.722025 76.119709,82.645519 69.15625,83.34375 53.023957,88.536726 37.721719,89.140031 21.875,82.28125 19.715285,68.367979 18.599566,53.65725 22.5,40 c 16.868164,-6.642068 33.121079,-6.120062 50.03125,-0.15625 1.285344,5.854815 1.574746,5.763255 2.375,11.6875 C 80.46378,51.970623 89.644961,53.334736 91.3125,46 91.85305,36.007959 89.372312,31.625095 87.1875,25.6875 73.709743,21.03478 59.804255,16.698888 45.375,17 z" - id="path3053" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cccccccccccccc" /> - </g> - <g - inkscape:groupmode="layer" - id="layer3" - inkscape:label="arrow_out" - style="display:none"> - <path - style="fill:#6e6e6e;fill-opacity:1;stroke:none;display:inline" - d="m 63.983409,65.48134 0.267857,-9.514444 36.161424,-0.194173 -7.414458,-8.757971 3.798312,-7.572721 c 0,0 23.437946,20.796656 22.500436,21.185 -0.93751,0.388345 -23.170094,22.73838 -23.170094,22.73838 l -3.128654,-8.931927 7.548388,-8.5638 z" - id="path3844" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cccccscccc" /> - </g> - <g - inkscape:groupmode="layer" - id="layer4" - inkscape:label="arrow_in" - style="display:none"> - <path - inkscape:connector-curvature="0" - id="path4080" - d="m 99.28763,65.48134 -0.26786,-9.514444 -36.161422,-0.194173 7.768009,-6.283097 -4.151865,-9.279828 c 0,0 -23.43795,20.028889 -22.500436,20.417233 0.937514,0.388345 23.170094,20.970613 23.170094,20.970613 l 3.482207,-9.639034 -7.901936,-6.088926 z" - style="fill:#6e6e6e;fill-opacity:1;stroke:none;display:inline" - sodipodi:nodetypes="cccccscccc" /> - </g> - <g - inkscape:groupmode="layer" - id="layer7" - inkscape:label="mined" - style="display:inline"> - <path - style="fill:#a9a9a9;fill-opacity:1;stroke:none;display:inline" - d="M 9.4375,99.758169 78.14665,33.110294 73.680556,28.300653 67.153187,8.375 l 18.55147,6.527369 4.80964,3.779003 4.809641,-4.80964 11.680552,12.367647 -6.18382,4.80964 13.74183,14.085377 -12.71119,14.42892 -14.77247,-16.14665 -65.273693,70.770424 z" - id="path4103" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cccccccccccccc" /> - <path - sodipodi:nodetypes="cccccccccccccc" - inkscape:connector-curvature="0" - id="path4619" - d="M 114.5625,99.758169 45.85335,33.110294 50.319444,28.300653 56.846813,8.375 l -18.55147,6.527369 -4.80964,3.779003 -4.809641,-4.80964 -11.680556,12.367647 6.183825,4.80964 L 9.4375,45.134396 22.148693,59.563316 36.92116,43.416666 102.19485,114.18709 z" - style="fill:#a9a9a9;fill-opacity:1;stroke:none;display:inline" /> - <path - style="fill:#6e6e6e;fill-opacity:1;stroke:none" - d="M 10.960155,44.693128 38.53732,16.408856 54.093669,10.752002 48.436815,28.076118 22.273864,56.713943 z" - id="path5256" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cccccc" /> - <path - style="fill:#6e6e6e;fill-opacity:1;stroke:none" - d="M 69.296465,10.398449 85.559921,17.115963 111.72287,45.046681 102.17693,56.713943 74.953319,27.722565 z" - id="path5258" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cccccc" /> - </g> -</svg> diff --git a/src/qt/res/src/mine.svg b/src/qt/res/src/mine.svg new file mode 100644 index 0000000000..4a3f786607 --- /dev/null +++ b/src/qt/res/src/mine.svg @@ -0,0 +1,12 @@ +<?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">
+<rect x="464" y="158.6" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 1027.5018 42.8013)" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="81.9" height="151.3"/>
+<rect x="190" y="342.1" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 882.9977 387.9771)" fill="none" stroke="#000000" stroke-width="30" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="342.3" height="69.4"/>
+<path stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M445.7,186l32.2-32.2
+ c-44.6-37.2-124-74.4-218.3-64.5l-2.5,9.9C361.4,114.1,403.6,153.8,445.7,186z"/>
+<path stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M552.4,292.7l32.2-32.2
+ c37.2,44.6,74.4,124,64.5,218.3l-9.9,2.5C624.3,377,584.6,332.4,552.4,292.7z"/>
+</svg>
diff --git a/src/qt/res/src/qt.svg b/src/qt/res/src/qt.svg new file mode 100644 index 0000000000..9ef54f493c --- /dev/null +++ b/src/qt/res/src/qt.svg @@ -0,0 +1,25 @@ +<?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>
diff --git a/src/qt/res/src/questionmark.svg b/src/qt/res/src/questionmark.svg deleted file mode 100644 index c03c159a5f..0000000000 --- a/src/qt/res/src/questionmark.svg +++ /dev/null @@ -1,159 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<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" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="16px" - height="16px" - id="svg2993" - version="1.1" - inkscape:version="0.48.0 r9654" - sodipodi:docname="questionmark.svg" - inkscape:export-filename="/store/orion/projects/bitcoin/questionmark.png" - inkscape:export-xdpi="90" - inkscape:export-ydpi="90"> - <defs - id="defs2995"> - <linearGradient - id="linearGradient3808"> - <stop - style="stop-color:#c8c8c8;stop-opacity:1;" - offset="0" - id="stop3810" /> - <stop - style="stop-color:#959595;stop-opacity:1" - offset="1" - id="stop3812" /> - </linearGradient> - <filter - inkscape:collect="always" - id="filter3804" - x="-0.2510722" - width="1.5021444" - y="-0.13164773" - height="1.2632955"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="0.73280473" - id="feGaussianBlur3806" /> - </filter> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient3808" - id="linearGradient3844" - x1="8.4916801" - y1="1.4395804" - x2="8.6022711" - y2="14.211697" - gradientUnits="userSpaceOnUse" /> - <filter - inkscape:collect="always" - id="filter3889" - x="-0.13954329" - width="1.2790866" - y="-0.073168421" - height="1.1463368"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="0.40728516" - id="feGaussianBlur3891" /> - </filter> - <filter - inkscape:collect="always" - id="filter3897" - x="-0.17178624" - width="1.3435725" - y="-0.090074761" - height="1.1801495"> - <feGaussianBlur - inkscape:collect="always" - stdDeviation="0.50139271" - id="feGaussianBlur3899" /> - </filter> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="1" - inkscape:cx="10.789648" - inkscape:cy="7.6382159" - inkscape:current-layer="layer2" - showgrid="true" - inkscape:grid-bbox="true" - inkscape:document-units="px" - inkscape:window-width="1920" - inkscape:window-height="1127" - inkscape:window-x="0" - inkscape:window-y="25" - inkscape:window-maximized="1" /> - <metadata - id="metadata2998"> - <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 - inkscape:groupmode="layer" - id="layer2" - inkscape:label="Below" - style="display:inline"> - <text - sodipodi:linespacing="125%" - id="text3006" - y="14.748394" - x="4.1060953" - style="font-size:18px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;filter:url(#filter3897)" - xml:space="preserve"><tspan - y="14.748394" - x="4.1060953" - id="tspan3008" - sodipodi:role="line">?</tspan></text> - <text - xml:space="preserve" - style="font-size:18px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;filter:url(#filter3889)" - x="4.1060953" - y="14.748394" - id="text3824" - sodipodi:linespacing="125%"><tspan - sodipodi:role="line" - id="tspan3826" - x="4.1060953" - y="14.748394">?</tspan></text> - </g> - <g - id="layer1" - inkscape:label="QuestionMark" - inkscape:groupmode="layer" - style="display:inline" - sodipodi:insensitive="true"> - <text - xml:space="preserve" - style="font-size:18px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient3844);fill-opacity:1;stroke:none;font-family:Sans" - x="4.1060953" - y="14.748394" - id="text3001" - sodipodi:linespacing="125%"><tspan - sodipodi:role="line" - id="tspan3003" - x="4.1060953" - y="14.748394" - style="fill:url(#linearGradient3844);fill-opacity:1">?</tspan></text> - </g> -</svg> diff --git a/src/qt/res/src/tx_in.svg b/src/qt/res/src/tx_in.svg new file mode 100644 index 0000000000..a8911f9045 --- /dev/null +++ b/src/qt/res/src/tx_in.svg @@ -0,0 +1,9 @@ +<?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,17.5c-2.5,0-4.5-2-4.5-4.5c0-0.6-0.4-1-1-1s-1,0.4-1,1c0,3.6,2.9,6.5,6.5,6.5s6.5-2.9,6.5-6.5S16.6,6.5,13,6.5
+ c-0.6,0-1,0.4-1,1s0.4,1,1,1c2.5,0,4.5,2,4.5,4.5S15.5,17.5,13,17.5z M3.7,10.3c-0.6,0-1-0.4-1-1s0.4-1,1-1H7L5.3,6.6L1.2,2.5
+ c-0.4-0.4-0.4-1,0-1.4c0.2-0.2,0.4-0.3,0.7-0.3s0.5,0.1,0.7,0.3l4.1,4.1l1.7,1.7V3.6c0-0.6,0.4-1,1-1s1,0.4,1,1v6.7L3.7,10.3"/>
+</svg>
diff --git a/src/qt/res/src/tx_inout.svg b/src/qt/res/src/tx_inout.svg new file mode 100644 index 0000000000..5b66889783 --- /dev/null +++ b/src/qt/res/src/tx_inout.svg @@ -0,0 +1,11 @@ +<?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="M14.7,19.5c-2.5,0-4.5-2-4.5-4.5c0-0.6-0.4-1-1-1c-0.6,0-1,0.4-1,1c0,3.6,2.9,6.5,6.5,6.5s6.5-2.9,6.5-6.5s-2.9-6.5-6.5-6.5
+ c-0.6,0-1,0.4-1,1s0.4,1,1,1c2.5,0,4.5,2,4.5,4.5S17.2,19.5,14.7,19.5z M5.9,12.5c-0.6,0-1-0.4-1-1s0.4-1,1-1h3.2L7.4,8.8L3.3,4.7
+ c-0.4-0.4-0.4-1,0-1.4C3.5,3.1,3.7,3,4,3s0.5,0.1,0.7,0.3l4.1,4.1l1.7,1.7V5.8c0-0.6,0.4-1,1-1s1,0.4,1,1v6.7L5.9,12.5 M7.5,0.8
+ c0.6,0,1,0.4,1,1s-0.4,1-1,1H4.3L6,4.5l4.1,4.1c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3S8.9,10.2,8.7,10L4.6,5.9L2.9,4.2v3.2
+ c0,0.6-0.4,1-1,1s-1-0.4-1-1V0.8L7.5,0.8"/>
+</svg>
diff --git a/src/qt/res/src/verify.svg b/src/qt/res/src/verify.svg new file mode 100644 index 0000000000..1ff11b7f5e --- /dev/null +++ b/src/qt/res/src/verify.svg @@ -0,0 +1,14 @@ +<?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">
+<path d="M654.1,317.5c-14.9-9.9-37.2-2.5-44.6,12.4l-62,111.6l-34.7-34.7c-12.4-12.4-34.7-12.4-47.1,0c-12.4,12.4-12.4,34.7,0,47.1
+ l67,67c7.4,7.4,14.9,9.9,22.3,9.9h5c9.9-2.5,19.8-7.4,24.8-17.4l81.9-148.8C676.4,347.2,671.5,327.4,654.1,317.5z"/>
+<path d="M326.7,471.3H177.9V362.1l94.3-94.3c-5-14.9-7.4-29.8-7.4-44.6c0-81.9,67-148.8,148.8-148.8s148.8,67,148.8,148.8
+ s-67,148.8-148.8,148.8h-37.2v49.6h-49.6L326.7,471.3L326.7,471.3z M227.5,421.7h49.6v-49.6h49.6v-49.6h86.8
+ c54.6,0,99.2-44.6,99.2-99.2S468.1,124,413.5,124s-99.2,44.6-99.2,99.2c0,14.9,2.5,27.3,9.9,39.7l7.4,14.9L230,379.5v42.2H227.5z
+ M413.5,198.4c14.9,0,24.8,9.9,24.8,24.8c0,14.9-9.9,24.8-24.8,24.8c-14.9,0-24.8-9.9-24.8-24.8
+ C388.7,208.3,401.1,198.4,413.5,198.4 M413.5,173.6c-27.3,0-49.6,22.3-49.6,49.6c0,27.3,22.3,49.6,49.6,49.6
+ c27.3,0,49.6-22.3,49.6-49.6C463.1,195.9,443.3,173.6,413.5,173.6z"/>
+</svg>
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 8129353d4b..a5e3ae2b35 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "rpcconsole.h" @@ -8,6 +8,7 @@ #include "clientmodel.h" #include "guiutil.h" #include "peertablemodel.h" +#include "scicon.h" #include "main.h" #include "chainparams.h" @@ -180,7 +181,7 @@ void RPCExecutor::request(const QString &command) emit reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint)); } - catch (json_spirit::Object& objError) + catch (const json_spirit::Object& objError) { try // Nice formatting for standard-format error { @@ -188,19 +189,19 @@ void RPCExecutor::request(const QString &command) std::string message = find_value(objError, "message").get_str(); emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")"); } - catch(std::runtime_error &) // raised when converting to invalid type, i.e. missing code or message + 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))); } } - catch (std::exception& e) + catch (const std::exception& e) { emit reply(RPCConsole::CMD_ERROR, QString("Error: ") + QString::fromStdString(e.what())); } } RPCConsole::RPCConsole(QWidget *parent) : - QDialog(parent), + QWidget(parent), ui(new Ui::RPCConsole), clientModel(0), historyPtr(0), @@ -210,8 +211,9 @@ RPCConsole::RPCConsole(QWidget *parent) : GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this); #ifndef Q_OS_MAC - ui->openDebugLogfileButton->setIcon(QIcon(":/icons/export")); + ui->openDebugLogfileButton->setIcon(SingleColorIcon(":/icons/export")); #endif + ui->clearButton->setIcon(SingleColorIcon(":/icons/remove")); // Install event filter for up and down arrow ui->lineEdit->installEventFilter(this); @@ -278,7 +280,7 @@ bool RPCConsole::eventFilter(QObject* obj, QEvent *event) } } } - return QDialog::eventFilter(obj, event); + return QWidget::eventFilter(obj, event); } void RPCConsole::setClientModel(ClientModel *model) @@ -348,7 +350,7 @@ void RPCConsole::clear() ui->messagesWidget->document()->addResource( QTextDocument::ImageResource, QUrl(ICON_MAPPING[i].url), - QImage(ICON_MAPPING[i].source).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + SingleColorImage(ICON_MAPPING[i].source, SingleColor()).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } // Set default style sheet @@ -361,16 +363,17 @@ void RPCConsole::clear() "b { color: #006060; } " ); - message(CMD_REPLY, (tr("Welcome to the Bitcoin RPC console.") + "<br>" + + message(CMD_REPLY, (tr("Welcome to the Bitcoin Core RPC console.") + "<br>" + tr("Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.") + "<br>" + tr("Type <b>help</b> for an overview of available commands.")), true); } -void RPCConsole::reject() +void RPCConsole::keyPressEvent(QKeyEvent *event) { - // Ignore escape keypress if this is not a seperate window - if(windowType() != Qt::Widget) - QDialog::reject(); + if(windowType() != Qt::Widget && event->key() == Qt::Key_Escape) + { + close(); + } } void RPCConsole::message(int category, const QString &message, bool html) @@ -611,7 +614,6 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats) 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->peerSyncNode->setText(stats->nodeStats.fSyncNode ? tr("Yes") : tr("No")); // This check fails for example if the lock was busy and // nodeStateStats couldn't be fetched. diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 1ffff92758..fff5cfbf59 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -1,16 +1,16 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. -#ifndef RPCCONSOLE_H -#define RPCCONSOLE_H +#ifndef BITCOIN_QT_RPCCONSOLE_H +#define BITCOIN_QT_RPCCONSOLE_H #include "guiutil.h" #include "peertablemodel.h" #include "net.h" -#include <QDialog> +#include <QWidget> class ClientModel; @@ -23,7 +23,7 @@ class QItemSelection; QT_END_NAMESPACE /** Local Bitcoin RPC console. */ -class RPCConsole: public QDialog +class RPCConsole: public QWidget { Q_OBJECT @@ -43,6 +43,7 @@ public: protected: virtual bool eventFilter(QObject* obj, QEvent *event); + void keyPressEvent(QKeyEvent *); private slots: void on_lineEdit_returnPressed(); @@ -59,7 +60,6 @@ private slots: public slots: void clear(); - void reject(); void message(int category, const QString &message, bool html = false); /** Set number of connections shown in the UI */ void setNumConnections(int count); @@ -100,4 +100,4 @@ private: NodeId cachedNodeid; }; -#endif // RPCCONSOLE_H +#endif // BITCOIN_QT_RPCCONSOLE_H diff --git a/src/qt/scicon.cpp b/src/qt/scicon.cpp new file mode 100644 index 0000000000..a0ffcd82a9 --- /dev/null +++ b/src/qt/scicon.cpp @@ -0,0 +1,84 @@ +// 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 new file mode 100644 index 0000000000..1388069ddb --- /dev/null +++ b/src/qt/scicon.h @@ -0,0 +1,24 @@ +// 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 25e3d2a0dc..ffee56131d 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "sendcoinsdialog.h" @@ -7,24 +7,31 @@ #include "addresstablemodel.h" #include "bitcoinunits.h" +#include "clientmodel.h" #include "coincontroldialog.h" #include "guiutil.h" #include "optionsmodel.h" +#include "scicon.h" #include "sendcoinsentry.h" #include "walletmodel.h" #include "base58.h" #include "coincontrol.h" #include "ui_interface.h" +#include "wallet.h" #include <QMessageBox> #include <QScrollBar> +#include <QSettings> #include <QTextDocument> SendCoinsDialog::SendCoinsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::SendCoinsDialog), - model(0) + clientModel(0), + model(0), + fNewRecipientAllowed(true), + fFeeMinimized(true) { ui->setupUi(this); @@ -32,6 +39,10 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent) : 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 GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this); @@ -72,7 +83,46 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent) : ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction); ui->labelCoinControlChange->addAction(clipboardChangeAction); - fNewRecipientAllowed = true; + // init transaction fee section + QSettings settings; + if (!settings.contains("fFeeSectionMinimized")) + settings.setValue("fFeeSectionMinimized", true); + if (!settings.contains("nFeeRadio") && settings.contains("nTransactionFee") && settings.value("nTransactionFee").toLongLong() > 0) // compatibility + settings.setValue("nFeeRadio", 1); // custom + if (!settings.contains("nFeeRadio")) + settings.setValue("nFeeRadio", 0); // recommended + if (!settings.contains("nCustomFeeRadio") && settings.contains("nTransactionFee") && settings.value("nTransactionFee").toLongLong() > 0) // compatibility + settings.setValue("nCustomFeeRadio", 1); // total at least + if (!settings.contains("nCustomFeeRadio")) + settings.setValue("nCustomFeeRadio", 0); // per kilobyte + if (!settings.contains("nSmartFeeSliderPosition")) + settings.setValue("nSmartFeeSliderPosition", 0); + if (!settings.contains("nTransactionFee")) + settings.setValue("nTransactionFee", (qint64)DEFAULT_TRANSACTION_FEE); + if (!settings.contains("fPayOnlyMinFee")) + settings.setValue("fPayOnlyMinFee", false); + if (!settings.contains("fSendFreeTransactions")) + settings.setValue("fSendFreeTransactions", false); + ui->groupFee->setId(ui->radioSmartFee, 0); + ui->groupFee->setId(ui->radioCustomFee, 1); + ui->groupFee->button((int)std::max(0, std::min(1, settings.value("nFeeRadio").toInt())))->setChecked(true); + ui->groupCustomFee->setId(ui->radioCustomPerKilobyte, 0); + ui->groupCustomFee->setId(ui->radioCustomAtLeast, 1); + ui->groupCustomFee->button((int)std::max(0, std::min(1, settings.value("nCustomFeeRadio").toInt())))->setChecked(true); + ui->sliderSmartFee->setValue(settings.value("nSmartFeeSliderPosition").toInt()); + ui->customFee->setValue(settings.value("nTransactionFee").toLongLong()); + ui->checkBoxMinimumFee->setChecked(settings.value("fPayOnlyMinFee").toBool()); + ui->checkBoxFreeTx->setChecked(settings.value("fSendFreeTransactions").toBool()); + minimizeFeeSection(settings.value("fFeeSectionMinimized").toBool()); +} + +void SendCoinsDialog::setClientModel(ClientModel *clientModel) +{ + this->clientModel = clientModel; + + if (clientModel) { + connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(updateSmartFeeLabel())); + } } void SendCoinsDialog::setModel(WalletModel *model) @@ -92,20 +142,52 @@ void SendCoinsDialog::setModel(WalletModel *model) setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance()); - connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64, qint64, qint64, qint64))); + connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount))); connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + updateDisplayUnit(); // Coin Control connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(coinControlUpdateLabels())); connect(model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(coinControlFeatureChanged(bool))); - connect(model->getOptionsModel(), SIGNAL(transactionFeeChanged(qint64)), this, SLOT(coinControlUpdateLabels())); ui->frameCoinControl->setVisible(model->getOptionsModel()->getCoinControlFeatures()); coinControlUpdateLabels(); + + // fee section + connect(ui->sliderSmartFee, SIGNAL(valueChanged(int)), this, SLOT(updateSmartFeeLabel())); + connect(ui->sliderSmartFee, SIGNAL(valueChanged(int)), this, SLOT(updateGlobalFeeVariables())); + connect(ui->sliderSmartFee, SIGNAL(valueChanged(int)), this, SLOT(coinControlUpdateLabels())); + connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(updateFeeSectionControls())); + connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(updateGlobalFeeVariables())); + connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, SLOT(coinControlUpdateLabels())); + connect(ui->groupCustomFee, SIGNAL(buttonClicked(int)), this, SLOT(updateGlobalFeeVariables())); + connect(ui->groupCustomFee, SIGNAL(buttonClicked(int)), this, SLOT(coinControlUpdateLabels())); + connect(ui->customFee, SIGNAL(valueChanged()), this, SLOT(updateGlobalFeeVariables())); + connect(ui->customFee, SIGNAL(valueChanged()), this, SLOT(coinControlUpdateLabels())); + connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(setMinimumFee())); + connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(updateFeeSectionControls())); + connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(updateGlobalFeeVariables())); + connect(ui->checkBoxMinimumFee, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels())); + connect(ui->checkBoxFreeTx, SIGNAL(stateChanged(int)), this, SLOT(updateGlobalFeeVariables())); + connect(ui->checkBoxFreeTx, SIGNAL(stateChanged(int)), this, SLOT(coinControlUpdateLabels())); + ui->customFee->setSingleStep(CWallet::minTxFee.GetFeePerK()); + updateFeeSectionControls(); + updateMinFeeLabel(); + updateSmartFeeLabel(); + updateGlobalFeeVariables(); } } SendCoinsDialog::~SendCoinsDialog() { + QSettings settings; + settings.setValue("fFeeSectionMinimized", fFeeMinimized); + settings.setValue("nFeeRadio", ui->groupFee->checkedId()); + settings.setValue("nCustomFeeRadio", ui->groupCustomFee->checkedId()); + settings.setValue("nSmartFeeSliderPosition", ui->sliderSmartFee->value()); + settings.setValue("nTransactionFee", (qint64)ui->customFee->value()); + settings.setValue("fPayOnlyMinFee", ui->checkBoxMinimumFee->isChecked()); + settings.setValue("fSendFreeTransactions", ui->checkBoxFreeTx->isChecked()); + delete ui; } @@ -203,7 +285,7 @@ void SendCoinsDialog::on_sendButton_clicked() return; } - qint64 txFee = currentTransaction.getTransactionFee(); + CAmount txFee = currentTransaction.getTransactionFee(); QString questionString = tr("Are you sure you want to send?"); questionString.append("<br /><br />%1"); @@ -214,11 +296,14 @@ void SendCoinsDialog::on_sendButton_clicked() questionString.append(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), txFee)); questionString.append("</span> "); questionString.append(tr("added as transaction fee")); + + // append transaction size + questionString.append(" (" + QString::number((double)currentTransaction.getTransactionSize() / 1000) + " kB)"); } // add total amount in all subdivision units questionString.append("<hr />"); - qint64 totalAmount = currentTransaction.getTotalTransactionAmount() + txFee; + CAmount totalAmount = currentTransaction.getTotalTransactionAmount() + txFee; QStringList alternativeUnits; foreach(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) { @@ -384,8 +469,8 @@ bool SendCoinsDialog::handlePaymentRequest(const SendCoinsRecipient &rv) return true; } -void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance, - qint64 watchBalance, qint64 watchUnconfirmedBalance, qint64 watchImmatureBalance) +void SendCoinsDialog::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, + const CAmount& watchBalance, const CAmount& watchUnconfirmedBalance, const CAmount& watchImmatureBalance) { Q_UNUSED(unconfirmedBalance); Q_UNUSED(immatureBalance); @@ -402,6 +487,9 @@ void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance, qint void SendCoinsDialog::updateDisplayUnit() { setBalance(model->getBalance(), 0, 0, 0, 0, 0); + ui->customFee->setDisplayUnit(model->getOptionsModel()->getDisplayUnit()); + updateMinFeeLabel(); + updateSmartFeeLabel(); } void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg) @@ -438,6 +526,9 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn msgParams.first = tr("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."); msgParams.second = CClientUIInterface::MSG_ERROR; break; + case WalletModel::InsaneFee: + msgParams.first = tr("A fee higher than %1 is considered an insanely high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000)); + break; // included to prevent a compiler warning. case WalletModel::OK: default: @@ -447,6 +538,110 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn emit message(tr("Send Coins"), msgParams.first, msgParams.second); } +void SendCoinsDialog::minimizeFeeSection(bool fMinimize) +{ + ui->labelFeeMinimized->setVisible(fMinimize); + ui->buttonChooseFee ->setVisible(fMinimize); + ui->buttonMinimizeFee->setVisible(!fMinimize); + ui->frameFeeSelection->setVisible(!fMinimize); + ui->horizontalLayoutSmartFee->setContentsMargins(0, (fMinimize ? 0 : 6), 0, 0); + fFeeMinimized = fMinimize; +} + +void SendCoinsDialog::on_buttonChooseFee_clicked() +{ + minimizeFeeSection(false); +} + +void SendCoinsDialog::on_buttonMinimizeFee_clicked() +{ + updateFeeMinimizedLabel(); + minimizeFeeSection(true); +} + +void SendCoinsDialog::setMinimumFee() +{ + ui->radioCustomPerKilobyte->setChecked(true); + ui->customFee->setValue(CWallet::minTxFee.GetFeePerK()); +} + +void SendCoinsDialog::updateFeeSectionControls() +{ + ui->sliderSmartFee ->setEnabled(ui->radioSmartFee->isChecked()); + ui->labelSmartFee ->setEnabled(ui->radioSmartFee->isChecked()); + ui->labelSmartFee2 ->setEnabled(ui->radioSmartFee->isChecked()); + ui->labelSmartFee3 ->setEnabled(ui->radioSmartFee->isChecked()); + ui->labelFeeEstimation ->setEnabled(ui->radioSmartFee->isChecked()); + ui->labelSmartFeeNormal ->setEnabled(ui->radioSmartFee->isChecked()); + ui->labelSmartFeeFast ->setEnabled(ui->radioSmartFee->isChecked()); + ui->checkBoxMinimumFee ->setEnabled(ui->radioCustomFee->isChecked()); + ui->labelMinFeeWarning ->setEnabled(ui->radioCustomFee->isChecked()); + ui->radioCustomPerKilobyte ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked()); + ui->radioCustomAtLeast ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked()); + ui->customFee ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked()); +} + +void SendCoinsDialog::updateGlobalFeeVariables() +{ + if (ui->radioSmartFee->isChecked()) + { + nTxConfirmTarget = (int)25 - (int)std::max(0, std::min(24, ui->sliderSmartFee->value())); + payTxFee = CFeeRate(0); + } + else + { + nTxConfirmTarget = 25; + payTxFee = CFeeRate(ui->customFee->value()); + fPayAtLeastCustomFee = ui->radioCustomAtLeast->isChecked(); + } + + fSendFreeTransactions = ui->checkBoxFreeTx->isChecked(); +} + +void SendCoinsDialog::updateFeeMinimizedLabel() +{ + if(!model || !model->getOptionsModel()) + return; + + if (ui->radioSmartFee->isChecked()) + ui->labelFeeMinimized->setText(ui->labelSmartFee->text()); + else { + ui->labelFeeMinimized->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), ui->customFee->value()) + + ((ui->radioCustomPerKilobyte->isChecked()) ? "/kB" : "")); + } +} + +void SendCoinsDialog::updateMinFeeLabel() +{ + if (model && model->getOptionsModel()) + ui->checkBoxMinimumFee->setText(tr("Pay only the minimum fee of %1").arg( + BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), CWallet::minTxFee.GetFeePerK()) + "/kB") + ); +} + +void SendCoinsDialog::updateSmartFeeLabel() +{ + if(!model || !model->getOptionsModel()) + return; + + int nBlocksToConfirm = (int)25 - (int)std::max(0, std::min(24, ui->sliderSmartFee->value())); + CFeeRate feeRate = mempool.estimateFee(nBlocksToConfirm); + if (feeRate <= CFeeRate(0)) // not enough data => minfee + { + ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), CWallet::minTxFee.GetFeePerK()) + "/kB"); + ui->labelSmartFee2->show(); // (Smart fee not initialized yet. This usually takes a few blocks...) + ui->labelFeeEstimation->setText(""); + } + else + { + ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB"); + ui->labelSmartFee2->hide(); + ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %n block(s).", "", nBlocksToConfirm)); + } + + updateFeeMinimizedLabel(); +} + // Coin Control: copy label "Quantity" to clipboard void SendCoinsDialog::coinControlClipboardQuantity() { @@ -462,19 +657,19 @@ void SendCoinsDialog::coinControlClipboardAmount() // Coin Control: copy label "Fee" to clipboard void SendCoinsDialog::coinControlClipboardFee() { - GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" "))); + GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace("~", "")); } // Coin Control: copy label "After fee" to clipboard void SendCoinsDialog::coinControlClipboardAfterFee() { - GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" "))); + GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace("~", "")); } // Coin Control: copy label "Bytes" to clipboard void SendCoinsDialog::coinControlClipboardBytes() { - GUIUtil::setClipboard(ui->labelCoinControlBytes->text()); + GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace("~", "")); } // Coin Control: copy label "Priority" to clipboard @@ -492,7 +687,7 @@ void SendCoinsDialog::coinControlClipboardLowOutput() // Coin Control: copy label "Change" to clipboard void SendCoinsDialog::coinControlClipboardChange() { - GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" "))); + GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace("~", "")); } // Coin Control: settings menu - coin control enabled/disabled by user diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index a090fa42d5..14adb02573 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -1,15 +1,16 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 SENDCOINSDIALOG_H -#define SENDCOINSDIALOG_H +#ifndef BITCOIN_QT_SENDCOINSDIALOG_H +#define BITCOIN_QT_SENDCOINSDIALOG_H #include "walletmodel.h" #include <QDialog> #include <QString> +class ClientModel; class OptionsModel; class SendCoinsEntry; class SendCoinsRecipient; @@ -31,6 +32,7 @@ public: explicit SendCoinsDialog(QWidget *parent = 0); ~SendCoinsDialog(); + void setClientModel(ClientModel *clientModel); void setModel(WalletModel *model); /** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907). @@ -47,21 +49,27 @@ public slots: void accept(); SendCoinsEntry *addEntry(); void updateTabsAndLabels(); - void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance, - qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance); + void setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, + const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance); private: Ui::SendCoinsDialog *ui; + ClientModel *clientModel; WalletModel *model; bool fNewRecipientAllowed; + bool fFeeMinimized; // Process WalletModel::SendCoinsReturn and generate a pair consisting // of a message and message flags for use in 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: void on_sendButton_clicked(); + void on_buttonChooseFee_clicked(); + void on_buttonMinimizeFee_clicked(); void removeEntry(SendCoinsEntry* entry); void updateDisplayUnit(); void coinControlFeatureChanged(bool); @@ -77,10 +85,15 @@ private slots: void coinControlClipboardPriority(); void coinControlClipboardLowOutput(); void coinControlClipboardChange(); + void setMinimumFee(); + void updateFeeSectionControls(); + void updateMinFeeLabel(); + void updateSmartFeeLabel(); + void updateGlobalFeeVariables(); signals: // Fired when a message should be reported to the user void message(const QString &title, const QString &message, unsigned int style); }; -#endif // SENDCOINSDIALOG_H +#endif // BITCOIN_QT_SENDCOINSDIALOG_H diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 52545c3857..6db6eee75b 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "sendcoinsentry.h" @@ -9,6 +9,7 @@ #include "addresstablemodel.h" #include "guiutil.h" #include "optionsmodel.h" +#include "scicon.h" #include "walletmodel.h" #include <QApplication> @@ -21,6 +22,12 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) : { 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")); + setCurrentWidget(ui->SendCoins); #ifdef Q_OS_MAC diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index 2b696c77fb..4cb00cd36a 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 SENDCOINSENTRY_H -#define SENDCOINSENTRY_H +#ifndef BITCOIN_QT_SENDCOINSENTRY_H +#define BITCOIN_QT_SENDCOINSENTRY_H #include "walletmodel.h" @@ -67,4 +67,4 @@ private: bool updateLabel(const QString &address); }; -#endif // SENDCOINSENTRY_H +#endif // BITCOIN_QT_SENDCOINSENTRY_H diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index d4d021e21c..970f6a520d 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "signverifymessagedialog.h" @@ -7,6 +7,7 @@ #include "addressbookpage.h" #include "guiutil.h" +#include "scicon.h" #include "walletmodel.h" #include "base58.h" @@ -25,6 +26,15 @@ SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) : { 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")); + #if QT_VERSION >= 0x040700 ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature")); #endif diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h index bba861649a..27807adc84 100644 --- a/src/qt/signverifymessagedialog.h +++ b/src/qt/signverifymessagedialog.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 SIGNVERIFYMESSAGEDIALOG_H -#define SIGNVERIFYMESSAGEDIALOG_H +#ifndef BITCOIN_QT_SIGNVERIFYMESSAGEDIALOG_H +#define BITCOIN_QT_SIGNVERIFYMESSAGEDIALOG_H #include <QDialog> @@ -48,4 +48,4 @@ private slots: void on_clearButton_VM_clicked(); }; -#endif // SIGNVERIFYMESSAGEDIALOG_H +#endif // BITCOIN_QT_SIGNVERIFYMESSAGEDIALOG_H diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 673e984691..366ed3df3d 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -1,11 +1,12 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "splashscreen.h" #include "clientversion.h" #include "init.h" +#include "networkstyle.h" #include "ui_interface.h" #include "util.h" #include "version.h" @@ -18,12 +19,11 @@ #include <QCloseEvent> #include <QDesktopWidget> #include <QPainter> +#include <QRadialGradient> -SplashScreen::SplashScreen(Qt::WindowFlags f, bool isTestNet) : +SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) : QWidget(0, f), curAlignment(0) { - //setAutoFillBackground(true); - // set reference point, paddings int paddingRight = 50; int paddingTop = 50; @@ -31,26 +31,46 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, bool isTestNet) : int titleCopyrightVSpace = 40; float fontFactor = 1.0; + float devicePixelRatio = 1.0; +#if QT_VERSION > 0x050100 + devicePixelRatio = ((QGuiApplication*)QCoreApplication::instance())->devicePixelRatio(); +#endif // define text to place QString titleText = tr("Bitcoin Core"); QString versionText = QString("Version %1").arg(QString::fromStdString(FormatFullVersion())); QString copyrightText = QChar(0xA9)+QString(" 2009-%1 ").arg(COPYRIGHT_YEAR) + QString(tr("The Bitcoin Core developers")); - QString testnetAddText = QString(tr("[testnet]")); // define text to place as single text object + QString titleAddText = networkStyle->getTitleAddText(); QString font = "Arial"; - // load the bitmap for writing some text over it - if(isTestNet) { - pixmap = QPixmap(":/images/splash_testnet"); - } - else { - pixmap = QPixmap(":/images/splash"); - } + // create a bitmap according to device pixelratio + QSize splashSize(480*devicePixelRatio,320*devicePixelRatio); + pixmap = QPixmap(splashSize); + +#if QT_VERSION > 0x050100 + // change to HiDPI if it makes sense + pixmap.setDevicePixelRatio(devicePixelRatio); +#endif QPainter pixPaint(&pixmap); pixPaint.setPen(QColor(100,100,100)); + // draw a slighly radial gradient + QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio); + gradient.setColorAt(0, Qt::white); + gradient.setColorAt(1, QColor(247,247,247)); + QRect rGradient(QPoint(0,0), splashSize); + pixPaint.fillRect(rGradient, gradient); + + // draw the bitcoin icon, expected size of PNG: 1024x1024 + QRect rectIcon(QPoint(-150,-122), QSize(430,430)); + + const QSize requiredSize(1024,1024); + QPixmap icon(networkStyle->getAppIcon().pixmap(requiredSize)); + + pixPaint.drawPixmap(rectIcon, icon); + // check font size and drawing with pixPaint.setFont(QFont(font, 33*fontFactor)); QFontMetrics fm = pixPaint.fontMetrics(); @@ -63,7 +83,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, bool isTestNet) : pixPaint.setFont(QFont(font, 33*fontFactor)); fm = pixPaint.fontMetrics(); titleTextWidth = fm.width(titleText); - pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight,paddingTop,titleText); + pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop,titleText); pixPaint.setFont(QFont(font, 15*fontFactor)); @@ -74,32 +94,29 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, bool isTestNet) : pixPaint.setFont(QFont(font, 10*fontFactor)); titleVersionVSpace -= 5; } - pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText); + pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText); // draw copyright stuff pixPaint.setFont(QFont(font, 10*fontFactor)); - pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight,paddingTop+titleCopyrightVSpace,copyrightText); + pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop+titleCopyrightVSpace,copyrightText); - // draw testnet string if testnet is on - if(isTestNet) { + // draw additional text if special network + if(!titleAddText.isEmpty()) { QFont boldFont = QFont(font, 10*fontFactor); boldFont.setWeight(QFont::Bold); pixPaint.setFont(boldFont); fm = pixPaint.fontMetrics(); - int testnetAddTextWidth = fm.width(testnetAddText); - pixPaint.drawText(pixmap.width()-testnetAddTextWidth-10,15,testnetAddText); + int titleAddTextWidth = fm.width(titleAddText); + pixPaint.drawText(pixmap.width()/devicePixelRatio-titleAddTextWidth-10,15,titleAddText); } pixPaint.end(); // Set window title - if(isTestNet) - setWindowTitle(titleText + " " + testnetAddText); - else - setWindowTitle(titleText); + setWindowTitle(titleText + " " + titleAddText); // Resize window and move to center of desktop, disallow resizing - QRect r(QPoint(), pixmap.size()); + QRect r(QPoint(), QSize(pixmap.size().width()/devicePixelRatio,pixmap.size().height()/devicePixelRatio)); resize(r.size()); setFixedSize(r.size()); move(QApplication::desktop()->screenGeometry().center() - r.center()); @@ -114,6 +131,7 @@ SplashScreen::~SplashScreen() void SplashScreen::slotFinish(QWidget *mainWin) { + Q_UNUSED(mainWin); hide(); } @@ -178,6 +196,6 @@ void SplashScreen::paintEvent(QPaintEvent *event) void SplashScreen::closeEvent(QCloseEvent *event) { + StartShutdown(); // allows an "emergency" shutdown during startup event->ignore(); } - diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h index 89c21e6457..84e4556dd8 100644 --- a/src/qt/splashscreen.h +++ b/src/qt/splashscreen.h @@ -1,12 +1,14 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. -#ifndef SPLASHSCREEN_H -#define SPLASHSCREEN_H +#ifndef BITCOIN_QT_SPLASHSCREEN_H +#define BITCOIN_QT_SPLASHSCREEN_H #include <QSplashScreen> +class NetworkStyle; + /** Class for the splashscreen with information of the running client. * * @note this is intentionally not a QSplashScreen. Bitcoin Core initialization @@ -18,7 +20,7 @@ class SplashScreen : public QWidget Q_OBJECT public: - explicit SplashScreen(Qt::WindowFlags f, bool isTestNet); + explicit SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle); ~SplashScreen(); protected: @@ -44,4 +46,4 @@ private: int curAlignment; }; -#endif // SPLASHSCREEN_H +#endif // BITCOIN_QT_SPLASHSCREEN_H diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h index aeaa7d89a0..37544cdebb 100644 --- a/src/qt/test/paymentrequestdata.h +++ b/src/qt/test/paymentrequestdata.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index 5d7fe96285..70254cd75d 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,7 +7,9 @@ #include "optionsmodel.h" #include "paymentrequestdata.h" +#include "random.h" #include "util.h" +#include "utilstrencodings.h" #include <openssl/x509.h> #include <openssl/x509_vfy.h> @@ -107,6 +109,17 @@ void PaymentServerTests::paymentServerTests() r.paymentRequest.getMerchant(caStore, merchant); QCOMPARE(merchant, QString("")); + // Just get some random data big enough to trigger BIP70 DoS protection + unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1]; + GetRandBytes(randData, sizeof(randData)); + // Write data to a temp file: + QTemporaryFile tempFile; + tempFile.open(); + tempFile.write((const char*)randData, sizeof(randData)); + tempFile.close(); + // Trigger BIP70 DoS protection + QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false); + delete server; } diff --git a/src/qt/test/paymentservertests.h b/src/qt/test/paymentservertests.h index 9b6400b0d5..c98bbf0833 100644 --- a/src/qt/test/paymentservertests.h +++ b/src/qt/test/paymentservertests.h @@ -1,9 +1,9 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef PAYMENTSERVERTESTS_H -#define PAYMENTSERVERTESTS_H +#ifndef BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H +#define BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H #include "../paymentserver.h" @@ -32,4 +32,4 @@ public: SendCoinsRecipient recipient; }; -#endif // PAYMENTSERVERTESTS_H +#endif // BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index f2161c2f79..da5f074390 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/uritests.cpp b/src/qt/test/uritests.cpp index 78a7b1b9b4..8b53c0d5c7 100644 --- a/src/qt/test/uritests.cpp +++ b/src/qt/test/uritests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/uritests.h b/src/qt/test/uritests.h index 1ea6d9f075..a0b7dc6c72 100644 --- a/src/qt/test/uritests.h +++ b/src/qt/test/uritests.h @@ -1,9 +1,9 @@ -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef URITESTS_H -#define URITESTS_H +#ifndef BITCOIN_QT_TEST_URITESTS_H +#define BITCOIN_QT_TEST_URITESTS_H #include <QObject> #include <QTest> @@ -16,4 +16,4 @@ private slots: void uriTests(); }; -#endif // URITESTS_H +#endif // BITCOIN_QT_TEST_URITESTS_H diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index 74565bb6d0..0b2eb9eaf2 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "trafficgraphwidget.h" @@ -76,10 +76,12 @@ void TrafficGraphWidget::paintEvent(QPaintEvent *) int base = floor(log10(fMax)); float val = pow(10.0f, base); - const QString units = tr("KB/s"); + const QString units = tr("KB/s"); + const float yMarginText = 2.0; + // draw lines painter.setPen(axisCol); - painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax, QString("%1 %2").arg(val).arg(units)); + painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units)); for(float y = val; y < fMax; y += val) { int yy = YMARGIN + h - h * y / fMax; painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy); @@ -89,7 +91,7 @@ void TrafficGraphWidget::paintEvent(QPaintEvent *) axisCol = axisCol.darker(); val = pow(10.0f, base - 1); painter.setPen(axisCol); - painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax, QString("%1 %2").arg(val).arg(units)); + painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units)); int count = 1; for(float y = val; y < fMax; y += val, count++) { // don't overwrite lines drawn above diff --git a/src/qt/trafficgraphwidget.h b/src/qt/trafficgraphwidget.h index efab6e7fc5..4c6b17fe7e 100644 --- a/src/qt/trafficgraphwidget.h +++ b/src/qt/trafficgraphwidget.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 TRAFFICGRAPHWIDGET_H -#define TRAFFICGRAPHWIDGET_H +#ifndef BITCOIN_QT_TRAFFICGRAPHWIDGET_H +#define BITCOIN_QT_TRAFFICGRAPHWIDGET_H #include <QWidget> #include <QQueue> @@ -45,4 +45,4 @@ private: ClientModel *clientModel; }; -#endif // TRAFFICGRAPHWIDGET_H +#endif // BITCOIN_QT_TRAFFICGRAPHWIDGET_H diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 4923718341..68c275d494 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "transactiondesc.h" @@ -56,9 +56,9 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>"; int64_t nTime = wtx.GetTxTime(); - int64_t nCredit = wtx.GetCredit(ISMINE_ALL); - int64_t nDebit = wtx.GetDebit(ISMINE_ALL); - int64_t nNet = nCredit - nDebit; + CAmount nCredit = wtx.GetCredit(ISMINE_ALL); + CAmount nDebit = wtx.GetDebit(ISMINE_ALL); + CAmount nNet = nCredit - nDebit; strHTML += "<b>" + tr("Status") + ":</b> " + FormatTxStatus(wtx); int nRequests = wtx.GetRequestCount(); @@ -132,7 +132,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco // // Coinbase // - int64_t nUnmatured = 0; + CAmount nUnmatured = 0; BOOST_FOREACH(const CTxOut& txout, wtx.vout) nUnmatured += wallet->GetCredit(txout, ISMINE_ALL); strHTML += "<b>" + tr("Credit") + ":</b> "; @@ -206,13 +206,13 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco if (fAllToMe) { // Payment to self - int64_t nChange = wtx.GetChange(); - int64_t nValue = nCredit - nChange; + CAmount nChange = wtx.GetChange(); + CAmount nValue = nCredit - nChange; strHTML += "<b>" + tr("Total debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -nValue) + "<br>"; strHTML += "<b>" + tr("Total credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, nValue) + "<br>"; } - int64_t nTxFee = nDebit - wtx.GetValueOut(); + CAmount nTxFee = nDebit - wtx.GetValueOut(); if (nTxFee > 0) strHTML += "<b>" + tr("Transaction fee") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -nTxFee) + "<br>"; } diff --git a/src/qt/transactiondesc.h b/src/qt/transactiondesc.h index 4bd4293210..5467348ee9 100644 --- a/src/qt/transactiondesc.h +++ b/src/qt/transactiondesc.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 TRANSACTIONDESC_H -#define TRANSACTIONDESC_H +#ifndef BITCOIN_QT_TRANSACTIONDESC_H +#define BITCOIN_QT_TRANSACTIONDESC_H #include <QObject> #include <QString> @@ -28,4 +28,4 @@ private: static QString FormatTxStatus(const CWalletTx& wtx); }; -#endif // TRANSACTIONDESC_H +#endif // BITCOIN_QT_TRANSACTIONDESC_H diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp index 5ca575fdd4..fadaa98f4a 100644 --- a/src/qt/transactiondescdialog.cpp +++ b/src/qt/transactiondescdialog.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "transactiondescdialog.h" diff --git a/src/qt/transactiondescdialog.h b/src/qt/transactiondescdialog.h index d4719975b2..54374e359d 100644 --- a/src/qt/transactiondescdialog.h +++ b/src/qt/transactiondescdialog.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 TRANSACTIONDESCDIALOG_H -#define TRANSACTIONDESCDIALOG_H +#ifndef BITCOIN_QT_TRANSACTIONDESCDIALOG_H +#define BITCOIN_QT_TRANSACTIONDESCDIALOG_H #include <QDialog> @@ -28,4 +28,4 @@ private: Ui::TransactionDescDialog *ui; }; -#endif // TRANSACTIONDESCDIALOG_H +#endif // BITCOIN_QT_TRANSACTIONDESCDIALOG_H diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp index 6ab029173b..7981eb7c91 100644 --- a/src/qt/transactionfilterproxy.cpp +++ b/src/qt/transactionfilterproxy.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "transactionfilterproxy.h" @@ -78,7 +78,7 @@ void TransactionFilterProxy::setTypeFilter(quint32 modes) invalidateFilter(); } -void TransactionFilterProxy::setMinAmount(qint64 minimum) +void TransactionFilterProxy::setMinAmount(const CAmount& minimum) { this->minAmount = minimum; invalidateFilter(); diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h index f408317b53..acea9a1e3b 100644 --- a/src/qt/transactionfilterproxy.h +++ b/src/qt/transactionfilterproxy.h @@ -1,9 +1,11 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 TRANSACTIONFILTERPROXY_H -#define TRANSACTIONFILTERPROXY_H +#ifndef BITCOIN_QT_TRANSACTIONFILTERPROXY_H +#define BITCOIN_QT_TRANSACTIONFILTERPROXY_H + +#include "amount.h" #include <QDateTime> #include <QSortFilterProxyModel> @@ -38,7 +40,7 @@ public: @note Type filter takes a bit field created with TYPE() or ALL_TYPES */ void setTypeFilter(quint32 modes); - void setMinAmount(qint64 minimum); + void setMinAmount(const CAmount& minimum); void setWatchOnlyFilter(WatchOnlyFilter filter); /** Set maximum number of rows returned, -1 if unlimited. */ @@ -58,9 +60,9 @@ private: QString addrPrefix; quint32 typeFilter; WatchOnlyFilter watchOnlyFilter; - qint64 minAmount; + CAmount minAmount; int limitRows; bool showInactive; }; -#endif // TRANSACTIONFILTERPROXY_H +#endif // BITCOIN_QT_TRANSACTIONFILTERPROXY_H diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 20c1449c92..fea436806a 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "transactionrecord.h" @@ -32,9 +32,9 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * { QList<TransactionRecord> parts; int64_t nTime = wtx.GetTxTime(); - int64_t nCredit = wtx.GetCredit(true); - int64_t nDebit = wtx.GetDebit(ISMINE_ALL); - int64_t nNet = nCredit - nDebit; + CAmount nCredit = wtx.GetCredit(ISMINE_ALL); + CAmount nDebit = wtx.GetDebit(ISMINE_ALL); + CAmount nNet = nCredit - nDebit; uint256 hash = wtx.GetHash(); std::map<std::string, std::string> mapValue = wtx.mapValue; @@ -97,7 +97,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * if (fAllFromMe && fAllToMe) { // Payment to self - int64_t nChange = wtx.GetChange(); + CAmount nChange = wtx.GetChange(); parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "", -(nDebit - nChange), nCredit - nChange)); @@ -108,7 +108,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * // // Debit // - int64_t nTxFee = nDebit - wtx.GetValueOut(); + CAmount nTxFee = nDebit - wtx.GetValueOut(); for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) { @@ -138,7 +138,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * sub.address = mapValue["to"]; } - int64_t nValue = txout.nValue; + CAmount nValue = txout.nValue; /* Add fee to first output */ if (nTxFee > 0) { diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index 626b7654c6..a5bc375717 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -1,10 +1,11 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 TRANSACTIONRECORD_H -#define TRANSACTIONRECORD_H +#ifndef BITCOIN_QT_TRANSACTIONRECORD_H +#define BITCOIN_QT_TRANSACTIONRECORD_H +#include "amount.h" #include "uint256.h" #include <QList> @@ -94,7 +95,7 @@ public: TransactionRecord(uint256 hash, qint64 time, Type type, const std::string &address, - qint64 debit, qint64 credit): + const CAmount& debit, const CAmount& credit): hash(hash), time(time), type(type), address(address), debit(debit), credit(credit), idx(0) { @@ -111,8 +112,8 @@ public: qint64 time; Type type; std::string address; - qint64 debit; - qint64 credit; + CAmount debit; + CAmount credit; /**@}*/ /** Subtransaction index, for sort key */ @@ -139,4 +140,4 @@ public: bool statusUpdateNeeded(); }; -#endif // TRANSACTIONRECORD_H +#endif // BITCOIN_QT_TRANSACTIONRECORD_H diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 2b869b4ea5..6771e77180 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "transactiontablemodel.h" @@ -8,6 +8,7 @@ #include "guiconstants.h" #include "guiutil.h" #include "optionsmodel.h" +#include "scicon.h" #include "transactiondesc.h" #include "transactionrecord.h" #include "walletmodel.h" @@ -91,87 +92,80 @@ public: Call with transaction that was added, removed or changed. */ - void updateWallet(const uint256 &hash, int status) + void updateWallet(const uint256 &hash, int status, bool showTransaction) { qDebug() << "TransactionTablePriv::updateWallet : " + QString::fromStdString(hash.ToString()) + " " + QString::number(status); - { - LOCK2(cs_main, wallet->cs_wallet); - // Find transaction in wallet - std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash); - bool inWallet = mi != wallet->mapWallet.end(); + // Find bounds of this transaction in model + QList<TransactionRecord>::iterator lower = qLowerBound( + cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); + QList<TransactionRecord>::iterator upper = qUpperBound( + cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); + int lowerIndex = (lower - cachedWallet.begin()); + int upperIndex = (upper - cachedWallet.begin()); + bool inModel = (lower != upper); - // Find bounds of this transaction in model - QList<TransactionRecord>::iterator lower = qLowerBound( - cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); - QList<TransactionRecord>::iterator upper = qUpperBound( - cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan()); - int lowerIndex = (lower - cachedWallet.begin()); - int upperIndex = (upper - cachedWallet.begin()); - bool inModel = (lower != upper); + if(status == CT_UPDATED) + { + if(showTransaction && !inModel) + status = CT_NEW; /* Not in model, but want to show, treat as new */ + if(!showTransaction && inModel) + status = CT_DELETED; /* In model, but want to hide, treat as deleted */ + } - // Determine whether to show transaction or not - bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second)); + qDebug() << " inModel=" + QString::number(inModel) + + " Index=" + QString::number(lowerIndex) + "-" + QString::number(upperIndex) + + " showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status); - if(status == CT_UPDATED) + switch(status) + { + case CT_NEW: + if(inModel) { - if(showTransaction && !inModel) - status = CT_NEW; /* Not in model, but want to show, treat as new */ - if(!showTransaction && inModel) - status = CT_DELETED; /* In model, but want to hide, treat as deleted */ + qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model"; + break; } - - qDebug() << " inWallet=" + QString::number(inWallet) + " inModel=" + QString::number(inModel) + - " Index=" + QString::number(lowerIndex) + "-" + QString::number(upperIndex) + - " showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status); - - switch(status) + if(showTransaction) { - case CT_NEW: - if(inModel) - { - qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model"; - break; - } - if(!inWallet) + LOCK2(cs_main, wallet->cs_wallet); + // Find transaction in wallet + std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash); + if(mi == wallet->mapWallet.end()) { qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet"; break; } - if(showTransaction) + // Added -- insert at the right position + QList<TransactionRecord> toInsert = + TransactionRecord::decomposeTransaction(wallet, mi->second); + if(!toInsert.isEmpty()) /* only if something to insert */ { - // Added -- insert at the right position - QList<TransactionRecord> toInsert = - TransactionRecord::decomposeTransaction(wallet, mi->second); - if(!toInsert.isEmpty()) /* only if something to insert */ + parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1); + int insert_idx = lowerIndex; + foreach(const TransactionRecord &rec, toInsert) { - parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1); - int insert_idx = lowerIndex; - foreach(const TransactionRecord &rec, toInsert) - { - cachedWallet.insert(insert_idx, rec); - insert_idx += 1; - } - parent->endInsertRows(); + cachedWallet.insert(insert_idx, rec); + insert_idx += 1; } + parent->endInsertRows(); } - break; - case CT_DELETED: - if(!inModel) - { - qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_DELETED, but transaction is not in model"; - break; - } - // Removed -- remove entire transaction from table - parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1); - cachedWallet.erase(lower, upper); - parent->endRemoveRows(); - break; - case CT_UPDATED: - // Miscellaneous updates -- nothing to do, status update will take care of this, and is only computed for - // visible transactions. + } + break; + case CT_DELETED: + if(!inModel) + { + qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_DELETED, but transaction is not in model"; break; } + // Removed -- remove entire transaction from table + parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1); + cachedWallet.erase(lower, upper); + parent->endRemoveRows(); + break; + case CT_UPDATED: + // Miscellaneous updates -- nothing to do, status update will take care of this, and is only computed for + // visible transactions. + break; } } @@ -230,16 +224,20 @@ TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *paren QAbstractTableModel(parent), wallet(wallet), walletModel(parent), - priv(new TransactionTablePriv(wallet, this)) + priv(new TransactionTablePriv(wallet, this)), + fProcessingQueuedTransactions(false) { columns << QString() << QString() << tr("Date") << tr("Type") << tr("Address") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit()); priv->refreshWallet(); connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + + subscribeToCoreSignals(); } TransactionTableModel::~TransactionTableModel() { + unsubscribeFromCoreSignals(); delete priv; } @@ -250,12 +248,12 @@ void TransactionTableModel::updateAmountColumnTitle() emit headerDataChanged(Qt::Horizontal,Amount,Amount); } -void TransactionTableModel::updateTransaction(const QString &hash, int status) +void TransactionTableModel::updateTransaction(const QString &hash, int status, bool showTransaction) { uint256 updated; updated.SetHex(hash.toStdString()); - priv->updateWallet(updated, status); + priv->updateWallet(updated, status, showTransaction); } void TransactionTableModel::updateConfirmations() @@ -507,7 +505,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const switch(role) { - case Qt::DecorationRole: + case RawDecorationRole: switch(index.column()) { case Status: @@ -518,6 +516,11 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const return txAddressDecoration(rec); } break; + case Qt::DecorationRole: + { + QIcon icon = qvariant_cast<QIcon>(index.data(RawDecorationRole)); + return TextColorIcon(icon); + } case Qt::DisplayRole: switch(index.column()) { @@ -546,7 +549,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case ToAddress: return formatTxToAddress(rec, true); case Amount: - return rec->credit + rec->debit; + return qint64(rec->credit + rec->debit); } break; case Qt::ToolTipRole: @@ -583,7 +586,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case LabelRole: return walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address)); case AmountRole: - return rec->credit + rec->debit; + return qint64(rec->credit + rec->debit); case TxIDRole: return rec->getTxID(); case TxHashRole: @@ -649,3 +652,82 @@ void TransactionTableModel::updateDisplayUnit() updateAmountColumnTitle(); emit dataChanged(index(0, Amount), index(priv->size()-1, Amount)); } + +// queue notifications to show a non freezing progress dialog e.g. for rescan +struct TransactionNotification +{ +public: + TransactionNotification() {} + TransactionNotification(uint256 hash, ChangeType status, bool showTransaction): + hash(hash), status(status), showTransaction(showTransaction) {} + + void invoke(QObject *ttm) + { + QString strHash = QString::fromStdString(hash.GetHex()); + qDebug() << "NotifyTransactionChanged : " + strHash + " status= " + QString::number(status); + QMetaObject::invokeMethod(ttm, "updateTransaction", Qt::QueuedConnection, + Q_ARG(QString, strHash), + Q_ARG(int, status), + Q_ARG(bool, showTransaction)); + } +private: + uint256 hash; + ChangeType status; + bool showTransaction; +}; + +static bool fQueueNotifications = false; +static std::vector< TransactionNotification > vQueueNotifications; + +static void NotifyTransactionChanged(TransactionTableModel *ttm, CWallet *wallet, const uint256 &hash, ChangeType status) +{ + // Find transaction in wallet + std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash); + // Determine whether to show transaction or not (determine this here so that no relocking is needed in GUI thread) + bool inWallet = mi != wallet->mapWallet.end(); + bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second)); + + TransactionNotification notification(hash, status, showTransaction); + + if (fQueueNotifications) + { + vQueueNotifications.push_back(notification); + return; + } + notification.invoke(ttm); +} + +static void ShowProgress(TransactionTableModel *ttm, const std::string &title, int nProgress) +{ + if (nProgress == 0) + fQueueNotifications = true; + + if (nProgress == 100) + { + fQueueNotifications = false; + if (vQueueNotifications.size() > 10) // prevent balloon spam, show maximum 10 balloons + QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true)); + for (unsigned int i = 0; i < vQueueNotifications.size(); ++i) + { + if (vQueueNotifications.size() - i <= 10) + QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false)); + + vQueueNotifications[i].invoke(ttm); + } + std::vector<TransactionNotification >().swap(vQueueNotifications); // clear + } +} + +void TransactionTableModel::subscribeToCoreSignals() +{ + // Connect signals to wallet + wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); + wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2)); +} + +void TransactionTableModel::unsubscribeFromCoreSignals() +{ + // Disconnect signals from wallet + wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); + wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2)); +} diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 413f3f9bf1..30a15df9e6 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 TRANSACTIONTABLEMODEL_H -#define TRANSACTIONTABLEMODEL_H +#ifndef BITCOIN_QT_TRANSACTIONTABLEMODEL_H +#define BITCOIN_QT_TRANSACTIONTABLEMODEL_H #include "bitcoinunits.h" @@ -64,7 +64,9 @@ public: /** Formatted amount, without brackets when unconfirmed */ FormattedAmountRole, /** Transaction status (TransactionRecord::Status) */ - StatusRole + StatusRole, + /** Unprocessed icon */ + RawDecorationRole, }; int rowCount(const QModelIndex &parent) const; @@ -72,12 +74,17 @@ public: 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 = QModelIndex()) const; + bool processingQueuedTransactions() { return fProcessingQueuedTransactions; } private: CWallet* wallet; WalletModel *walletModel; QStringList columns; TransactionTablePriv *priv; + bool fProcessingQueuedTransactions; + + void subscribeToCoreSignals(); + void unsubscribeFromCoreSignals(); QString lookupAddress(const std::string &address, bool tooltip) const; QVariant addressColor(const TransactionRecord *wtx) const; @@ -92,13 +99,16 @@ private: QVariant txAddressDecoration(const TransactionRecord *wtx) const; public slots: - void updateTransaction(const QString &hash, int status); + /* New transaction, or transaction changed status */ + void updateTransaction(const QString &hash, int status, bool showTransaction); void updateConfirmations(); void updateDisplayUnit(); /** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */ void updateAmountColumnTitle(); + /* Needed to update fProcessingQueuedTransactions through a QueuedConnection */ + void setProcessingQueuedTransactions(bool value) { fProcessingQueuedTransactions = value; } friend class TransactionTablePriv; }; -#endif // TRANSACTIONTABLEMODEL_H +#endif // BITCOIN_QT_TRANSACTIONTABLEMODEL_H diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index a7ba100cd2..526940632e 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "transactionview.h" @@ -10,6 +10,7 @@ #include "editaddressdialog.h" #include "guiutil.h" #include "optionsmodel.h" +#include "scicon.h" #include "transactiondescdialog.h" #include "transactionfilterproxy.h" #include "transactionrecord.h" @@ -54,8 +55,8 @@ TransactionView::TransactionView(QWidget *parent) : watchOnlyWidget = new QComboBox(this); watchOnlyWidget->setFixedWidth(24); watchOnlyWidget->addItem("", TransactionFilterProxy::WatchOnlyFilter_All); - watchOnlyWidget->addItem(QIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes); - watchOnlyWidget->addItem(QIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No); + watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes); + watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No); hlayout->addWidget(watchOnlyWidget); dateWidget = new QComboBox(this); @@ -304,7 +305,7 @@ void TransactionView::changedAmount(const QString &amount) { if(!transactionProxyModel) return; - qint64 amount_parsed = 0; + CAmount amount_parsed = 0; if(BitcoinUnits::parse(model->getOptionsModel()->getDisplayUnit(), amount, &amount_parsed)) { transactionProxyModel->setMinAmount(amount_parsed); diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index b249e00411..2858982f09 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 TRANSACTIONVIEW_H -#define TRANSACTIONVIEW_H +#ifndef BITCOIN_QT_TRANSACTIONVIEW_H +#define BITCOIN_QT_TRANSACTIONVIEW_H #include "guiutil.h" @@ -112,4 +112,4 @@ public slots: }; -#endif // TRANSACTIONVIEW_H +#endif // BITCOIN_QT_TRANSACTIONVIEW_H diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 84f88dff5a..e6cec8173e 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "utilitydialog.h" @@ -10,8 +10,8 @@ #include "clientmodel.h" #include "guiutil.h" +#include "clientversion.h" #include "init.h" -#include "version.h" #include <stdio.h> diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index ae5045cca9..288b985f13 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. -#ifndef UTILITYDIALOG_H -#define UTILITYDIALOG_H +#ifndef BITCOIN_QT_UTILITYDIALOG_H +#define BITCOIN_QT_UTILITYDIALOG_H #include <QDialog> #include <QObject> @@ -49,4 +49,4 @@ protected: void closeEvent(QCloseEvent *event); }; -#endif // UTILITYDIALOG_H +#endif // BITCOIN_QT_UTILITYDIALOG_H diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index fead022928..892947bf3a 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "walletframe.h" diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index f1830a0d6b..eea97defc9 100644 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 WALLETFRAME_H -#define WALLETFRAME_H +#ifndef BITCOIN_QT_WALLETFRAME_H +#define BITCOIN_QT_WALLETFRAME_H #include <QFrame> #include <QMap> @@ -77,4 +77,4 @@ public slots: void usedReceivingAddresses(); }; -#endif // WALLETFRAME_H +#endif // BITCOIN_QT_WALLETFRAME_H diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index ed90914ba7..6006a7bd7b 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "walletmodel.h" @@ -34,7 +34,6 @@ WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *p cachedEncryptionStatus(Unencrypted), cachedNumBlocks(0) { - fProcessingQueuedTransactions = false; fHaveWatchOnly = wallet->HaveWatchOnly(); fForceCheckBalanceChanged = false; @@ -55,11 +54,11 @@ WalletModel::~WalletModel() unsubscribeFromCoreSignals(); } -qint64 WalletModel::getBalance(const CCoinControl *coinControl) const +CAmount WalletModel::getBalance(const CCoinControl *coinControl) const { if (coinControl) { - qint64 nBalance = 0; + CAmount nBalance = 0; std::vector<COutput> vCoins; wallet->AvailableCoins(vCoins, true, coinControl); BOOST_FOREACH(const COutput& out, vCoins) @@ -72,12 +71,12 @@ qint64 WalletModel::getBalance(const CCoinControl *coinControl) const return wallet->GetBalance(); } -qint64 WalletModel::getUnconfirmedBalance() const +CAmount WalletModel::getUnconfirmedBalance() const { return wallet->GetUnconfirmedBalance(); } -qint64 WalletModel::getImmatureBalance() const +CAmount WalletModel::getImmatureBalance() const { return wallet->GetImmatureBalance(); } @@ -87,17 +86,17 @@ bool WalletModel::haveWatchOnly() const return fHaveWatchOnly; } -qint64 WalletModel::getWatchBalance() const +CAmount WalletModel::getWatchBalance() const { return wallet->GetWatchOnlyBalance(); } -qint64 WalletModel::getWatchUnconfirmedBalance() const +CAmount WalletModel::getWatchUnconfirmedBalance() const { return wallet->GetUnconfirmedWatchOnlyBalance(); } -qint64 WalletModel::getWatchImmatureBalance() const +CAmount WalletModel::getWatchImmatureBalance() const { return wallet->GetImmatureWatchOnlyBalance(); } @@ -137,12 +136,12 @@ void WalletModel::pollBalanceChanged() void WalletModel::checkBalanceChanged() { - qint64 newBalance = getBalance(); - qint64 newUnconfirmedBalance = getUnconfirmedBalance(); - qint64 newImmatureBalance = getImmatureBalance(); - qint64 newWatchOnlyBalance = 0; - qint64 newWatchUnconfBalance = 0; - qint64 newWatchImmatureBalance = 0; + CAmount newBalance = getBalance(); + CAmount newUnconfirmedBalance = getUnconfirmedBalance(); + CAmount newImmatureBalance = getImmatureBalance(); + CAmount newWatchOnlyBalance = 0; + CAmount newWatchUnconfBalance = 0; + CAmount newWatchImmatureBalance = 0; if (haveWatchOnly()) { newWatchOnlyBalance = getWatchBalance(); @@ -164,11 +163,8 @@ void WalletModel::checkBalanceChanged() } } -void WalletModel::updateTransaction(const QString &hash, int status) +void WalletModel::updateTransaction() { - if(transactionTableModel) - transactionTableModel->updateTransaction(hash, status); - // Balance and number of transactions might have changed fForceCheckBalanceChanged = true; } @@ -194,9 +190,9 @@ bool WalletModel::validateAddress(const QString &address) WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl) { - qint64 total = 0; + CAmount total = 0; QList<SendCoinsRecipient> recipients = transaction.getRecipients(); - std::vector<std::pair<CScript, int64_t> > vecSend; + std::vector<std::pair<CScript, CAmount> > vecSend; if(recipients.empty()) { @@ -211,7 +207,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact { if (rcp.paymentRequest.IsInitialized()) { // PaymentRequest... - int64_t subtotal = 0; + CAmount subtotal = 0; const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); for (int i = 0; i < details.outputs_size(); i++) { @@ -220,7 +216,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact subtotal += out.amount(); const unsigned char* scriptStr = (const unsigned char*)out.script().data(); CScript scriptPubKey(scriptStr, scriptStr+out.script().size()); - vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, out.amount())); + vecSend.push_back(std::pair<CScript, CAmount>(scriptPubKey, out.amount())); } if (subtotal <= 0) { @@ -242,7 +238,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact ++nAddresses; CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); - vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, rcp.amount)); + vecSend.push_back(std::pair<CScript, CAmount>(scriptPubKey, rcp.amount)); total += rcp.amount; } @@ -252,7 +248,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact return DuplicateAddress; } - qint64 nBalance = getBalance(coinControl); + CAmount nBalance = getBalance(coinControl); if(total > nBalance) { @@ -263,7 +259,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact LOCK2(cs_main, wallet->cs_wallet); transaction.newPossibleKeyChange(wallet); - int64_t nFeeRequired = 0; + CAmount nFeeRequired = 0; std::string strFailReason; CWalletTx *newTx = transaction.getTransaction(); @@ -281,6 +277,10 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } + + // reject insane fee > 0.1 bitcoin + if (nFeeRequired > 10000000) + return InsaneFee; } return SendCoinsReturn(OK); @@ -455,45 +455,16 @@ static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, Q_ARG(int, status)); } -// queue notifications to show a non freezing progress dialog e.g. for rescan -static bool fQueueNotifications = false; -static std::vector<std::pair<uint256, ChangeType> > vQueueNotifications; static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status) { - if (fQueueNotifications) - { - vQueueNotifications.push_back(make_pair(hash, status)); - return; - } - - QString strHash = QString::fromStdString(hash.GetHex()); - - qDebug() << "NotifyTransactionChanged : " + strHash + " status= " + QString::number(status); - QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection, - Q_ARG(QString, strHash), - Q_ARG(int, status)); + Q_UNUSED(wallet); + Q_UNUSED(hash); + Q_UNUSED(status); + QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection); } static void ShowProgress(WalletModel *walletmodel, const std::string &title, int nProgress) { - if (nProgress == 0) - fQueueNotifications = true; - - if (nProgress == 100) - { - fQueueNotifications = false; - if (vQueueNotifications.size() > 10) // prevent balloon spam, show maximum 10 balloons - QMetaObject::invokeMethod(walletmodel, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true)); - for (unsigned int i = 0; i < vQueueNotifications.size(); ++i) - { - if (vQueueNotifications.size() - i <= 10) - QMetaObject::invokeMethod(walletmodel, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false)); - - NotifyTransactionChanged(walletmodel, NULL, vQueueNotifications[i].first, vQueueNotifications[i].second); - } - std::vector<std::pair<uint256, ChangeType> >().swap(vQueueNotifications); // clear - } - // emits signal "showProgress" QMetaObject::invokeMethod(walletmodel, "showProgress", Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString(title)), @@ -605,7 +576,8 @@ void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins) int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain(); if (nDepth < 0) continue; COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true); - vCoins.push_back(out); + if (outpoint.n < out.tx->vout.size() && wallet->IsMine(out.tx->vout[outpoint.n]) == ISMINE_SPENDABLE) + vCoins.push_back(out); } BOOST_FOREACH(const COutput& out, vCoins) diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 111ae2178c..d8df25f660 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. -#ifndef WALLETMODEL_H -#define WALLETMODEL_H +#ifndef BITCOIN_QT_WALLETMODEL_H +#define BITCOIN_QT_WALLETMODEL_H #include "paymentrequestplus.h" #include "walletmodeltransaction.h" @@ -37,7 +37,7 @@ class SendCoinsRecipient { public: explicit SendCoinsRecipient() : amount(0), nVersion(SendCoinsRecipient::CURRENT_VERSION) { } - explicit SendCoinsRecipient(const QString &addr, const QString &label, quint64 amount, const QString &message): + explicit SendCoinsRecipient(const QString &addr, const QString &label, const CAmount& amount, const QString &message): address(addr), label(label), amount(amount), message(message), nVersion(SendCoinsRecipient::CURRENT_VERSION) {} // If from an insecure payment request, this is used for storing @@ -47,7 +47,7 @@ public: // Todo: This is a hack, should be replaced with a cleaner solution! QString address; QString label; - qint64 amount; + CAmount amount; // If from a payment request, this is used for storing the memo QString message; @@ -110,7 +110,8 @@ public: AmountWithFeeExceedsBalance, DuplicateAddress, TransactionCreationFailed, // Error returned when wallet is still locked - TransactionCommitFailed + TransactionCommitFailed, + InsaneFee }; enum EncryptionStatus @@ -125,15 +126,14 @@ public: TransactionTableModel *getTransactionTableModel(); RecentRequestsTableModel *getRecentRequestsTableModel(); - qint64 getBalance(const CCoinControl *coinControl = NULL) const; - qint64 getUnconfirmedBalance() const; - qint64 getImmatureBalance() const; + CAmount getBalance(const CCoinControl *coinControl = NULL) const; + CAmount getUnconfirmedBalance() const; + CAmount getImmatureBalance() const; bool haveWatchOnly() const; - qint64 getWatchBalance() const; - qint64 getWatchUnconfirmedBalance() const; - qint64 getWatchImmatureBalance() const; + CAmount getWatchBalance() const; + CAmount getWatchUnconfirmedBalance() const; + CAmount getWatchImmatureBalance() const; EncryptionStatus getEncryptionStatus() const; - bool processingQueuedTransactions() { return fProcessingQueuedTransactions; } // Check address for validity bool validateAddress(const QString &address); @@ -197,7 +197,6 @@ public: private: CWallet *wallet; - bool fProcessingQueuedTransactions; bool fHaveWatchOnly; bool fForceCheckBalanceChanged; @@ -210,12 +209,12 @@ private: RecentRequestsTableModel *recentRequestsTableModel; // Cache some values to be able to detect changes - qint64 cachedBalance; - qint64 cachedUnconfirmedBalance; - qint64 cachedImmatureBalance; - qint64 cachedWatchOnlyBalance; - qint64 cachedWatchUnconfBalance; - qint64 cachedWatchImmatureBalance; + CAmount cachedBalance; + CAmount cachedUnconfirmedBalance; + CAmount cachedImmatureBalance; + CAmount cachedWatchOnlyBalance; + CAmount cachedWatchUnconfBalance; + CAmount cachedWatchImmatureBalance; EncryptionStatus cachedEncryptionStatus; int cachedNumBlocks; @@ -227,8 +226,8 @@ private: signals: // Signal that balance in wallet changed - void balanceChanged(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance, - qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance); + void balanceChanged(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, + const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance); // Encryption status of wallet changed void encryptionStatusChanged(int status); @@ -254,15 +253,13 @@ public slots: /* Wallet status might have changed */ void updateStatus(); /* New transaction, or transaction changed status */ - void updateTransaction(const QString &hash, int status); + void updateTransaction(); /* New, updated or removed address book entry */ void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status); /* Watch-only added */ void updateWatchOnlyFlag(bool fHaveWatchonly); /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */ void pollBalanceChanged(); - /* Needed to update fProcessingQueuedTransactions through a QueuedConnection */ - void setProcessingQueuedTransactions(bool value) { fProcessingQueuedTransactions = value; } }; -#endif // WALLETMODEL_H +#endif // BITCOIN_QT_WALLETMODEL_H diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 943f13e208..8f32e46148 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "walletmodeltransaction.h" @@ -31,19 +31,24 @@ CWalletTx *WalletModelTransaction::getTransaction() return walletTransaction; } -qint64 WalletModelTransaction::getTransactionFee() +unsigned int WalletModelTransaction::getTransactionSize() +{ + return (!walletTransaction ? 0 : (::GetSerializeSize(*(CTransaction*)walletTransaction, SER_NETWORK, PROTOCOL_VERSION))); +} + +CAmount WalletModelTransaction::getTransactionFee() { return fee; } -void WalletModelTransaction::setTransactionFee(qint64 newFee) +void WalletModelTransaction::setTransactionFee(const CAmount& newFee) { fee = newFee; } -qint64 WalletModelTransaction::getTotalTransactionAmount() +CAmount WalletModelTransaction::getTotalTransactionAmount() { - qint64 totalTransactionAmount = 0; + CAmount totalTransactionAmount = 0; foreach(const SendCoinsRecipient &rcp, recipients) { totalTransactionAmount += rcp.amount; diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h index b7e85bcd11..b6bb6d67f6 100644 --- a/src/qt/walletmodeltransaction.h +++ b/src/qt/walletmodeltransaction.h @@ -1,9 +1,9 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 WALLETMODELTRANSACTION_H -#define WALLETMODELTRANSACTION_H +#ifndef BITCOIN_QT_WALLETMODELTRANSACTION_H +#define BITCOIN_QT_WALLETMODELTRANSACTION_H #include "walletmodel.h" @@ -25,11 +25,12 @@ public: QList<SendCoinsRecipient> getRecipients(); CWalletTx *getTransaction(); + unsigned int getTransactionSize(); - void setTransactionFee(qint64 newFee); - qint64 getTransactionFee(); + void setTransactionFee(const CAmount& newFee); + CAmount getTransactionFee(); - qint64 getTotalTransactionAmount(); + CAmount getTotalTransactionAmount(); void newPossibleKeyChange(CWallet *wallet); CReserveKey *getPossibleKeyChange(); @@ -38,7 +39,7 @@ private: const QList<SendCoinsRecipient> recipients; CWalletTx *walletTransaction; CReserveKey *keyChange; - qint64 fee; + CAmount fee; }; -#endif // WALLETMODELTRANSACTION_H +#endif // BITCOIN_QT_WALLETMODELTRANSACTION_H diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index b40ddc0a2f..9d6a060194 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "walletview.h" @@ -12,6 +12,7 @@ #include "optionsmodel.h" #include "overviewpage.h" #include "receivecoinsdialog.h" +#include "scicon.h" #include "sendcoinsdialog.h" #include "signverifymessagedialog.h" #include "transactiontablemodel.h" @@ -44,7 +45,7 @@ WalletView::WalletView(QWidget *parent): 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(QIcon(":/icons/export")); + exportButton->setIcon(SingleColorIcon(":/icons/export")); #endif hbox_buttons->addStretch(); hbox_buttons->addWidget(exportButton); @@ -92,7 +93,7 @@ void WalletView::setBitcoinGUI(BitcoinGUI *gui) connect(this, SIGNAL(encryptionStatusChanged(int)), gui, SLOT(setEncryptionStatus(int))); // Pass through transaction notifications - connect(this, SIGNAL(incomingTransaction(QString,int,qint64,QString,QString)), gui, SLOT(incomingTransaction(QString,int,qint64,QString,QString))); + connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString))); } } @@ -101,6 +102,7 @@ void WalletView::setClientModel(ClientModel *clientModel) this->clientModel = clientModel; overviewPage->setClientModel(clientModel); + sendCoinsPage->setClientModel(clientModel); } void WalletView::setWalletModel(WalletModel *walletModel) @@ -137,10 +139,12 @@ void WalletView::setWalletModel(WalletModel *walletModel) void WalletView::processNewTransaction(const QModelIndex& parent, int start, int /*end*/) { // Prevent balloon-spam when initial block download is in progress - if (!walletModel || walletModel->processingQueuedTransactions() || !clientModel || clientModel->inInitialBlockDownload()) + if (!walletModel || !clientModel || clientModel->inInitialBlockDownload()) return; TransactionTableModel *ttm = walletModel->getTransactionTableModel(); + if (!ttm || ttm->processingQueuedTransactions()) + return; QString date = ttm->index(start, TransactionTableModel::Date, parent).data().toString(); qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong(); diff --git a/src/qt/walletview.h b/src/qt/walletview.h index 9cfa8d6760..f3d14c065c 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -1,9 +1,11 @@ -// Copyright (c) 2011-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 WALLETVIEW_H -#define WALLETVIEW_H +#ifndef BITCOIN_QT_WALLETVIEW_H +#define BITCOIN_QT_WALLETVIEW_H + +#include "amount.h" #include <QStackedWidget> @@ -111,7 +113,7 @@ signals: /** Encryption status of wallet changed */ void encryptionStatusChanged(int status); /** Notify that a new transaction appeared */ - void incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address); + void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address); }; -#endif // WALLETVIEW_H +#endif // BITCOIN_QT_WALLETVIEW_H diff --git a/src/qt/winshutdownmonitor.cpp b/src/qt/winshutdownmonitor.cpp index a06f42f66e..1bc4f77959 100644 --- a/src/qt/winshutdownmonitor.cpp +++ b/src/qt/winshutdownmonitor.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "winshutdownmonitor.h" diff --git a/src/qt/winshutdownmonitor.h b/src/qt/winshutdownmonitor.h index 4c76d2c816..0bed55a2c6 100644 --- a/src/qt/winshutdownmonitor.h +++ b/src/qt/winshutdownmonitor.h @@ -1,9 +1,9 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef WINSHUTDOWNMONITOR_H -#define WINSHUTDOWNMONITOR_H +#ifndef BITCOIN_QT_WINSHUTDOWNMONITOR_H +#define BITCOIN_QT_WINSHUTDOWNMONITOR_H #ifdef WIN32 #include <QByteArray> @@ -26,4 +26,4 @@ public: #endif #endif -#endif // WINSHUTDOWNMONITOR_H +#endif // BITCOIN_QT_WINSHUTDOWNMONITOR_H diff --git a/src/random.cpp b/src/random.cpp index 998e7dfb08..663456e962 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "random.h" @@ -82,13 +82,12 @@ void RandAddSeedPerfmon() #endif } -bool GetRandBytes(unsigned char* buf, int num) +void GetRandBytes(unsigned char* buf, int num) { if (RAND_bytes(buf, num) != 1) { LogPrintf("%s: OpenSSL RAND_bytes() failed with error: %s\n", __func__, ERR_error_string(ERR_get_error(), NULL)); - return false; + assert(false); } - return true; } uint64_t GetRand(uint64_t nMax) diff --git a/src/random.h b/src/random.h index 161ebe8986..1a2d3e8ee2 100644 --- a/src/random.h +++ b/src/random.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_RANDOM_H @@ -19,14 +19,14 @@ void RandAddSeedPerfmon(); /** * Functions to gather random data via the OpenSSL PRNG */ -bool GetRandBytes(unsigned char* buf, int num); +void GetRandBytes(unsigned char* buf, int num); uint64_t GetRand(uint64_t nMax); int GetRandInt(int nMax); uint256 GetRandHash(); /** * Seed insecure_rand using the random pool. - * @param Deterministic Use a determinstic seed + * @param Deterministic Use a deterministic seed */ void seed_insecure_rand(bool fDeterministic = false); diff --git a/src/rest.cpp b/src/rest.cpp new file mode 100644 index 0000000000..4702f0d707 --- /dev/null +++ b/src/rest.cpp @@ -0,0 +1,317 @@ +// 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. + +#include "primitives/block.h" +#include "primitives/transaction.h" +#include "main.h" +#include "rpcserver.h" +#include "streams.h" +#include "sync.h" +#include "utilstrencodings.h" +#include "version.h" + +#include <boost/algorithm/string.hpp> + +using namespace std; +using namespace json_spirit; + +enum RetFormat { + RF_UNDEF, + RF_BINARY, + RF_HEX, + RF_JSON, +}; + +static const struct { + enum RetFormat rf; + const char* name; +} rf_names[] = { + {RF_UNDEF, ""}, + {RF_BINARY, "bin"}, + {RF_HEX, "hex"}, + {RF_JSON, "json"}, +}; + +class RestErr +{ +public: + enum HTTPStatusCode status; + string message; +}; + +extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry); +extern Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); + +static RestErr RESTERR(enum HTTPStatusCode status, string message) +{ + RestErr re; + re.status = status; + re.message = message; + return re; +} + +static enum RetFormat ParseDataFormat(vector<string>& params, const 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; + } + + return rf_names[0].rf; +} + +static string AvailableDataFormatsString() +{ + string formats = ""; + for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++) + if (strlen(rf_names[i].name) > 0) { + formats.append("."); + formats.append(rf_names[i].name); + formats.append(", "); + } + + if (formats.length() > 0) + return formats.substr(0, formats.length() - 2); + + return formats; +} + +static bool ParseHashStr(const string& strReq, uint256& v) +{ + if (!IsHex(strReq) || (strReq.size() != 64)) + return false; + + v.SetHex(strReq); + return true; +} + +static bool rest_headers(AcceptedConnection* conn, + const std::string& strReq, + const std::map<std::string, std::string>& mapHeaders, + bool fRun) +{ + vector<string> params; + enum RetFormat rf = ParseDataFormat(params, strReq); + vector<string> path; + boost::split(path, params[0], boost::is_any_of("/")); + + if (path.size() != 2) + throw RESTERR(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]); + + string hashStr = path[1]; + uint256 hash; + if (!ParseHashStr(hashStr, hash)) + throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); + + std::vector<CBlockHeader> 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()); + if (headers.size() == (unsigned long)count) + break; + pindex = chainActive.Next(pindex); + } + } + + CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); + BOOST_FOREACH(const CBlockHeader &header, headers) { + ssHeader << header; + } + + switch (rf) { + case RF_BINARY: { + string binaryHeader = ssHeader.str(); + conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryHeader.size(), "application/octet-stream") << binaryHeader << std::flush; + 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; + return true; + } + + default: { + throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)"); + } + } + + // not reached + 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, + bool showTxDetails) +{ + vector<string> params; + enum RetFormat rf = ParseDataFormat(params, strReq); + + string hashStr = params[0]; + uint256 hash; + if (!ParseHashStr(hashStr, hash)) + throw RESTERR(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"); + + pblockindex = mapBlockIndex[hash]; + if (!ReadBlockFromDisk(block, pblockindex)) + throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); + } + + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + ssBlock << block; + + switch (rf) { + case RF_BINARY: { + string binaryBlock = ssBlock.str(); + conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryBlock.size(), "application/octet-stream") << binaryBlock << std::flush; + 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; + 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; + return true; + } + + default: { + throw RESTERR(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_block_extended(AcceptedConnection* conn, + const std::string& strReq, + const std::map<std::string, std::string>& mapHeaders, + bool fRun) +{ + return rest_block(conn, strReq, mapHeaders, fRun, true); +} + +static bool rest_block_notxdetails(AcceptedConnection* conn, + const std::string& strReq, + const std::map<std::string, std::string>& mapHeaders, + bool fRun) +{ + return rest_block(conn, strReq, mapHeaders, fRun, false); +} + +static bool rest_tx(AcceptedConnection* conn, + const std::string& strReq, + const std::map<std::string, std::string>& mapHeaders, + bool fRun) +{ + vector<string> params; + enum RetFormat rf = ParseDataFormat(params, strReq); + + string hashStr = params[0]; + uint256 hash; + if (!ParseHashStr(hashStr, hash)) + throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); + + CTransaction tx; + uint256 hashBlock = 0; + if (!GetTransaction(hash, tx, hashBlock, true)) + throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found"); + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << tx; + + switch (rf) { + case RF_BINARY: { + string binaryTx = ssTx.str(); + conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryTx.size(), "application/octet-stream") << binaryTx << std::flush; + 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; + return true; + } + + case RF_JSON: { + Object objTx; + TxToJSON(tx, hashBlock, objTx); + string strJSON = write_string(Value(objTx), false) + "\n"; + conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; + return true; + } + + default: { + throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")"); + } + } + + // not reached + return true; // continue to process further HTTP reqs on this cxn +} + +static const struct { + const char* prefix; + bool (*handler)(AcceptedConnection* conn, + const std::string& strURI, + const std::map<std::string, std::string>& mapHeaders, + bool fRun); +} uri_prefixes[] = { + {"/rest/tx/", rest_tx}, + {"/rest/block/notxdetails/", rest_block_notxdetails}, + {"/rest/block/", rest_block_extended}, + {"/rest/headers/", rest_headers}, +}; + +bool HTTPReq_REST(AcceptedConnection* conn, + const std::string& strURI, + const std::map<std::string, std::string>& mapHeaders, + bool fRun) +{ + 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; + } + + conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush; + return false; +} diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 4b3beae20c..71fb7c8233 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "checkpoints.h" @@ -16,6 +16,7 @@ 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); double GetDifficulty(const CBlockIndex* blockindex) @@ -50,7 +51,7 @@ double GetDifficulty(const CBlockIndex* blockindex) } -Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex) +Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { Object result; result.push_back(Pair("hash", block.GetHash().GetHex())); @@ -65,7 +66,16 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex) result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); Array txs; BOOST_FOREACH(const CTransaction&tx, block.vtx) - txs.push_back(tx.GetHash().GetHex()); + { + if(txDetails) + { + Object objTx; + TxToJSON(tx, uint256(0), objTx); + txs.push_back(objTx); + } + else + txs.push_back(tx.GetHash().GetHex()); + } result.push_back(Pair("tx", txs)); result.push_back(Pair("time", block.GetBlockTime())); result.push_back(Pair("nonce", (uint64_t)block.nNonce)); @@ -225,7 +235,7 @@ Value getblockhash(const Array& params, bool fHelp) int nHeight = params[0].get_int(); if (nHeight < 0 || nHeight > chainActive.Height()) - throw runtime_error("Block number out of range."); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); CBlockIndex* pblockindex = chainActive[nHeight]; return pblockindex->GetBlockHash().GetHex(); @@ -319,6 +329,7 @@ Value gettxoutsetinfo(const Array& params, bool fHelp) Object ret; CCoinsStats stats; + FlushStateToDisk(); if (pcoinsTip->GetStats(stats)) { ret.push_back(Pair("height", (int64_t)stats.nHeight)); ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); @@ -381,7 +392,7 @@ Value gettxout(const Array& params, bool fHelp) CCoins coins; if (fMempool) { LOCK(mempool.cs); - CCoinsViewMemPool view(*pcoinsTip, mempool); + CCoinsViewMemPool view(pcoinsTip, mempool); if (!view.GetCoins(hash, coins)) return Value::null; mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool @@ -445,6 +456,7 @@ Value getblockchaininfo(const Array& params, bool fHelp) "{\n" " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n" + " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n" " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n" " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" @@ -458,6 +470,7 @@ Value getblockchaininfo(const Array& params, bool fHelp) Object obj; 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()))); @@ -465,13 +478,13 @@ Value getblockchaininfo(const Array& params, bool fHelp) return obj; } -/* Comparison function for sorting the getchaintips heads. */ +/** Comparison function for sorting the getchaintips heads. */ struct CompareBlocksByHeight { bool operator()(const CBlockIndex* a, const CBlockIndex* b) const { /* Make sure that unequal blocks with the same height do not compare - equal. Use the pointers themselves to make a distinction. */ + equal. Use the pointers themselves to make a distinction. */ if (a->nHeight != b->nHeight) return (a->nHeight > b->nHeight); @@ -493,13 +506,21 @@ Value getchaintips(const Array& params, bool fHelp) " \"height\": xxxx, (numeric) height of the chain tip\n" " \"hash\": \"xxxx\", (string) block hash of the tip\n" " \"branchlen\": 0 (numeric) zero for main chain\n" + " \"status\": \"active\" (string) \"active\" for the main chain\n" " },\n" " {\n" " \"height\": xxxx,\n" " \"hash\": \"xxxx\",\n" " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n" + " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n" " }\n" "]\n" + "Possible values for status:\n" + "1. \"invalid\" This branch contains at least one invalid block\n" + "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n" + "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n" + "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n" + "5. \"active\" This is the tip of the active main chain, which is certainly valid\n" "\nExamples:\n" + HelpExampleCli("getchaintips", "") + HelpExampleRpc("getchaintips", "") @@ -518,6 +539,9 @@ Value getchaintips(const Array& params, bool fHelp) setTips.erase(pprev); } + // Always report the currently active tip. + setTips.insert(chainActive.Tip()); + /* Construct the output array. */ Array res; BOOST_FOREACH(const CBlockIndex* block, setTips) @@ -529,6 +553,28 @@ Value getchaintips(const Array& params, bool fHelp) const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight; obj.push_back(Pair("branchlen", branchLen)); + string status; + if (chainActive.Contains(block)) { + // This block is part of the currently active chain. + status = "active"; + } else if (block->nStatus & BLOCK_FAILED_MASK) { + // This block or one of its ancestors is invalid. + status = "invalid"; + } else if (block->nChainTx == 0) { + // This block cannot be connected because full block data for it or one of its parents is missing. + status = "headers-only"; + } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) { + // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized. + status = "valid-fork"; + } else if (block->IsValid(BLOCK_VALID_TREE)) { + // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain. + status = "valid-headers"; + } else { + // No clue. + status = "unknown"; + } + obj.push_back(Pair("status", status)); + res.push_back(obj); } @@ -558,3 +604,79 @@ Value getmempoolinfo(const Array& params, bool fHelp) return ret; } +Value invalidateblock(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "invalidateblock \"hash\"\n" + "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n" + "\nArguments:\n" + "1. hash (string, required) the hash of the block to mark as invalid\n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("invalidateblock", "\"blockhash\"") + + HelpExampleRpc("invalidateblock", "\"blockhash\"") + ); + + std::string strHash = params[0].get_str(); + uint256 hash(strHash); + CValidationState state; + + { + LOCK(cs_main); + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlockIndex* pblockindex = mapBlockIndex[hash]; + InvalidateBlock(state, pblockindex); + } + + if (state.IsValid()) { + ActivateBestChain(state); + } + + if (!state.IsValid()) { + throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); + } + + return Value::null; +} + +Value reconsiderblock(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "reconsiderblock \"hash\"\n" + "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n" + "This can be used to undo the effects of invalidateblock.\n" + "\nArguments:\n" + "1. hash (string, required) the hash of the block to reconsider\n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("reconsiderblock", "\"blockhash\"") + + HelpExampleRpc("reconsiderblock", "\"blockhash\"") + ); + + std::string strHash = params[0].get_str(); + uint256 hash(strHash); + CValidationState state; + + { + LOCK(cs_main); + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlockIndex* pblockindex = mapBlockIndex[hash]; + ReconsiderBlock(state, pblockindex); + } + + if (state.IsValid()) { + ActivateBestChain(state); + } + + if (!state.IsValid()) { + throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); + } + + return Value::null; +} diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index a9c491cede..4e45bc32ab 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "rpcclient.h" @@ -18,13 +18,14 @@ using namespace json_spirit; class CRPCConvertParam { public: - std::string methodName; // method whose params want conversion - int paramIdx; // 0-based idx of param to convert + std::string methodName; //! method whose params want conversion + int paramIdx; //! 0-based idx of param to convert }; static const CRPCConvertParam vRPCConvertParams[] = { { "stop", 0 }, + { "setmocktime", 0 }, { "getaddednodeinfo", 0 }, { "setgenerate", 0 }, { "setgenerate", 1 }, @@ -115,7 +116,7 @@ CRPCConvertTable::CRPCConvertTable() static CRPCConvertTable rpcCvtTable; -// Convert strings to command-specific RPC representation +/** Convert strings to command-specific RPC representation */ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams) { Array params; diff --git a/src/rpcclient.h b/src/rpcclient.h index 307aa2aab8..42fa2d06fe 100644 --- a/src/rpcclient.h +++ b/src/rpcclient.h @@ -1,10 +1,10 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 _BITCOINRPC_CLIENT_H_ -#define _BITCOINRPC_CLIENT_H_ +#ifndef BITCOIN_RPCCLIENT_H +#define BITCOIN_RPCCLIENT_H #include "json/json_spirit_reader_template.h" #include "json/json_spirit_utils.h" @@ -12,4 +12,4 @@ json_spirit::Array RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams); -#endif // _BITCOINRPC_CLIENT_H_ +#endif // BITCOIN_RPCCLIENT_H diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index 1ac7024550..8666779cc1 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "base58.h" @@ -112,10 +112,9 @@ Value importprivkey(const Array& params, bool fHelp) if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range"); CPubKey pubkey = key.GetPubKey(); + assert(key.VerifyPubKey(pubkey)); CKeyID vchAddress = pubkey.GetID(); { - LOCK2(cs_main, pwalletMain->cs_wallet); - pwalletMain->MarkDirty(); pwalletMain->SetAddressBook(vchAddress, strLabel, "receive"); @@ -181,7 +180,8 @@ Value importaddress(const Array& params, bool fHelp) fRescan = params[2].get_bool(); { - LOCK2(cs_main, pwalletMain->cs_wallet); + 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()) @@ -254,6 +254,7 @@ Value importwallet(const Array& params, bool fHelp) continue; CKey key = vchSecret.GetKey(); CPubKey pubkey = key.GetPubKey(); + assert(key.VerifyPubKey(pubkey)); CKeyID keyid = pubkey.GetID(); if (pwalletMain->HaveKey(keyid)) { LogPrintf("Skipping import of %s (key already present)\n", CBitcoinAddress(keyid).ToString()); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 82eaf5d037..35760f9af0 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -1,8 +1,9 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. +#include "amount.h" #include "chainparams.h" #include "core_io.h" #include "init.h" @@ -27,9 +28,11 @@ using namespace json_spirit; using namespace std; -// Return average network hashes per second based on the last 'lookup' blocks, -// 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. +/** + * Return average network hashes per second based on the last 'lookup' blocks, + * 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) { CBlockIndex *pb = chainActive.Tip(); @@ -120,6 +123,8 @@ Value setgenerate(const Array& params, bool fHelp) "1. generate (boolean, required) Set to true to turn on generation, off to turn off.\n" "2. genproclimit (numeric, optional) Set the processor limit for when generation is on. Can be -1 for unlimited.\n" " Note: in -regtest mode, genproclimit controls how many blocks are generated immediately.\n" + "\nResult\n" + "[ blockhashes ] (array, -regtest only) hashes of blocks generated\n" "\nExamples:\n" "\nSet the generation on with a limit of one processor\n" + HelpExampleCli("setgenerate", "true 1") + @@ -153,26 +158,38 @@ Value setgenerate(const Array& params, bool fHelp) int nHeightEnd = 0; int nHeight = 0; int nGenerate = (nGenProcLimit > 0 ? nGenProcLimit : 1); + CReserveKey reservekey(pwalletMain); + { // Don't keep cs_main locked LOCK(cs_main); nHeightStart = chainActive.Height(); nHeight = nHeightStart; nHeightEnd = nHeightStart+nGenerate; } - int nHeightLast = -1; + unsigned int nExtraNonce = 0; + Array blockHashes; while (nHeight < nHeightEnd) { - if (nHeightLast != nHeight) + auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey)); + if (!pblocktemplate.get()) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty"); + CBlock *pblock = &pblocktemplate->block; { - nHeightLast = nHeight; - GenerateBitcoins(fGenerate, pwalletMain, 1); - } - MilliSleep(1); - { // Don't keep cs_main locked LOCK(cs_main); - nHeight = chainActive.Height(); + IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce); + } + while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits)) { + // Yes, there is a chance every nonce could fail to satisfy the -regtest + // target -- 1 in 2^(2^32). That ain't gonna happen. + ++pblock->nNonce; } + CValidationState state; + if (!ProcessNewBlock(state, NULL, pblock)) + throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); + ++nHeight; + blockHashes.push_back(pblock->GetHash().GetHex()); } + return blockHashes; } else // Not -regtest: start generate thread, return immediately { @@ -239,7 +256,7 @@ Value getmininginfo(const Array& params, bool fHelp) obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); - obj.push_back(Pair("testnet", Params().NetworkID() == CBaseChainParams::TESTNET)); + 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))); @@ -249,6 +266,7 @@ Value getmininginfo(const Array& params, bool fHelp) } +// 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) { if (fHelp || params.size() != 3) @@ -260,28 +278,44 @@ Value prioritisetransaction(const Array& params, bool fHelp) "2. priority delta (numeric, required) The priority to add or subtract.\n" " The transaction selection algorithm considers the tx as it would have a higher priority.\n" " (priority of a transaction is calculated: coinage * value_in_satoshis / txsize) \n" - "3. fee delta (numeric, required) The absolute fee value to add or subtract in bitcoin.\n" + "3. fee delta (numeric, required) The fee value (in satoshis) to add (or subtract, if negative).\n" " The fee is not actually paid, only the algorithm for selecting transactions into a block\n" " considers the transaction as it would have paid a higher (or lower) fee.\n" "\nResult\n" "true (boolean) Returns true\n" "\nExamples:\n" - + HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 0.00010000") - + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 0.00010000") + + HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000") + + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000") ); - uint256 hash; - hash.SetHex(params[0].get_str()); + uint256 hash = ParseHashStr(params[0].get_str(), "txid"); - int64_t nAmount = 0; - if (params[2].get_real() != 0.0) - nAmount = AmountFromValue(params[2]); + CAmount nAmount = params[2].get_int64(); mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), nAmount); return true; } +// NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller +static Value BIP22ValidationResult(const CValidationState& state) +{ + if (state.IsValid()) + return Value::null; + + std::string strRejectReason = state.GetRejectReason(); + if (state.IsError()) + throw JSONRPCError(RPC_VERIFY_ERROR, strRejectReason); + if (state.IsInvalid()) + { + if (strRejectReason.empty()) + return "rejected"; + return strRejectReason; + } + // Should be impossible + return "valid?"; +} + Value getblocktemplate(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) @@ -359,6 +393,36 @@ Value getblocktemplate(const Array& params, bool fHelp) else throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); lpval = find_value(oparam, "longpollid"); + + if (strMode == "proposal") + { + const Value& dataval = find_value(oparam, "data"); + if (dataval.type() != str_type) + throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); + + CBlock block; + if (!DecodeHexBlk(block, dataval.get_str())) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); + + uint256 hash = block.GetHash(); + BlockMap::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) { + CBlockIndex *pindex = mi->second; + if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) + return "duplicate"; + if (pindex->nStatus & BLOCK_FAILED_MASK) + return "duplicate-invalid"; + return "duplicate-inconclusive"; + } + + CBlockIndex* const pindexPrev = chainActive.Tip(); + // TestBlockValidity only supports blocks built on the current Tip + if (block.hashPrevBlock != pindexPrev->GetBlockHash()) + return "inconclusive-not-best-prevblk"; + CValidationState state; + TestBlockValidity(state, block, pindexPrev, false, true); + return BIP22ValidationResult(state); + } } if (strMode != "template") @@ -461,6 +525,8 @@ Value getblocktemplate(const Array& params, bool fHelp) UpdateTime(pblock, pindexPrev); pblock->nNonce = 0; + static const Array aCaps = boost::assign::list_of("proposal"); + Array transactions; map<uint256, int64_t> setTxIndex; int i = 0; @@ -507,6 +573,7 @@ Value getblocktemplate(const Array& params, bool fHelp) } Object result; + result.push_back(Pair("capabilities", aCaps)); result.push_back(Pair("version", pblock->nVersion)); result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); result.push_back(Pair("transactions", transactions)); @@ -526,6 +593,24 @@ Value getblocktemplate(const Array& params, bool fHelp) return result; } +class submitblock_StateCatcher : public CValidationInterface +{ +public: + uint256 hash; + bool found; + CValidationState state; + + submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), found(false), state() {}; + +protected: + virtual void BlockChecked(const CBlock& block, const CValidationState& stateIn) { + if (block.GetHash() != hash) + return; + found = true; + state = stateIn; + }; +}; + Value submitblock(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) @@ -547,22 +632,39 @@ Value submitblock(const Array& params, bool fHelp) + HelpExampleRpc("submitblock", "\"mydata\"") ); - vector<unsigned char> blockData(ParseHex(params[0].get_str())); - CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION); - CBlock pblock; - try { - ssBlock >> pblock; - } - catch (const std::exception &) { + CBlock block; + if (!DecodeHexBlk(block, params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); + + uint256 hash = block.GetHash(); + BlockMap::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) { + CBlockIndex *pindex = mi->second; + if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) + return "duplicate"; + if (pindex->nStatus & BLOCK_FAILED_MASK) + return "duplicate-invalid"; + // Otherwise, we might only have the header - process the block before returning } CValidationState state; - bool fAccepted = ProcessBlock(state, NULL, &pblock); - if (!fAccepted) - return "rejected"; // TODO: report validation state - - return Value::null; + submitblock_StateCatcher sc(block.GetHash()); + RegisterValidationInterface(&sc); + bool fAccepted = ProcessNewBlock(state, NULL, &block); + UnregisterValidationInterface(&sc); + if (mi != mapBlockIndex.end()) + { + if (fAccepted && !sc.found) + return "duplicate-inconclusive"; + return "duplicate"; + } + if (fAccepted) + { + if (!sc.found) + return "inconclusive"; + state = sc.state; + } + return BIP22ValidationResult(state); } Value estimatefee(const Array& params, bool fHelp) @@ -571,7 +673,7 @@ Value estimatefee(const Array& params, bool fHelp) throw runtime_error( "estimatefee nblocks\n" "\nEstimates the approximate fee per kilobyte\n" - "needed for a transaction to get confirmed\n" + "needed for a transaction to begin confirmation\n" "within nblocks blocks.\n" "\nArguments:\n" "1. nblocks (numeric)\n" @@ -603,7 +705,7 @@ Value estimatepriority(const Array& params, bool fHelp) throw runtime_error( "estimatepriority nblocks\n" "\nEstimates the approximate priority\n" - "a zero-fee transaction needs to get confirmed\n" + "a zero-fee transaction needs to begin confirmation\n" "within nblocks blocks.\n" "\nArguments:\n" "1. nblocks (numeric)\n" diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index d1ab5093ff..7c08a5c246 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -1,9 +1,10 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "base58.h" +#include "clientversion.h" #include "init.h" #include "main.h" #include "net.h" @@ -29,7 +30,7 @@ using namespace std; /** * @note Do not add or change anything in the information returned by this - * method. `getinfo` exists for backwards-compatibilty only. It combines + * method. `getinfo` exists for backwards-compatibility only. It combines * information from wildly different sources in the program, which is a mess, * and is thus planned to be deprecated eventually. * @@ -87,7 +88,7 @@ Value getinfo(const Array& params, bool fHelp) obj.push_back(Pair("connections", (int)vNodes.size())); obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.ToStringIPPort() : string()))); obj.push_back(Pair("difficulty", (double)GetDifficulty())); - obj.push_back(Pair("testnet", Params().NetworkID() == CBaseChainParams::TESTNET)); + obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC())); #ifdef ENABLE_WALLET if (pwalletMain) { obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); @@ -202,9 +203,9 @@ Value validateaddress(const Array& params, bool fHelp) return ret; } -// -// Used by addmultisigaddress / createmultisig: -// +/** + * Used by addmultisigaddress / createmultisig: + */ CScript _createmultisig_redeemScript(const Array& params) { int nRequired = params[0].get_int(); @@ -297,7 +298,7 @@ Value createmultisig(const Array& params, bool fHelp) // Construct using pay-to-script-hash: CScript inner = _createmultisig_redeemScript(params); - CScriptID innerID = inner.GetID(); + CScriptID innerID(inner); CBitcoinAddress address(innerID); Object result; @@ -358,3 +359,23 @@ Value verifymessage(const Array& params, bool fHelp) return (pubkey.GetID() == keyID); } + +Value setmocktime(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "setmocktime timestamp\n" + "\nSet the local time to given timestamp (-regtest only)\n" + "\nArguments:\n" + "1. timestamp (integer, required) Unix seconds-since-epoch timestamp\n" + " Pass 0 to go back to using the system time." + ); + + if (!Params().MineBlocksOnDemand()) + throw runtime_error("setmocktime for regression testing (-regtest mode) only"); + + RPCTypeCheck(params, boost::assign::list_of(int_type)); + SetMockTime(params[0].get_int64()); + + return Value::null; +} diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 95f42eb47f..2886f7adab 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -1,9 +1,10 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "rpcserver.h" +#include "clientversion.h" #include "main.h" #include "net.h" #include "netbase.h" @@ -11,6 +12,7 @@ #include "sync.h" #include "timedata.h" #include "util.h" +#include "version.h" #include <boost/foreach.hpp> @@ -96,7 +98,12 @@ Value getpeerinfo(const Array& params, bool fHelp) " \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n" " \"startingheight\": n, (numeric) The starting height (block) of the peer\n" " \"banscore\": n, (numeric) The ban score\n" - " \"syncnode\": true|false (boolean) if sync node\n" + " \"synced_headers\": n, (numeric) The last header we have in common with this peer\n" + " \"synced_blocks\": n, (numeric) The last block we have in common with this peer\n" + " \"inflight\": [\n" + " n, (numeric) The heights of blocks we're currently asking from this peer\n" + " ...\n" + " ]\n" " }\n" " ,...\n" "]\n" @@ -136,9 +143,14 @@ Value getpeerinfo(const Array& params, bool fHelp) obj.push_back(Pair("startingheight", stats.nStartingHeight)); if (fStateStats) { obj.push_back(Pair("banscore", statestats.nMisbehavior)); - obj.push_back(Pair("syncheight", statestats.nSyncHeight)); + obj.push_back(Pair("synced_headers", statestats.nSyncHeight)); + obj.push_back(Pair("synced_blocks", statestats.nCommonHeight)); + Array heights; + BOOST_FOREACH(int height, statestats.vHeightInFlight) { + heights.push_back(height); + } + obj.push_back(Pair("inflight", heights)); } - obj.push_back(Pair("syncnode", stats.fSyncNode)); obj.push_back(Pair("whitelisted", stats.fWhitelisted)); ret.push_back(obj); @@ -367,23 +379,29 @@ Value getnetworkinfo(const Array& params, bool fHelp) "Returns an object containing various state info regarding P2P networking.\n" "\nResult:\n" "{\n" - " \"version\": xxxxx, (numeric) the server version\n" - " \"protocolversion\": xxxxx, (numeric) the protocol version\n" - " \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n" - " \"timeoffset\": xxxxx, (numeric) the time offset\n" - " \"connections\": xxxxx, (numeric) the number of connections\n" - " \"networks\": [ (array) information per network\n" - " \"name\": \"xxx\", (string) network (ipv4, ipv6 or onion)\n" - " \"limited\": xxx, (boolean) is the network limited using -onlynet?\n" - " \"reachable\": xxx, (boolean) is the network reachable?\n" - " \"proxy\": \"host:port\" (string) the proxy that is used for this network, or empty if none\n" - " },\n" + " \"version\": xxxxx, (numeric) the server version\n" + " \"subversion\": \"/Satoshi:x.x.x/\", (string) the server subversion string\n" + " \"protocolversion\": xxxxx, (numeric) the protocol version\n" + " \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n" + " \"timeoffset\": xxxxx, (numeric) the time offset\n" + " \"connections\": xxxxx, (numeric) the number of connections\n" + " \"networks\": [ (array) information per network\n" + " {\n" + " \"name\": \"xxx\", (string) network (ipv4, ipv6 or onion)\n" + " \"limited\": true|false, (boolean) is the network limited using -onlynet?\n" + " \"reachable\": true|false, (boolean) is the network reachable?\n" + " \"proxy\": \"host:port\" (string) the proxy that is used for this network, or empty if none\n" + " }\n" + " ,...\n" " ],\n" - " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n" - " \"localaddresses\": [, (array) list of local addresses\n" - " \"address\": \"xxxx\", (string) network address\n" - " \"port\": xxx, (numeric) network port\n" - " \"score\": xxx (numeric) relative score\n" + " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n" + " \"localaddresses\": [ (array) list of local addresses\n" + " {\n" + " \"address\": \"xxxx\", (string) network address\n" + " \"port\": xxx, (numeric) network port\n" + " \"score\": xxx (numeric) relative score\n" + " }\n" + " ,...\n" " ]\n" "}\n" "\nExamples:\n" @@ -392,8 +410,10 @@ Value getnetworkinfo(const Array& params, bool fHelp) ); Object obj; - obj.push_back(Pair("version", (int)CLIENT_VERSION)); - obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION)); + obj.push_back(Pair("version", CLIENT_VERSION)); + obj.push_back(Pair("subversion", + FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()))); + 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())); diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index c99d113bc3..c4d6f06b12 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -1,10 +1,11 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "rpcprotocol.h" +#include "clientversion.h" #include "tinyformat.h" #include "util.h" #include "utilstrencodings.h" @@ -29,15 +30,15 @@ using namespace boost; using namespace boost::asio; using namespace json_spirit; -// Number of bytes to allocate and read at most at once in post data +//! Number of bytes to allocate and read at most at once in post data const size_t POST_READ_SIZE = 256 * 1024; -// -// HTTP protocol -// -// This ain't Apache. We're just using HTTP header for the length field -// and to be compatible with other JSON-RPC implementations. -// +/** + * HTTP protocol + * + * This ain't Apache. We're just using HTTP header for the length field + * and to be compatible with other JSON-RPC implementations. + */ string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeaders) { @@ -245,15 +246,15 @@ int ReadHTTPMessage(std::basic_istream<char>& stream, map<string, 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 -// +/** + * 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) { diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h index a9adb58803..4f3f70fb37 100644 --- a/src/rpcprotocol.h +++ b/src/rpcprotocol.h @@ -1,10 +1,10 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 _BITCOINRPC_PROTOCOL_H_ -#define _BITCOINRPC_PROTOCOL_H_ +#ifndef BITCOIN_RPCPROTOCOL_H +#define BITCOIN_RPCPROTOCOL_H #include <list> #include <map> @@ -19,7 +19,7 @@ #include "json/json_spirit_utils.h" #include "json/json_spirit_writer_template.h" -// HTTP status codes +//! HTTP status codes enum HTTPStatusCode { HTTP_OK = 200, @@ -28,52 +28,59 @@ enum HTTPStatusCode HTTP_FORBIDDEN = 403, HTTP_NOT_FOUND = 404, HTTP_INTERNAL_SERVER_ERROR = 500, + HTTP_SERVICE_UNAVAILABLE = 503, }; -// Bitcoin RPC error codes +//! Bitcoin RPC error codes enum RPCErrorCode { - // Standard JSON-RPC 2.0 errors + //! Standard JSON-RPC 2.0 errors RPC_INVALID_REQUEST = -32600, RPC_METHOD_NOT_FOUND = -32601, RPC_INVALID_PARAMS = -32602, RPC_INTERNAL_ERROR = -32603, RPC_PARSE_ERROR = -32700, - // General application defined errors - RPC_MISC_ERROR = -1, // std::exception thrown in command handling - RPC_FORBIDDEN_BY_SAFE_MODE = -2, // Server is in safe mode, and command is not allowed in safe mode - RPC_TYPE_ERROR = -3, // Unexpected type was passed as parameter - RPC_INVALID_ADDRESS_OR_KEY = -5, // Invalid address or key - RPC_OUT_OF_MEMORY = -7, // Ran out of memory during operation - RPC_INVALID_PARAMETER = -8, // Invalid, missing or duplicate parameter - RPC_DATABASE_ERROR = -20, // Database error - RPC_DESERIALIZATION_ERROR = -22, // Error parsing or validating structure in raw format - RPC_TRANSACTION_ERROR = -25, // General error during transaction submission - RPC_TRANSACTION_REJECTED = -26, // Transaction was rejected by network rules - RPC_TRANSACTION_ALREADY_IN_CHAIN= -27, // Transaction already in chain + //! General application defined errors + RPC_MISC_ERROR = -1, //! std::exception thrown in command handling + RPC_FORBIDDEN_BY_SAFE_MODE = -2, //! Server is in safe mode, and command is not allowed in safe mode + RPC_TYPE_ERROR = -3, //! Unexpected type was passed as parameter + RPC_INVALID_ADDRESS_OR_KEY = -5, //! Invalid address or key + RPC_OUT_OF_MEMORY = -7, //! Ran out of memory during operation + RPC_INVALID_PARAMETER = -8, //! Invalid, missing or duplicate parameter + RPC_DATABASE_ERROR = -20, //! Database error + RPC_DESERIALIZATION_ERROR = -22, //! Error parsing or validating structure in raw format + RPC_VERIFY_ERROR = -25, //! General error during transaction or block submission + RPC_VERIFY_REJECTED = -26, //! Transaction or block was rejected by network rules + RPC_VERIFY_ALREADY_IN_CHAIN = -27, //! Transaction already in chain + RPC_IN_WARMUP = -28, //! Client still warming up - // P2P client errors - RPC_CLIENT_NOT_CONNECTED = -9, // Bitcoin is not connected - RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, // Still downloading initial blocks - RPC_CLIENT_NODE_ALREADY_ADDED = -23, // Node is already added - RPC_CLIENT_NODE_NOT_ADDED = -24, // Node has not been added before + //! Aliases for backward compatibility + RPC_TRANSACTION_ERROR = RPC_VERIFY_ERROR, + RPC_TRANSACTION_REJECTED = RPC_VERIFY_REJECTED, + RPC_TRANSACTION_ALREADY_IN_CHAIN= RPC_VERIFY_ALREADY_IN_CHAIN, - // Wallet errors - RPC_WALLET_ERROR = -4, // Unspecified problem with wallet (key not found etc.) - RPC_WALLET_INSUFFICIENT_FUNDS = -6, // Not enough funds in wallet or account - RPC_WALLET_INVALID_ACCOUNT_NAME = -11, // Invalid account name - RPC_WALLET_KEYPOOL_RAN_OUT = -12, // Keypool ran out, call keypoolrefill first - RPC_WALLET_UNLOCK_NEEDED = -13, // Enter the wallet passphrase with walletpassphrase first - RPC_WALLET_PASSPHRASE_INCORRECT = -14, // The wallet passphrase entered was incorrect - RPC_WALLET_WRONG_ENC_STATE = -15, // Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.) - RPC_WALLET_ENCRYPTION_FAILED = -16, // Failed to encrypt the wallet - RPC_WALLET_ALREADY_UNLOCKED = -17, // Wallet is already unlocked + //! P2P client errors + RPC_CLIENT_NOT_CONNECTED = -9, //! Bitcoin is not connected + RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, //! Still downloading initial blocks + RPC_CLIENT_NODE_ALREADY_ADDED = -23, //! Node is already added + RPC_CLIENT_NODE_NOT_ADDED = -24, //! Node has not been added before + + //! Wallet errors + RPC_WALLET_ERROR = -4, //! Unspecified problem with wallet (key not found etc.) + RPC_WALLET_INSUFFICIENT_FUNDS = -6, //! Not enough funds in wallet or account + RPC_WALLET_INVALID_ACCOUNT_NAME = -11, //! Invalid account name + RPC_WALLET_KEYPOOL_RAN_OUT = -12, //! Keypool ran out, call keypoolrefill first + RPC_WALLET_UNLOCK_NEEDED = -13, //! Enter the wallet passphrase with walletpassphrase first + RPC_WALLET_PASSPHRASE_INCORRECT = -14, //! The wallet passphrase entered was incorrect + RPC_WALLET_WRONG_ENC_STATE = -15, //! Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.) + RPC_WALLET_ENCRYPTION_FAILED = -16, //! Failed to encrypt the wallet + RPC_WALLET_ALREADY_UNLOCKED = -17, //! Wallet is already unlocked }; -// -// IOStream device that speaks SSL but can also speak non-SSL -// +/** + * IOStream device that speaks SSL but can also speak non-SSL + */ template <typename Protocol> class SSLIOStreamDevice : public boost::iostreams::device<boost::iostreams::bidirectional> { public: @@ -115,8 +122,7 @@ public: tcp::resolver::query query(server.c_str(), port.c_str()); endpoint_iterator = resolver.resolve(query); #if BOOST_VERSION >= 104300 - } catch(boost::system::system_error &e) - { + } 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); @@ -159,4 +165,4 @@ json_spirit::Object JSONRPCReplyObj(const json_spirit::Value& result, const json 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); -#endif // _BITCOINRPC_PROTOCOL_H_ +#endif // BITCOIN_RPCPROTOCOL_H diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index dbb0966ae2..b87a8baac3 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -1,10 +1,10 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "base58.h" -#include "core.h" +#include "primitives/transaction.h" #include "core_io.h" #include "init.h" #include "keystore.h" @@ -110,6 +110,9 @@ Value getrawtransaction(const Array& params, bool fHelp) if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "getrawtransaction \"txid\" ( verbose )\n" + "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n" + "or there is an unspent output in the utxo for this transaction. To make it always work,\n" + "you need to maintain a transaction index, using the -txindex command line option.\n" "\nReturn the raw transaction data.\n" "\nIf verbose=0, returns a string that is serialized, hex-encoded data for 'txid'.\n" "If verbose is non-zero, returns an Object with information about 'txid'.\n" @@ -202,7 +205,7 @@ Value listunspent(const Array& params, bool fHelp) "Results are an array of Objects, each of which has:\n" "{txid, vout, scriptPubKey, amount, confirmations}\n" "\nArguments:\n" - "1. minconf (numeric, optional, default=1) The minimum confirmationsi to filter\n" + "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n" "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n" "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n" " [\n" @@ -269,7 +272,7 @@ Value listunspent(const Array& params, bool fHelp) continue; } - int64_t nValue = out.tx->vout[out.i].nValue; + CAmount nValue = out.tx->vout[out.i].nValue; const CScript& pk = out.tx->vout[out.i].scriptPubKey; Object entry; entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); @@ -367,7 +370,7 @@ Value createrawtransaction(const Array& params, bool fHelp) setAddress.insert(address); CScript scriptPubKey = GetScriptForDestination(address.Get()); - int64_t nAmount = AmountFromValue(s.value_); + CAmount nAmount = AmountFromValue(s.value_); CTxOut out(nAmount, scriptPubKey); rawTx.vout.push_back(out); @@ -477,7 +480,7 @@ Value decodescript(const Array& params, bool fHelp) } ScriptPubKeyToJSON(script, r, false); - r.push_back(Pair("p2sh", CBitcoinAddress(script.GetID()).ToString())); + r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString())); return r; } @@ -542,7 +545,7 @@ Value signrawtransaction(const Array& params, bool fHelp) ssData >> tx; txVariants.push_back(tx); } - catch (const std::exception &) { + catch (const std::exception&) { throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); } } @@ -557,11 +560,11 @@ Value signrawtransaction(const Array& params, bool fHelp) // Fetch previous transactions (inputs): CCoinsView viewDummy; - CCoinsViewCache view(viewDummy); + CCoinsViewCache view(&viewDummy); { LOCK(mempool.cs); CCoinsViewCache &viewChain = *pcoinsTip; - CCoinsViewMemPool viewMempool(viewChain, mempool); + CCoinsViewMemPool viewMempool(&viewChain, mempool); view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) { @@ -584,6 +587,8 @@ Value signrawtransaction(const Array& params, bool fHelp) if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); CKey key = vchSecret.GetKey(); + if (!key.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range"); tempKeystore.AddKey(key); } } @@ -612,21 +617,19 @@ Value signrawtransaction(const Array& params, bool fHelp) vector<unsigned char> pkData(ParseHexO(prevOut, "scriptPubKey")); CScript scriptPubKey(pkData.begin(), pkData.end()); - CCoins coins; - if (view.GetCoins(txid, coins)) { - if (coins.IsAvailable(nOut) && coins.vout[nOut].scriptPubKey != scriptPubKey) { + { + 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"+ + err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+ scriptPubKey.ToString(); throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err); } - // what todo if txid is known, but the actual output isn't? + if ((unsigned int)nOut >= coins->vout.size()) + coins->vout.resize(nOut+1); + coins->vout[nOut].scriptPubKey = scriptPubKey; + coins->vout[nOut].nValue = 0; // we don't know the actual output value } - if ((unsigned int)nOut >= coins.vout.size()) - coins.vout.resize(nOut+1); - coins.vout[nOut].scriptPubKey = scriptPubKey; - coins.vout[nOut].nValue = 0; // we don't know the actual output value - view.SetCoins(txid, coins); // if redeemScript given and not using the local wallet (private keys // given), add redeemScript to the tempKeystore so it can be signed: @@ -687,7 +690,7 @@ 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, mergedTx, i, STANDARD_SCRIPT_VERIFY_FLAGS)) + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i))) fComplete = false; } diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 190de62282..210c7fe973 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "rpcserver.h" @@ -34,7 +34,11 @@ using namespace std; static std::string strRPCUserColonPass; static bool fRPCRunning = false; -// These are created by StartRPCThreads, destroyed in StopRPCThreads +static bool fRPCInWarmup = true; +static std::string rpcWarmupStatus("RPC server started"); +static CCriticalSection cs_rpcWarmup; + +//! These are created by StartRPCThreads, destroyed in StopRPCThreads static asio::io_service* rpc_io_service = NULL; static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers; static ssl::context* rpc_ssl_context = NULL; @@ -88,18 +92,18 @@ static inline int64_t roundint64(double d) return (int64_t)(d > 0 ? d + 0.5 : d - 0.5); } -int64_t AmountFromValue(const Value& value) +CAmount AmountFromValue(const Value& value) { double dAmount = value.get_real(); if (dAmount <= 0.0 || dAmount > 21000000.0) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); - int64_t nAmount = roundint64(dAmount * COIN); + CAmount nAmount = roundint64(dAmount * COIN); if (!MoneyRange(nAmount)) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); return nAmount; } -Value ValueFromAmount(int64_t amount) +Value ValueFromAmount(const CAmount& amount) { return (double)amount / (double)COIN; } @@ -134,9 +138,9 @@ vector<unsigned char> ParseHexO(const Object& o, string strKey) } -/// -/// Note: This interface may still be subject to change. -/// +/** + * Note: This interface may still be subject to change. + */ string CRPCTable::help(string strCommand) const { @@ -156,7 +160,7 @@ string CRPCTable::help(string strCommand) const // We already filter duplicates, but these deprecated screw up the sort order if (strMethod.find("label") != string::npos) continue; - if (strCommand != "" && strMethod != strCommand) + if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand) continue; #ifdef ENABLE_WALLET if (pcmd->reqWallet && !pwalletMain) @@ -170,7 +174,7 @@ string CRPCTable::help(string strCommand) const if (setDone.insert(pfn).second) (*pfn)(params, true); } - catch (std::exception& e) + catch (const std::exception& e) { // Help text is returned in an exception string strHelp = string(e.what()); @@ -232,11 +236,9 @@ Value stop(const Array& params, bool fHelp) -// -// Call Table -// - - +/** + * Call Table + */ static const CRPCCommand vRPCCommands[] = { // category name actor (function) okSafeMode threadSafe reqWallet // --------------------- ------------------------ ----------------------- ---------- ---------- --------- @@ -267,6 +269,8 @@ static const CRPCCommand vRPCCommands[] = { "blockchain", "gettxout", &gettxout, true, false, false }, { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, false, false }, { "blockchain", "verifychain", &verifychain, true, false, false }, + { "blockchain", "invalidateblock", &invalidateblock, true, true, false }, + { "blockchain", "reconsiderblock", &reconsiderblock, true, true, false }, /* Mining */ { "mining", "getblocktemplate", &getblocktemplate, true, false, false }, @@ -297,6 +301,11 @@ static const CRPCCommand vRPCCommands[] = { "util", "estimatefee", &estimatefee, true, true, false }, { "util", "estimatepriority", &estimatepriority, true, true, false }, + /* Not shown in help */ + { "hidden", "invalidateblock", &invalidateblock, true, true, false }, + { "hidden", "reconsiderblock", &reconsiderblock, true, true, false }, + { "hidden", "setmocktime", &setmocktime, true, false, false }, + #ifdef ENABLE_WALLET /* Wallet */ { "wallet", "addmultisigaddress", &addmultisigaddress, true, false, true }, @@ -453,7 +462,7 @@ private: void ServiceConnection(AcceptedConnection *conn); -// Forward declaration required for RPCListen +//! 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, @@ -562,13 +571,8 @@ void StartRPCThreads() { unsigned char rand_pwd[32]; GetRandBytes(rand_pwd, 32); - string strWhatAmI = "To use bitcoind"; - if (mapArgs.count("-server")) - strWhatAmI = strprintf(_("To use the %s option"), "\"-server\""); - else if (mapArgs.count("-daemon")) - strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\""); uiInterface.ThreadSafeMessageBox(strprintf( - _("%s, you must set a rpcpassword in the configuration file:\n" + _("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" @@ -578,10 +582,9 @@ void StartRPCThreads() "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"), - strWhatAmI, GetConfigFile().string(), EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32)), - "", CClientUIInterface::MSG_ERROR); + "", CClientUIInterface::MSG_ERROR | CClientUIInterface::SECURE); StartShutdown(); return; } @@ -594,7 +597,7 @@ void StartRPCThreads() if (fUseSSL) { - rpc_ssl_context->set_options(ssl::context::no_sslv2); + rpc_ssl_context->set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3); filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert")); if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile; @@ -628,7 +631,7 @@ void StartRPCThreads() try { vEndpoints.push_back(ParseEndpoint(addr, defaultPort)); } - catch(const boost::system::system_error &) + catch (const boost::system::system_error&) { uiInterface.ThreadSafeMessageBox( strprintf(_("Could not parse -rpcbind value %s as network address"), addr), @@ -647,14 +650,16 @@ void StartRPCThreads() bool fListening = false; std::string strerr; + std::string straddress; BOOST_FOREACH(const ip::tcp::endpoint &endpoint, vEndpoints) { - asio::ip::address bindAddress = endpoint.address(); - LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", bindAddress.to_string(), endpoint.port(), bBindAny); - boost::system::error_code v6_only_error; - boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service)); - try { + 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)); @@ -669,14 +674,14 @@ void StartRPCThreads() fListening = true; rpc_acceptors.push_back(acceptor); - // If dual IPv6/IPv4 bind succesful, skip binding to IPv4 separately + // If dual IPv6/IPv4 bind successful, skip binding to IPv4 separately if(bBindAny && bindAddress == asio::ip::address_v6::any() && !v6_only_error) break; } - catch(boost::system::system_error &e) + catch (const boost::system::system_error& e) { - LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", bindAddress.to_string(), endpoint.port(), e.what()); - strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), bindAddress.to_string(), endpoint.port(), e.what()); + 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()); } } @@ -746,6 +751,27 @@ bool IsRPCRunning() return fRPCRunning; } +void SetRPCWarmupStatus(const std::string& newStatus) +{ + LOCK(cs_rpcWarmup); + rpcWarmupStatus = newStatus; +} + +void SetRPCWarmupFinished() +{ + LOCK(cs_rpcWarmup); + assert(fRPCInWarmup); + fRPCInWarmup = false; +} + +bool RPCIsInWarmup(std::string *outStatus) +{ + LOCK(cs_rpcWarmup); + if (outStatus) + *outStatus = rpcWarmupStatus; + return fRPCInWarmup; +} + void RPCRunHandler(const boost::system::error_code& err, boost::function<void(void)> func) { if (!err) @@ -818,11 +844,11 @@ static Object JSONRPCExecOne(const Value& req) Value result = tableRPC.execute(jreq.strMethod, jreq.params); rpc_result = JSONRPCReplyObj(result, Value::null, jreq.id); } - catch (Object& objError) + catch (const Object& objError) { rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id); } - catch (std::exception& e) + catch (const std::exception& e) { rpc_result = JSONRPCReplyObj(Value::null, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); @@ -872,6 +898,13 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, 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 @@ -891,12 +924,12 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, strReply.size()) << strReply << std::flush; } - catch (Object& objError) + catch (const Object& objError) { ErrorReply(conn->stream(), objError, jreq.id); return false; } - catch (std::exception& e) + catch (const std::exception& e) { ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); return false; @@ -924,9 +957,16 @@ void ServiceConnection(AcceptedConnection *conn) if (mapHeaders["connection"] == "close") 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; @@ -975,7 +1015,7 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s } return result; } - catch (std::exception& e) + catch (const std::exception& e) { throw JSONRPCError(RPC_MISC_ERROR, e.what()); } diff --git a/src/rpcserver.h b/src/rpcserver.h index 820c1bc081..fb561ab939 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -1,13 +1,14 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 _BITCOINRPC_SERVER_H_ -#define _BITCOINRPC_SERVER_H_ +#ifndef BITCOIN_RPCSERVER_H +#define BITCOIN_RPCSERVER_H -#include "uint256.h" +#include "amount.h" #include "rpcprotocol.h" +#include "uint256.h" #include <list> #include <map> @@ -31,35 +32,47 @@ public: virtual void close() = 0; }; -/* Start RPC threads */ +/** Start RPC threads */ void StartRPCThreads(); -/* Alternative to StartRPCThreads for the GUI, when no server is +/** + * 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 */ +/** Stop RPC threads */ void StopRPCThreads(); -/* Query whether RPC is running */ +/** Query whether RPC is running */ bool IsRPCRunning(); -/* - Type-check arguments; throws JSONRPCError if wrong type given. Does not check that - the right number of arguments are passed, just that any passed are the correct type. - Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type)); -*/ +/** + * Set the RPC warmup status. When this is done, all RPC calls will error out + * immediately with RPC_IN_WARMUP. + */ +void SetRPCWarmupStatus(const std::string& newStatus); +/* Mark warmup as done. RPC calls will be processed from now on. */ +void SetRPCWarmupFinished(); + +/* returns the current warmup state. */ +bool RPCIsInWarmup(std::string *statusOut); + +/** + * Type-check arguments; throws JSONRPCError if wrong type given. Does not check that + * the right number of arguments are passed, just that any passed are the correct type. + * Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type)); + */ void RPCTypeCheck(const json_spirit::Array& params, const std::list<json_spirit::Value_type>& typesExpected, bool fAllowNull=false); -/* - Check for expected keys/value types in an Object. - Use like: RPCTypeCheck(object, boost::assign::map_list_of("name", str_type)("value", int_type)); -*/ +/** + * Check for expected keys/value types in an Object. + * Use like: RPCTypeCheck(object, boost::assign::map_list_of("name", str_type)("value", int_type)); + */ void RPCTypeCheck(const json_spirit::Object& o, const std::map<std::string, json_spirit::Value_type>& typesExpected, bool fAllowNull=false); -/* - Run func nSeconds from now. Uses boost deadline timers. - Overrides previous timer <name> (if any). +/** + * Run func nSeconds from now. Uses boost deadline timers. + * Overrides previous timer <name> (if any). */ void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds); @@ -103,10 +116,10 @@ public: extern const CRPCTable tableRPC; -// -// Utilities: convert hex-encoded Values -// (throws error if not hex). -// +/** + * 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); @@ -116,8 +129,8 @@ extern void InitRPCMining(); extern void ShutdownRPCMining(); extern int64_t nWalletUnlockTime; -extern int64_t AmountFromValue(const json_spirit::Value& value); -extern json_spirit::Value ValueFromAmount(int64_t amount); +extern CAmount AmountFromValue(const json_spirit::Value& value); +extern json_spirit::Value 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); @@ -185,6 +198,7 @@ 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 getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp); @@ -208,5 +222,13 @@ extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool 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); -#endif // _BITCOINRPC_SERVER_H_ +#endif // BITCOIN_RPCSERVER_H diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 35637362a4..56be6dba13 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1,8 +1,9 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. +#include "amount.h" #include "base58.h" #include "core_io.h" #include "rpcserver.h" @@ -11,6 +12,7 @@ #include "netbase.h" #include "timedata.h" #include "util.h" +#include "utilmoneystr.h" #include "wallet.h" #include "walletdb.h" @@ -230,15 +232,20 @@ Value setaccount(const Array& params, bool fHelp) if (params.size() > 1) strAccount = AccountFromValue(params[1]); - // Detect when changing the account of an address that is the 'unused current key' of another account: - if (pwalletMain->mapAddressBook.count(address.Get())) + // Only add the account if the address is yours. + if (IsMine(*pwalletMain, address.Get())) { - string strOldAccount = pwalletMain->mapAddressBook[address.Get()].name; - if (address == GetAccountAddress(strOldAccount)) - GetAccountAddress(strOldAccount, true); + // Detect when changing the account of an address that is the 'unused current key' of another account: + if (pwalletMain->mapAddressBook.count(address.Get())) + { + string strOldAccount = pwalletMain->mapAddressBook[address.Get()].name; + if (address == GetAccountAddress(strOldAccount)) + GetAccountAddress(strOldAccount, true); + } + pwalletMain->SetAddressBook(address.Get(), strAccount, "receive"); } - - pwalletMain->SetAddressBook(address.Get(), strAccount, "receive"); + else + throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address"); return Value::null; } @@ -303,12 +310,46 @@ Value getaddressesbyaccount(const Array& params, bool fHelp) return ret; } +void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew) +{ + // Check amount + if (nValue <= 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); + + if (nValue > pwalletMain->GetBalance()) + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + + string strError; + if (pwalletMain->IsLocked()) + { + strError = "Error: Wallet locked, unable to create transaction!"; + LogPrintf("SendMoney() : %s", strError); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + + // Parse Bitcoin address + CScript scriptPubKey = GetScriptForDestination(address); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired; + if (!pwalletMain->CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError)) + { + if (nValue + nFeeRequired > pwalletMain->GetBalance()) + strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired)); + LogPrintf("SendMoney() : %s\n", strError); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + if (!pwalletMain->CommitTransaction(wtxNew, reservekey)) + throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); +} + Value sendtoaddress(const Array& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 4) throw runtime_error( "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" )\n" - "\nSent an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n" + "\nSend an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n" + HelpRequiringPassphrase() + "\nArguments:\n" "1. \"bitcoinaddress\" (string, required) The bitcoin address to send to.\n" @@ -331,7 +372,7 @@ Value sendtoaddress(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); // Amount - int64_t nAmount = AmountFromValue(params[1]); + CAmount nAmount = AmountFromValue(params[1]); // Wallet comments CWalletTx wtx; @@ -342,9 +383,7 @@ Value sendtoaddress(const Array& params, bool fHelp) EnsureWalletIsUnlocked(); - string strError = pwalletMain->SendMoney(address.Get(), nAmount, wtx); - if (strError != "") - throw JSONRPCError(RPC_WALLET_ERROR, strError); + SendMoney(address.Get(), nAmount, wtx); return wtx.GetHash().GetHex(); } @@ -375,7 +414,7 @@ Value listaddressgroupings(const Array& params, bool fHelp) ); Array jsonGroupings; - map<CTxDestination, int64_t> balances = pwalletMain->GetAddressBalances(); + map<CTxDestination, CAmount> balances = pwalletMain->GetAddressBalances(); BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings()) { Array jsonGrouping; @@ -483,7 +522,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) nMinDepth = params[1].get_int(); // Tally - int64_t nAmount = 0; + CAmount nAmount = 0; for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; @@ -532,7 +571,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) set<CTxDestination> setAddress = pwalletMain->GetAccountAddresses(strAccount); // Tally - int64_t nAmount = 0; + CAmount nAmount = 0; for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; @@ -552,9 +591,9 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) } -int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth, const isminefilter& filter) +CAmount GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth, const isminefilter& filter) { - int64_t nBalance = 0; + CAmount nBalance = 0; // Tally wallet transactions for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) @@ -563,7 +602,7 @@ int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi if (!IsFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0) continue; - int64_t nReceived, nSent, nFee; + CAmount nReceived, nSent, nFee; wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter); if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) @@ -577,7 +616,7 @@ int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi return nBalance; } -int64_t GetAccountBalance(const string& strAccount, int nMinDepth, const isminefilter& filter) +CAmount GetAccountBalance(const string& strAccount, int nMinDepth, const isminefilter& filter) { CWalletDB walletdb(pwalletMain->strWalletFile); return GetAccountBalance(walletdb, strAccount, nMinDepth, filter); @@ -627,14 +666,14 @@ Value getbalance(const Array& params, bool fHelp) // Calculate total balance a different way from GetBalance() // (GetBalance() sums up all unspent TxOuts) // getbalance and getbalance '*' 0 should return the same number - int64_t nBalance = 0; + 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) continue; - int64_t allFee; + CAmount allFee; string strSentAccount; list<COutputEntry> listReceived; list<COutputEntry> listSent; @@ -653,7 +692,7 @@ Value getbalance(const Array& params, bool fHelp) string strAccount = AccountFromValue(params[0]); - int64_t nBalance = GetAccountBalance(strAccount, nMinDepth, filter); + CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, filter); return ValueFromAmount(nBalance); } @@ -692,7 +731,7 @@ Value movecmd(const Array& params, bool fHelp) string strFrom = AccountFromValue(params[0]); string strTo = AccountFromValue(params[1]); - int64_t nAmount = AmountFromValue(params[2]); + CAmount nAmount = AmountFromValue(params[2]); if (params.size() > 3) // unused parameter, used to be nMinDepth, keep type-checking it though (void)params[3].get_int(); @@ -766,7 +805,7 @@ Value sendfrom(const Array& params, bool fHelp) CBitcoinAddress address(params[1].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); - int64_t nAmount = AmountFromValue(params[2]); + CAmount nAmount = AmountFromValue(params[2]); int nMinDepth = 1; if (params.size() > 3) nMinDepth = params[3].get_int(); @@ -781,14 +820,11 @@ Value sendfrom(const Array& params, bool fHelp) EnsureWalletIsUnlocked(); // Check funds - int64_t nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); + CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); if (nAmount > nBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); - // Send - string strError = pwalletMain->SendMoney(address.Get(), nAmount, wtx); - if (strError != "") - throw JSONRPCError(RPC_WALLET_ERROR, strError); + SendMoney(address.Get(), nAmount, wtx); return wtx.GetHash().GetHex(); } @@ -834,9 +870,9 @@ Value sendmany(const Array& params, bool fHelp) wtx.mapValue["comment"] = params[3].get_str(); set<CBitcoinAddress> setAddress; - vector<pair<CScript, int64_t> > vecSend; + vector<pair<CScript, CAmount> > vecSend; - int64_t totalAmount = 0; + CAmount totalAmount = 0; BOOST_FOREACH(const Pair& s, sendTo) { CBitcoinAddress address(s.name_); @@ -848,7 +884,7 @@ Value sendmany(const Array& params, bool fHelp) setAddress.insert(address); CScript scriptPubKey = GetScriptForDestination(address.Get()); - int64_t nAmount = AmountFromValue(s.value_); + CAmount nAmount = AmountFromValue(s.value_); totalAmount += nAmount; vecSend.push_back(make_pair(scriptPubKey, nAmount)); @@ -857,13 +893,13 @@ Value sendmany(const Array& params, bool fHelp) EnsureWalletIsUnlocked(); // Check funds - int64_t nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); + CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); if (totalAmount > nBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); // Send CReserveKey keyChange(pwalletMain); - int64_t nFeeRequired = 0; + CAmount nFeeRequired = 0; string strFailReason; bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, strFailReason); if (!fCreated) @@ -913,7 +949,7 @@ Value addmultisigaddress(const Array& params, bool fHelp) // Construct using pay-to-script-hash: CScript inner = _createmultisig_redeemScript(params); - CScriptID innerID = inner.GetID(); + CScriptID innerID(inner); pwalletMain->AddCScript(inner); pwalletMain->SetAddressBook(innerID, strAccount, "send"); @@ -923,7 +959,7 @@ Value addmultisigaddress(const Array& params, bool fHelp) struct tallyitem { - int64_t nAmount; + CAmount nAmount; int nConf; vector<uint256> txids; bool fIsWatchonly; @@ -995,7 +1031,7 @@ Value ListReceived(const Array& params, bool fByAccounts) if (it == mapTally.end() && !fIncludeEmpty) continue; - int64_t nAmount = 0; + CAmount nAmount = 0; int nConf = std::numeric_limits<int>::max(); bool fIsWatchonly = false; if (it != mapTally.end()) @@ -1038,7 +1074,7 @@ Value ListReceived(const Array& params, bool fByAccounts) { for (map<string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it) { - int64_t nAmount = (*it).second.nAmount; + CAmount nAmount = (*it).second.nAmount; int nConf = (*it).second.nConf; Object obj; if((*it).second.fIsWatchonly) @@ -1061,13 +1097,13 @@ Value listreceivedbyaddress(const Array& params, bool fHelp) "\nList balances by receiving address.\n" "\nArguments:\n" "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n" - "2. includeempty (numeric, optional, dafault=false) Whether to include addresses that haven't received any payments.\n" + "2. includeempty (numeric, optional, default=false) Whether to include addresses that haven't received any payments.\n" "3. includeWatchonly (bool, optional, default=false) Whether to include watchonly addresses (see 'importaddress').\n" "\nResult:\n" "[\n" " {\n" - " \"involvesWatchonly\" : \"true\", (bool) Only returned if imported addresses were involved in transaction\n" + " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n" " \"address\" : \"receivingaddress\", (string) The receiving address\n" " \"account\" : \"accountname\", (string) 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" @@ -1099,7 +1135,7 @@ Value listreceivedbyaccount(const Array& params, bool fHelp) "\nResult:\n" "[\n" " {\n" - " \"involvesWatchonly\" : \"true\", (bool) Only returned if imported addresses were involved in transaction\n" + " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n" " \"account\" : \"accountname\", (string) The account name of the receiving account\n" " \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n" " \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n" @@ -1125,7 +1161,7 @@ static void MaybePushAddress(Object & entry, const CTxDestination &dest) void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret, const isminefilter& filter) { - int64_t nFee; + CAmount nFee; string strSentAccount; list<COutputEntry> listReceived; list<COutputEntry> listSent; @@ -1329,7 +1365,7 @@ Value listaccounts(const Array& params, bool fHelp) "listaccounts ( minconf includeWatchonly)\n" "\nReturns Object that has account names as keys, account balances as values.\n" "\nArguments:\n" - "1. minconf (numeric, optional, default=1) Only onclude transactions with at least this many confirmations\n" + "1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n" "2. includeWatchonly (bool, optional, default=false) Include balances in watchonly addresses (see 'importaddress')\n" "\nResult:\n" "{ (json object where keys are account names, and values are numeric balances\n" @@ -1355,7 +1391,7 @@ Value listaccounts(const Array& params, bool fHelp) if(params[1].get_bool()) includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY; - map<string, int64_t> mapAccountBalances; + map<string, CAmount> mapAccountBalances; BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& entry, pwalletMain->mapAddressBook) { if (IsMine(*pwalletMain, entry.first) & includeWatchonly) // This address belongs to me mapAccountBalances[entry.second.name] = 0; @@ -1364,7 +1400,7 @@ Value listaccounts(const Array& params, bool fHelp) for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; - int64_t nFee; + CAmount nFee; string strSentAccount; list<COutputEntry> listReceived; list<COutputEntry> listSent; @@ -1391,7 +1427,7 @@ Value listaccounts(const Array& params, bool fHelp) mapAccountBalances[entry.strAccount] += entry.nCreditDebit; Object ret; - BOOST_FOREACH(const PAIRTYPE(string, int64_t)& accountBalance, mapAccountBalances) { + BOOST_FOREACH(const PAIRTYPE(string, CAmount)& accountBalance, mapAccountBalances) { ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second))); } return ret; @@ -1534,10 +1570,10 @@ Value gettransaction(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); const CWalletTx& wtx = pwalletMain->mapWallet[hash]; - int64_t nCredit = wtx.GetCredit(filter != 0); - int64_t nDebit = wtx.GetDebit(filter); - int64_t nNet = nCredit - nDebit; - int64_t nFee = (wtx.IsFromMe(filter) ? wtx.GetValueOut() - nDebit : 0); + CAmount nCredit = wtx.GetCredit(filter); + CAmount nDebit = wtx.GetDebit(filter); + CAmount nNet = nCredit - nDebit; + CAmount nFee = (wtx.IsFromMe(filter) ? wtx.GetValueOut() - nDebit : 0); entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee))); if (wtx.IsFromMe(filter)) @@ -1937,7 +1973,7 @@ Value settxfee(const Array& params, bool fHelp) ); // Amount - int64_t nAmount = 0; + CAmount nAmount = 0; if (params[0].get_real() != 0.0) nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp new file mode 100644 index 0000000000..c8dd54a747 --- /dev/null +++ b/src/script/bitcoinconsensus.cpp @@ -0,0 +1,91 @@ +// 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. + +#include "bitcoinconsensus.h" + +#include "primitives/transaction.h" +#include "script/interpreter.h" +#include "version.h" + +namespace { + +/** A class that deserializes a single CTransaction one time. */ +class TxInputStream +{ +public: + TxInputStream(int nTypeIn, int nVersionIn, const unsigned char *txTo, size_t txToLen) : + m_type(nTypeIn), + m_version(nVersionIn), + m_data(txTo), + m_remaining(txToLen) + {} + + TxInputStream& read(char* pch, size_t nSize) + { + if (nSize > m_remaining) + throw std::ios_base::failure(std::string(__func__) + ": end of data"); + + if (pch == NULL) + throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer"); + + if (m_data == NULL) + throw std::ios_base::failure(std::string(__func__) + ": bad source buffer"); + + memcpy(pch, m_data, nSize); + m_remaining -= nSize; + m_data += nSize; + return *this; + } + + template<typename T> + TxInputStream& operator>>(T& obj) + { + ::Unserialize(*this, obj, m_type, m_version); + return *this; + } + +private: + const int m_type; + const int m_version; + const unsigned char* m_data; + size_t m_remaining; +}; + +inline int set_error(bitcoinconsensus_error* ret, bitcoinconsensus_error serror) +{ + if (ret) + *ret = serror; + return 0; +} + +} // anon namespace + +int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, + const unsigned char *txTo , unsigned int txToLen, + unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err) +{ + try { + TxInputStream stream(SER_NETWORK, PROTOCOL_VERSION, txTo, txToLen); + CTransaction tx; + stream >> tx; + if (nIn >= tx.vin.size()) + return set_error(err, bitcoinconsensus_ERR_TX_INDEX); + if (tx.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION) != txToLen) + return set_error(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH); + + // Regardless of the verification result, the tx did not error. + set_error(err, bitcoinconsensus_ERR_OK); + + return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, SignatureChecker(tx, nIn), NULL); + } catch (const std::exception&) { + return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing + } +} + +unsigned int bitcoinconsensus_version() +{ + // Just use the API version for now + return BITCOINCONSENSUS_API_VER; +} diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h new file mode 100644 index 0000000000..9d9c266435 --- /dev/null +++ b/src/script/bitcoinconsensus.h @@ -0,0 +1,67 @@ +// 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_BITCOINCONSENSUS_H +#define BITCOIN_BITCOINCONSENSUS_H + +#if defined(BUILD_BITCOIN_INTERNAL) && defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" + #if defined(_WIN32) + #if defined(DLL_EXPORT) + #if defined(HAVE_FUNC_ATTRIBUTE_DLLEXPORT) + #define EXPORT_SYMBOL __declspec(dllexport) + #else + #define EXPORT_SYMBOL + #endif + #endif + #elif defined(HAVE_FUNC_ATTRIBUTE_VISIBILITY) + #define EXPORT_SYMBOL __attribute__ ((visibility ("default"))) + #endif +#elif defined(MSC_VER) && !defined(STATIC_LIBBITCOINCONSENSUS) + #define EXPORT_SYMBOL __declspec(dllimport) +#endif + +#ifndef EXPORT_SYMBOL + #define EXPORT_SYMBOL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define BITCOINCONSENSUS_API_VER 0 + +typedef enum bitcoinconsensus_error_t +{ + bitcoinconsensus_ERR_OK = 0, + bitcoinconsensus_ERR_TX_INDEX, + bitcoinconsensus_ERR_TX_SIZE_MISMATCH, + bitcoinconsensus_ERR_TX_DESERIALIZE, +} bitcoinconsensus_error; + +/** Script verification flags */ +enum +{ + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0, + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts +}; + +/// Returns 1 if the input nIn of the serialized transaction pointed to by +/// txTo correctly spends the scriptPubKey pointed to by scriptPubKey under +/// the additional constraints specified by flags. +/// If not NULL, err will contain an error/success code for the operation +EXPORT_SYMBOL int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, + const unsigned char *txTo , unsigned int txToLen, + unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err); + +EXPORT_SYMBOL unsigned int bitcoinconsensus_version(); + +#ifdef __cplusplus +} // extern "C" +#endif + +#undef EXPORT_SYMBOL + +#endif // BITCOIN_BITCOINCONSENSUS_H diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index fd3e4f1ff7..80a32e78f9 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1,32 +1,40 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "interpreter.h" -#include "core.h" +#include "primitives/transaction.h" #include "crypto/ripemd160.h" #include "crypto/sha1.h" -#include "crypto/sha2.h" -#include "random.h" +#include "crypto/sha256.h" +#include "eccryptoverify.h" +#include "pubkey.h" #include "script/script.h" #include "uint256.h" -#include "util.h" - -#include <boost/thread.hpp> -#include <boost/tuple/tuple_comparison.hpp> using namespace std; typedef vector<unsigned char> valtype; -static const valtype vchFalse(0); -static const valtype vchZero(0); -static const valtype vchTrue(1, 1); -static const CScriptNum bnZero(0); -static const CScriptNum bnOne(1); -static const CScriptNum bnFalse(0); -static const CScriptNum bnTrue(1); + +namespace { + +inline bool set_success(ScriptError* ret) +{ + if (ret) + *ret = SCRIPT_ERR_OK; + return true; +} + +inline bool set_error(ScriptError* ret, const ScriptError serror) +{ + if (ret) + *ret = serror; + return false; +} + +} // anon namespace bool CastToBool(const valtype& vch) { @@ -43,10 +51,10 @@ bool CastToBool(const valtype& vch) return false; } -// -// Script is a stack machine (like Forth) that evaluates a predicate -// returning a bool indicating valid or not. There are no loops. -// +/** + * Script is a stack machine (like Forth) that evaluates a predicate + * returning a bool indicating valid or not. There are no loops. + */ #define stacktop(i) (stack.at(stack.size()+(i))) #define altstacktop(i) (altstack.at(altstack.size()+(i))) static inline void popstack(vector<valtype>& stack) @@ -56,84 +64,182 @@ static inline void popstack(vector<valtype>& stack) stack.pop_back(); } -bool IsCanonicalPubKey(const valtype &vchPubKey, unsigned int flags) { - if (!(flags & SCRIPT_VERIFY_STRICTENC)) - return true; - - if (vchPubKey.size() < 33) - return error("Non-canonical public key: too short"); +bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { + if (vchPubKey.size() < 33) { + // Non-canonical public key: too short + return false; + } if (vchPubKey[0] == 0x04) { - if (vchPubKey.size() != 65) - return error("Non-canonical public key: invalid length for uncompressed key"); + if (vchPubKey.size() != 65) { + // Non-canonical public key: invalid length for uncompressed key + return false; + } } else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) { - if (vchPubKey.size() != 33) - return error("Non-canonical public key: invalid length for compressed key"); + if (vchPubKey.size() != 33) { + // Non-canonical public key: invalid length for compressed key + return false; + } } else { - return error("Non-canonical public key: neither compressed nor uncompressed"); + // Non-canonical public key: neither compressed nor uncompressed + return false; } return true; } -bool IsCanonicalSignature(const valtype &vchSig, unsigned int flags) { - if (!(flags & SCRIPT_VERIFY_STRICTENC)) - return true; - - // See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 - // A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype> - // Where R and S are not negative (their first byte has its highest bit not set), and not - // excessively padded (do not start with a 0 byte, unless an otherwise negative number follows, - // in which case a single 0 byte is necessary and even required). - if (vchSig.size() < 9) - return error("Non-canonical signature: too short"); - if (vchSig.size() > 73) - return error("Non-canonical signature: too long"); - unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY)); - if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE) - return error("Non-canonical signature: unknown hashtype byte"); - if (vchSig[0] != 0x30) - return error("Non-canonical signature: wrong type"); - if (vchSig[1] != vchSig.size()-3) - return error("Non-canonical signature: wrong length marker"); +/** + * A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype> + * Where R and S are not negative (their first byte has its highest bit not set), and not + * excessively padded (do not start with a 0 byte, unless an otherwise negative number follows, + * in which case a single 0 byte is necessary and even required). + * + * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 + */ +bool static IsDERSignature(const valtype &vchSig) { + + if (vchSig.size() < 9) { + // Non-canonical signature: too short + return false; + } + if (vchSig.size() > 73) { + // Non-canonical signature: too long + return false; + } + if (vchSig[0] != 0x30) { + // Non-canonical signature: wrong type + return false; + } + if (vchSig[1] != vchSig.size()-3) { + // Non-canonical signature: wrong length marker + return false; + } unsigned int nLenR = vchSig[3]; - if (5 + nLenR >= vchSig.size()) - return error("Non-canonical signature: S length misplaced"); + if (5 + nLenR >= vchSig.size()) { + // Non-canonical signature: S length misplaced + return false; + } unsigned int nLenS = vchSig[5+nLenR]; - if ((unsigned long)(nLenR+nLenS+7) != vchSig.size()) - return error("Non-canonical signature: R+S length mismatch"); + if ((unsigned long)(nLenR+nLenS+7) != vchSig.size()) { + // Non-canonical signature: R+S length mismatch + return false; + } const unsigned char *R = &vchSig[4]; - if (R[-2] != 0x02) - return error("Non-canonical signature: R value type mismatch"); - if (nLenR == 0) - return error("Non-canonical signature: R length is zero"); - if (R[0] & 0x80) - return error("Non-canonical signature: R value negative"); - if (nLenR > 1 && (R[0] == 0x00) && !(R[1] & 0x80)) - return error("Non-canonical signature: R value excessively padded"); + if (R[-2] != 0x02) { + // Non-canonical signature: R value type mismatch + return false; + } + if (nLenR == 0) { + // Non-canonical signature: R length is zero + return false; + } + if (R[0] & 0x80) { + // Non-canonical signature: R value negative + return false; + } + if (nLenR > 1 && (R[0] == 0x00) && !(R[1] & 0x80)) { + // Non-canonical signature: R value excessively padded + return false; + } const unsigned char *S = &vchSig[6+nLenR]; - if (S[-2] != 0x02) - return error("Non-canonical signature: S value type mismatch"); - if (nLenS == 0) - return error("Non-canonical signature: S length is zero"); - if (S[0] & 0x80) - return error("Non-canonical signature: S value negative"); - if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80)) - return error("Non-canonical signature: S value excessively padded"); - - if (flags & SCRIPT_VERIFY_LOW_S) { - // If the S value is above the order of the curve divided by two, its - // complement modulo the order could have been used instead, which is - // one byte shorter when encoded correctly. - if (!CKey::CheckSignatureElement(S, nLenS, true)) - return error("Non-canonical signature: S value is unnecessarily high"); + if (S[-2] != 0x02) { + // Non-canonical signature: S value type mismatch + return false; + } + if (nLenS == 0) { + // Non-canonical signature: S length is zero + return false; + } + if (S[0] & 0x80) { + // Non-canonical signature: S value negative + return false; + } + if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80)) { + // Non-canonical signature: S value excessively padded + return false; + } + return true; +} + +bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) { + if (!IsDERSignature(vchSig)) { + return set_error(serror, SCRIPT_ERR_SIG_DER); } + unsigned int nLenR = vchSig[3]; + unsigned int nLenS = vchSig[5+nLenR]; + const unsigned char *S = &vchSig[6+nLenR]; + // If the S value is above the order of the curve divided by two, its + // complement modulo the order could have been used instead, which is + // one byte shorter when encoded correctly. + if (!eccrypto::CheckSignatureElement(S, nLenS, true)) + return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); return true; } -bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags) +bool static IsDefinedHashtypeSignature(const valtype &vchSig) { + if (vchSig.size() == 0) { + return false; + } + unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY)); + if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE) + return false; + + return true; +} + +bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { + if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsDERSignature(vchSig)) { + return set_error(serror, SCRIPT_ERR_SIG_DER); + } else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) { + // serror is set + return false; + } else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature(vchSig)) { + return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE); + } + return true; +} + +bool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { + if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchSig)) { + return set_error(serror, SCRIPT_ERR_PUBKEYTYPE); + } + return true; +} + +bool static CheckMinimalPush(const valtype& data, opcodetype opcode) { + if (data.size() == 0) { + // Could have used OP_0. + return opcode == OP_0; + } else if (data.size() == 1 && data[0] >= 1 && data[0] <= 16) { + // Could have used OP_1 .. OP_16. + return opcode == OP_1 + (data[0] - 1); + } else if (data.size() == 1 && data[0] == 0x81) { + // Could have used OP_1NEGATE. + return opcode == OP_1NEGATE; + } else if (data.size() <= 75) { + // Could have used a direct push (opcode indicating number of bytes pushed + those bytes). + return opcode == data.size(); + } else if (data.size() <= 255) { + // Could have used OP_PUSHDATA. + return opcode == OP_PUSHDATA1; + } else if (data.size() <= 65535) { + // Could have used OP_PUSHDATA2. + return opcode == OP_PUSHDATA2; + } + return true; +} + +bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) { + static const CScriptNum bnZero(0); + static const CScriptNum bnOne(1); + static const CScriptNum bnFalse(0); + static const CScriptNum bnTrue(1); + static const valtype vchFalse(0); + static const valtype vchZero(0); + static const valtype vchTrue(1, 1); + CScript::const_iterator pc = script.begin(); CScript::const_iterator pend = script.end(); CScript::const_iterator pbegincodehash = script.begin(); @@ -141,9 +247,11 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co valtype vchPushValue; vector<bool> vfExec; vector<valtype> altstack; + set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); if (script.size() > 10000) - return false; + return set_error(serror, SCRIPT_ERR_SCRIPT_SIZE); int nOpCount = 0; + bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0; try { @@ -155,13 +263,13 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co // Read instruction // if (!script.GetOp(pc, opcode, vchPushValue)) - return false; + return set_error(serror, SCRIPT_ERR_BAD_OPCODE); if (vchPushValue.size() > MAX_SCRIPT_ELEMENT_SIZE) - return false; + return set_error(serror, SCRIPT_ERR_PUSH_SIZE); // Note how OP_RESERVED does not count towards the opcode limit. if (opcode > OP_16 && ++nOpCount > 201) - return false; + return set_error(serror, SCRIPT_ERR_OP_COUNT); if (opcode == OP_CAT || opcode == OP_SUBSTR || @@ -178,11 +286,14 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co opcode == OP_MOD || opcode == OP_LSHIFT || opcode == OP_RSHIFT) - return false; // Disabled opcodes. + return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); // Disabled opcodes. - if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) + if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) { + if (fRequireMinimal && !CheckMinimalPush(vchPushValue, opcode)) { + return set_error(serror, SCRIPT_ERR_MINIMALDATA); + } stack.push_back(vchPushValue); - else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) + } else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) switch (opcode) { // @@ -209,6 +320,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co // ( -- value) CScriptNum bn((int)opcode - (int)(OP_1 - 1)); stack.push_back(bn.getvch()); + // The result of these opcodes should always be the minimal way to push the data + // they push, so no need for a CheckMinimalPush here. } break; @@ -217,8 +330,14 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co // Control // case OP_NOP: + break; + case OP_NOP1: case OP_NOP2: 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) + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); + } break; case OP_IF: @@ -229,7 +348,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co if (fExec) { if (stack.size() < 1) - return false; + return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); valtype& vch = stacktop(-1); fValue = CastToBool(vch); if (opcode == OP_NOTIF) @@ -243,7 +362,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co case OP_ELSE: { if (vfExec.empty()) - return false; + return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); vfExec.back() = !vfExec.back(); } break; @@ -251,7 +370,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co case OP_ENDIF: { if (vfExec.empty()) - return false; + return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); vfExec.pop_back(); } break; @@ -261,18 +380,18 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co // (true -- ) or // (false -- false) and return if (stack.size() < 1) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); bool fValue = CastToBool(stacktop(-1)); if (fValue) popstack(stack); else - return false; + return set_error(serror, SCRIPT_ERR_VERIFY); } break; case OP_RETURN: { - return false; + return set_error(serror, SCRIPT_ERR_OP_RETURN); } break; @@ -283,7 +402,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co case OP_TOALTSTACK: { if (stack.size() < 1) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); altstack.push_back(stacktop(-1)); popstack(stack); } @@ -292,7 +411,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co case OP_FROMALTSTACK: { if (altstack.size() < 1) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_ALTSTACK_OPERATION); stack.push_back(altstacktop(-1)); popstack(altstack); } @@ -302,7 +421,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x1 x2 -- ) if (stack.size() < 2) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); popstack(stack); popstack(stack); } @@ -312,7 +431,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x1 x2 -- x1 x2 x1 x2) if (stack.size() < 2) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch1 = stacktop(-2); valtype vch2 = stacktop(-1); stack.push_back(vch1); @@ -324,7 +443,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) if (stack.size() < 3) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch1 = stacktop(-3); valtype vch2 = stacktop(-2); valtype vch3 = stacktop(-1); @@ -338,7 +457,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) if (stack.size() < 4) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch1 = stacktop(-4); valtype vch2 = stacktop(-3); stack.push_back(vch1); @@ -350,7 +469,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) if (stack.size() < 6) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch1 = stacktop(-6); valtype vch2 = stacktop(-5); stack.erase(stack.end()-6, stack.end()-4); @@ -363,7 +482,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x1 x2 x3 x4 -- x3 x4 x1 x2) if (stack.size() < 4) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); swap(stacktop(-4), stacktop(-2)); swap(stacktop(-3), stacktop(-1)); } @@ -373,7 +492,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x - 0 | x x) if (stack.size() < 1) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-1); if (CastToBool(vch)) stack.push_back(vch); @@ -392,7 +511,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x -- ) if (stack.size() < 1) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); popstack(stack); } break; @@ -401,7 +520,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x -- x x) if (stack.size() < 1) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-1); stack.push_back(vch); } @@ -411,7 +530,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x1 x2 -- x2) if (stack.size() < 2) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); stack.erase(stack.end() - 2); } break; @@ -420,7 +539,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x1 x2 -- x1 x2 x1) if (stack.size() < 2) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-2); stack.push_back(vch); } @@ -432,11 +551,11 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) if (stack.size() < 2) - return false; - int n = CScriptNum(stacktop(-1)).getint(); + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + int n = CScriptNum(stacktop(-1), fRequireMinimal).getint(); popstack(stack); if (n < 0 || n >= (int)stack.size()) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-n-1); if (opcode == OP_ROLL) stack.erase(stack.end()-n-1); @@ -450,7 +569,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co // x2 x1 x3 after first swap // x2 x3 x1 after second swap if (stack.size() < 3) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); swap(stacktop(-3), stacktop(-2)); swap(stacktop(-2), stacktop(-1)); } @@ -460,7 +579,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x1 x2 -- x2 x1) if (stack.size() < 2) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); swap(stacktop(-2), stacktop(-1)); } break; @@ -469,7 +588,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x1 x2 -- x2 x1 x2) if (stack.size() < 2) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-1); stack.insert(stack.end()-2, vch); } @@ -480,7 +599,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (in -- in size) if (stack.size() < 1) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); CScriptNum bn(stacktop(-1).size()); stack.push_back(bn.getvch()); } @@ -496,7 +615,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x1 x2 - bool) if (stack.size() < 2) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype& vch1 = stacktop(-2); valtype& vch2 = stacktop(-1); bool fEqual = (vch1 == vch2); @@ -513,7 +632,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co if (fEqual) popstack(stack); else - return false; + return set_error(serror, SCRIPT_ERR_EQUALVERIFY); } } break; @@ -531,8 +650,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (in -- out) if (stack.size() < 1) - return false; - CScriptNum bn(stacktop(-1)); + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + CScriptNum bn(stacktop(-1), fRequireMinimal); switch (opcode) { case OP_1ADD: bn += bnOne; break; @@ -564,9 +683,9 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x1 x2 -- out) if (stack.size() < 2) - return false; - CScriptNum bn1(stacktop(-2)); - CScriptNum bn2(stacktop(-1)); + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + CScriptNum bn1(stacktop(-2), fRequireMinimal); + CScriptNum bn2(stacktop(-1), fRequireMinimal); CScriptNum bn(0); switch (opcode) { @@ -600,7 +719,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co if (CastToBool(stacktop(-1))) popstack(stack); else - return false; + return set_error(serror, SCRIPT_ERR_NUMEQUALVERIFY); } } break; @@ -609,10 +728,10 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (x min max -- out) if (stack.size() < 3) - return false; - CScriptNum bn1(stacktop(-3)); - CScriptNum bn2(stacktop(-2)); - CScriptNum bn3(stacktop(-1)); + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + CScriptNum bn1(stacktop(-3), fRequireMinimal); + CScriptNum bn2(stacktop(-2), fRequireMinimal); + CScriptNum bn3(stacktop(-1), fRequireMinimal); bool fValue = (bn2 <= bn1 && bn1 < bn3); popstack(stack); popstack(stack); @@ -633,23 +752,23 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (in -- hash) if (stack.size() < 1) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype& vch = stacktop(-1); valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); if (opcode == OP_RIPEMD160) - CRIPEMD160().Write(&vch[0], vch.size()).Finalize(&vchHash[0]); + CRIPEMD160().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); else if (opcode == OP_SHA1) - CSHA1().Write(&vch[0], vch.size()).Finalize(&vchHash[0]); + CSHA1().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); else if (opcode == OP_SHA256) - CSHA256().Write(&vch[0], vch.size()).Finalize(&vchHash[0]); + CSHA256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); else if (opcode == OP_HASH160) - CHash160().Write(&vch[0], vch.size()).Finalize(&vchHash[0]); + CHash160().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); else if (opcode == OP_HASH256) - CHash256().Write(&vch[0], vch.size()).Finalize(&vchHash[0]); + CHash256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); popstack(stack); stack.push_back(vchHash); } - break; + break; case OP_CODESEPARATOR: { @@ -663,7 +782,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co { // (sig pubkey -- bool) if (stack.size() < 2) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype& vchSig = stacktop(-2); valtype& vchPubKey = stacktop(-1); @@ -674,8 +793,11 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co // Drop the signature, since there's no way for a signature to sign itself scriptCode.FindAndDelete(CScript(vchSig)); - bool fSuccess = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) && - CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, flags); + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { + //serror is set + return false; + } + bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode); popstack(stack); popstack(stack); @@ -685,7 +807,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co if (fSuccess) popstack(stack); else - return false; + return set_error(serror, SCRIPT_ERR_CHECKSIGVERIFY); } } break; @@ -697,26 +819,26 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co int i = 1; if ((int)stack.size() < i) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - int nKeysCount = CScriptNum(stacktop(-i)).getint(); + int nKeysCount = CScriptNum(stacktop(-i), fRequireMinimal).getint(); if (nKeysCount < 0 || nKeysCount > 20) - return false; + return set_error(serror, SCRIPT_ERR_PUBKEY_COUNT); nOpCount += nKeysCount; if (nOpCount > 201) - return false; + return set_error(serror, SCRIPT_ERR_OP_COUNT); int ikey = ++i; i += nKeysCount; if ((int)stack.size() < i) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - int nSigsCount = CScriptNum(stacktop(-i)).getint(); + int nSigsCount = CScriptNum(stacktop(-i), fRequireMinimal).getint(); if (nSigsCount < 0 || nSigsCount > nKeysCount) - return false; + return set_error(serror, SCRIPT_ERR_SIG_COUNT); int isig = ++i; i += nSigsCount; if ((int)stack.size() < i) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); @@ -734,9 +856,16 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co valtype& vchSig = stacktop(-isig); valtype& vchPubKey = stacktop(-ikey); + // Note how this makes the exact order of pubkey/signature evaluation + // distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set. + // See the script_(in)valid tests for details. + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { + // serror is set + return false; + } + // Check signature - bool fOk = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) && - CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, flags); + bool fOk = checker.CheckSig(vchSig, vchPubKey, scriptCode); if (fOk) { isig++; @@ -746,7 +875,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co nKeysCount--; // If there are more signatures left than keys left, - // then too many signatures have failed + // then too many signatures have failed. Exit early, + // without checking any further signatures. if (nSigsCount > nKeysCount) fSuccess = false; } @@ -762,9 +892,9 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co // so optionally verify it is exactly equal to zero prior // to removing it from the stack. if (stack.size() < 1) - return false; + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); if ((flags & SCRIPT_VERIFY_NULLDUMMY) && stacktop(-1).size()) - return error("CHECKMULTISIG dummy argument not null"); + return set_error(serror, SCRIPT_ERR_SIG_NULLDUMMY); popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); @@ -774,44 +904,45 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co if (fSuccess) popstack(stack); else - return false; + return set_error(serror, SCRIPT_ERR_CHECKMULTISIGVERIFY); } } break; default: - return false; + return set_error(serror, SCRIPT_ERR_BAD_OPCODE); } // Size limits if (stack.size() + altstack.size() > 1000) - return false; + return set_error(serror, SCRIPT_ERR_STACK_SIZE); } } catch (...) { - return false; + return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); } if (!vfExec.empty()) - return false; + return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); - return true; + return set_success(serror); } namespace { -/** Wrapper that serializes like CTransaction, but with the modifications +/** + * Wrapper that serializes like CTransaction, but with the modifications * required for the signature hash done in-place */ class CTransactionSignatureSerializer { private: - const CTransaction &txTo; // reference to the spending transaction (the one being serialized) - const CScript &scriptCode; // output script being consumed - const unsigned int nIn; // input index of txTo being signed - const bool fAnyoneCanPay; // whether the hashtype has the SIGHASH_ANYONECANPAY flag set - const bool fHashSingle; // whether the hashtype is SIGHASH_SINGLE - const bool fHashNone; // whether the hashtype is SIGHASH_NONE + const CTransaction &txTo; //! reference to the spending transaction (the one being serialized) + const CScript &scriptCode; //! output script being consumed + const unsigned int nIn; //! input index of txTo being signed + const bool fAnyoneCanPay; //! whether the hashtype has the SIGHASH_ANYONECANPAY flag set + const bool fHashSingle; //! whether the hashtype is SIGHASH_SINGLE + const bool fHashNone; //! whether the hashtype is SIGHASH_NONE public: CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : @@ -839,7 +970,8 @@ public: itBegin = it; } } - s.write((char*)&itBegin[0], it-itBegin); + if (itBegin != scriptCode.end()) + s.write((char*)&itBegin[0], it-itBegin); } /** Serialize an input of txTo */ @@ -889,24 +1021,24 @@ public: ::WriteCompactSize(s, nOutputs); for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++) SerializeOutput(s, nOutput, nType, nVersion); - // Serialie nLockTime + // Serialize nLockTime ::Serialize(s, txTo.nLockTime, nType, nVersion); } }; } // anon namespace -uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) +uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) { if (nIn >= txTo.vin.size()) { - LogPrintf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); + // nIn out of range return 1; } // Check for invalid use of SIGHASH_SINGLE if ((nHashType & 0x1f) == SIGHASH_SINGLE) { if (nIn >= txTo.vout.size()) { - LogPrintf("ERROR: SignatureHash() : nOut=%d out of range\n", nIn); + // nOut out of range return 1; } } @@ -920,70 +1052,19 @@ uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsig return ss.GetHash(); } -// Valid signature cache, to avoid doing expensive ECDSA signature checking -// twice for every transaction (once when accepted into memory pool, and -// again when accepted into the block chain) -class CSignatureCache +bool SignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const { -private: - // sigdata_type is (signature hash, signature, public key): - typedef boost::tuple<uint256, std::vector<unsigned char>, CPubKey> sigdata_type; - std::set< sigdata_type> setValid; - boost::shared_mutex cs_sigcache; - -public: - bool - Get(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey) - { - boost::shared_lock<boost::shared_mutex> lock(cs_sigcache); - - sigdata_type k(hash, vchSig, pubKey); - std::set<sigdata_type>::iterator mi = setValid.find(k); - if (mi != setValid.end()) - return true; - return false; - } - - void Set(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey) - { - // DoS prevention: limit cache size to less than 10MB - // (~200 bytes per cache entry times 50,000 entries) - // Since there are a maximum of 20,000 signature operations per block - // 50,000 is a reasonable default. - int64_t nMaxCacheSize = GetArg("-maxsigcachesize", 50000); - if (nMaxCacheSize <= 0) return; - - boost::unique_lock<boost::shared_mutex> lock(cs_sigcache); - - while (static_cast<int64_t>(setValid.size()) > nMaxCacheSize) - { - // Evict a random entry. Random because that helps - // foil would-be DoS attackers who might try to pre-generate - // and re-use a set of valid signatures just-slightly-greater - // than our cache size. - uint256 randomHash = GetRandHash(); - std::vector<unsigned char> unused; - std::set<sigdata_type>::iterator it = - setValid.lower_bound(sigdata_type(randomHash, unused, unused)); - if (it == setValid.end()) - it = setValid.begin(); - setValid.erase(*it); - } - - sigdata_type k(hash, vchSig, pubKey); - setValid.insert(k); - } -}; + return pubkey.Verify(sighash, vchSig); +} -bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char>& vchPubKey, const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int flags) +bool SignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vector<unsigned char>& vchPubKey, const CScript& scriptCode) const { - static CSignatureCache signatureCache; - CPubKey pubkey(vchPubKey); if (!pubkey.IsValid()) return false; // Hash type is one byte tacked on to the end of the signature + vector<unsigned char> vchSig(vchSigIn); if (vchSig.empty()) return false; int nHashType = vchSig.back(); @@ -991,38 +1072,41 @@ bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char>& vchPubK uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType); - if (signatureCache.Get(sighash, vchSig, pubkey)) - return true; - - if (!pubkey.Verify(sighash, vchSig)) + if (!VerifySignature(vchSig, pubkey, sighash)) return false; - if (!(flags & SCRIPT_VERIFY_NOCACHE)) - signatureCache.Set(sighash, vchSig, pubkey); - return true; } -bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, unsigned int flags) +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) { + set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); + + if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !scriptSig.IsPushOnly()) { + return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); + } + vector<vector<unsigned char> > stack, stackCopy; - if (!EvalScript(stack, scriptSig, txTo, nIn, flags)) + if (!EvalScript(stack, scriptSig, flags, checker, serror)) + // serror is set return false; if (flags & SCRIPT_VERIFY_P2SH) stackCopy = stack; - if (!EvalScript(stack, scriptPubKey, txTo, nIn, flags)) + if (!EvalScript(stack, scriptPubKey, flags, checker, serror)) + // serror is set return false; if (stack.empty()) - return false; + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); if (CastToBool(stack.back()) == false) - return false; + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); // Additional validation for spend-to-script-hash transactions: if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) { - if (!scriptSig.IsPushOnly()) // scriptSig must be literals-only - return false; // or validation fails + // scriptSig must be literals-only or validation fails + if (!scriptSig.IsPushOnly()) + return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); // stackCopy cannot be empty here, because if it was the // P2SH HASH <> EQUAL scriptPubKey would be evaluated with @@ -1033,12 +1117,16 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); popstack(stackCopy); - if (!EvalScript(stackCopy, pubKey2, txTo, nIn, flags)) + if (!EvalScript(stackCopy, pubKey2, flags, checker, serror)) + // serror is set return false; if (stackCopy.empty()) - return false; - return CastToBool(stackCopy.back()); + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + if (!CastToBool(stackCopy.back())) + return set_error(serror, SCRIPT_ERR_EVAL_FALSE); + else + return set_success(serror); } - return true; + return set_success(serror); } diff --git a/src/script/interpreter.h b/src/script/interpreter.h index adca2142ac..3c4e7d466a 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -1,15 +1,18 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef H_BITCOIN_SCRIPT_INTERPRETER -#define H_BITCOIN_SCRIPT_INTERPRETER +#ifndef BITCOIN_SCRIPT_INTERPRETER_H +#define BITCOIN_SCRIPT_INTERPRETER_H + +#include "script_error.h" #include <vector> #include <stdint.h> #include <string> +class CPubKey; class CScript; class CTransaction; class uint256; @@ -27,19 +30,75 @@ enum enum { SCRIPT_VERIFY_NONE = 0, - SCRIPT_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts - SCRIPT_VERIFY_STRICTENC = (1U << 1), // enforce strict conformance to DER and SEC2 for signatures and pubkeys - SCRIPT_VERIFY_LOW_S = (1U << 2), // enforce low S values (<n/2) in signatures (depends on STRICTENC) - SCRIPT_VERIFY_NOCACHE = (1U << 3), // do not store results in signature cache (but do query it) - SCRIPT_VERIFY_NULLDUMMY = (1U << 4), // verify dummy stack item consumed by CHECKMULTISIG is of zero-length -}; -bool IsCanonicalPubKey(const std::vector<unsigned char> &vchPubKey, unsigned int flags); -bool IsCanonicalSignature(const std::vector<unsigned char> &vchSig, unsigned int flags); + // Evaluate P2SH subscripts (softfork safe, BIP16). + SCRIPT_VERIFY_P2SH = (1U << 0), + + // Passing a non-strict-DER signature or one with undefined hashtype to a checksig operation causes script failure. + // Evaluating a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) by checksig causes script failure. + // (softfork safe, but not used or intended as a consensus rule). + SCRIPT_VERIFY_STRICTENC = (1U << 1), + + // Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1) + SCRIPT_VERIFY_DERSIG = (1U << 2), + + // Passing a non-strict-DER signature or one with S > order/2 to a checksig operation causes script failure + // (softfork safe, BIP62 rule 5). + SCRIPT_VERIFY_LOW_S = (1U << 3), + + // verify dummy stack item consumed by CHECKMULTISIG is of zero-length (softfork safe, BIP62 rule 7). + SCRIPT_VERIFY_NULLDUMMY = (1U << 4), + + // Using a non-push operator in the scriptSig causes script failure (softfork safe, BIP62 rule 2). + SCRIPT_VERIFY_SIGPUSHONLY = (1U << 5), + + // Require minimal encodings for all push operations (OP_0... OP_16, OP_1NEGATE where possible, direct + // pushes up to 75 bytes, OP_PUSHDATA up to 255 bytes, OP_PUSHDATA2 for anything larger). Evaluating + // any other push causes the script to fail (BIP62 rule 3). + // In addition, whenever a stack element is interpreted as a number, it must be of minimal length (BIP62 rule 4). + // (softfork safe) + SCRIPT_VERIFY_MINIMALDATA = (1U << 6), + + // Discourage use of NOPs reserved for upgrades (NOP1-10) + // + // Provided so that nodes can avoid accepting or mining transactions + // containing executed NOP's whose meaning may change after a soft-fork, + // thus rendering the script invalid; with this flag set executing + // discouraged NOPs fails the script. This verification flag will never be + // a mandatory flag applied to scripts in a block. NOPs that are not + // executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected. + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7) + +}; uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); -bool CheckSig(std::vector<unsigned char> vchSig, const std::vector<unsigned char> &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int flags); -bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags); -bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, unsigned int flags); -#endif // H_BITCOIN_SCRIPT_INTERPRETER +class BaseSignatureChecker +{ +public: + virtual bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const + { + return false; + } + + virtual ~BaseSignatureChecker() {} +}; + +class SignatureChecker : public BaseSignatureChecker +{ +private: + const CTransaction& txTo; + unsigned int nIn; + +protected: + virtual bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; + +public: + SignatureChecker(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 EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL); +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL); + +#endif // BITCOIN_SCRIPT_INTERPRETER_H diff --git a/src/script/script.cpp b/src/script/script.cpp index a5126e7cc2..fd33924732 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -1,11 +1,22 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "script.h" -#include <boost/foreach.hpp> +#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; @@ -219,7 +230,7 @@ bool CScript::IsPushOnly() const return false; // Note that IsPushOnly() *does* consider OP_RESERVED to be a // push-type opcode, however execution of OP_RESERVED fails, so - // it's not relevant to P2SH as the scriptSig would fail prior to + // it's not relevant to P2SH/BIP62 as the scriptSig would fail prior to // the P2SH special validation code being executed. if (opcode > OP_16) return false; @@ -227,29 +238,25 @@ bool CScript::IsPushOnly() const return true; } -bool CScript::HasCanonicalPushes() const +std::string CScript::ToString() const { + std::string str; + opcodetype opcode; + std::vector<unsigned char> vch; const_iterator pc = begin(); while (pc < end()) { - opcodetype opcode; - std::vector<unsigned char> data; - if (!GetOp(pc, opcode, data)) - return false; - if (opcode > OP_16) - continue; - if (opcode < OP_PUSHDATA1 && opcode > OP_0 && (data.size() == 1 && data[0] <= 16)) - // Could have used an OP_n code, rather than a 1-byte push. - return false; - if (opcode == OP_PUSHDATA1 && data.size() < OP_PUSHDATA1) - // Could have used a normal n-byte push, rather than OP_PUSHDATA1. - return false; - if (opcode == OP_PUSHDATA2 && data.size() <= 0xFF) - // Could have used an OP_PUSHDATA1. - return false; - if (opcode == OP_PUSHDATA4 && data.size() <= 0xFFFF) - // Could have used an OP_PUSHDATA2. - return false; + 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 true; + return str; } diff --git a/src/script/script.h b/src/script/script.h index 4c9ac74b78..78fd12cd29 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -1,21 +1,28 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef H_BITCOIN_SCRIPT -#define H_BITCOIN_SCRIPT - -#include "key.h" -#include "tinyformat.h" -#include "utilstrencodings.h" +#ifndef BITCOIN_SCRIPT_SCRIPT_H +#define BITCOIN_SCRIPT_SCRIPT_H +#include <assert.h> +#include <climits> +#include <limits> #include <stdexcept> - -#include <boost/variant.hpp> +#include <stdint.h> +#include <string.h> +#include <string> +#include <vector> static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes +template <typename T> +std::vector<unsigned char> ToByteVector(const T& in) +{ + return std::vector<unsigned char>(in.begin(), in.end()); +} + /** Script opcodes */ enum opcodetype { @@ -172,12 +179,14 @@ public: class CScriptNum { -// Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte integers. -// The semantics are subtle, though: operands must be in the range [-2^31 +1...2^31 -1], -// but results may overflow (and are valid as long as they are not used in a subsequent -// numeric operation). CScriptNum enforces those semantics by storing results as -// an int64 and allowing out-of-range values to be returned as a vector of bytes but -// throwing an exception if arithmetic is done or the result is interpreted as an integer. +/** + * Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte integers. + * The semantics are subtle, though: operands must be in the range [-2^31 +1...2^31 -1], + * but results may overflow (and are valid as long as they are not used in a subsequent + * numeric operation). CScriptNum enforces those semantics by storing results as + * an int64 and allowing out-of-range values to be returned as a vector of bytes but + * throwing an exception if arithmetic is done or the result is interpreted as an integer. + */ public: explicit CScriptNum(const int64_t& n) @@ -185,10 +194,29 @@ public: m_value = n; } - explicit CScriptNum(const std::vector<unsigned char>& vch) + explicit CScriptNum(const std::vector<unsigned char>& vch, bool fRequireMinimal) { - if (vch.size() > nMaxNumSize) - throw scriptnum_error("CScriptNum(const std::vector<unsigned char>&) : overflow"); + if (vch.size() > nMaxNumSize) { + throw scriptnum_error("script number overflow"); + } + if (fRequireMinimal && vch.size() > 0) { + // Check that the number is encoded with the minimum possible + // number of bytes. + // + // If the most-significant-byte - excluding the sign bit - is zero + // then we're not minimal. Note how this test also rejects the + // negative-zero encoding, 0x80. + if ((vch.back() & 0x7f) == 0) { + // One exception: if there's more than one byte and the most + // significant bit of the second-most-significant-byte is set + // it would conflict with the sign bit. An example of this case + // is +-255, which encode to 0xff00 and 0xff80 respectively. + // (big-endian). + if (vch.size() <= 1 || (vch[vch.size() - 2] & 0x80) == 0) { + throw scriptnum_error("non-minimally encoded script number"); + } + } + } m_value = set_vch(vch); } @@ -304,7 +332,7 @@ private: // If the input vector's most significant byte is 0x80, remove it from // the result's msb and return a negative. if (vch.back() & 0x80) - return -(result & ~(0x80ULL << (8 * (vch.size() - 1)))); + return -((int64_t)(result & ~(0x80ULL << (8 * (vch.size() - 1))))); return result; } @@ -312,14 +340,6 @@ private: int64_t m_value; }; -inline std::string ValueString(const std::vector<unsigned char>& vch) -{ - if (vch.size() <= 4) - return strprintf("%d", CScriptNum(vch).getint()); - else - return HexStr(vch); -} - /** Serialized script, used inside transaction inputs and outputs */ class CScript : public std::vector<unsigned char> { @@ -330,6 +350,10 @@ protected: { push_back(n + (OP_1 - 1)); } + else if (n == 0) + { + push_back(OP_0); + } else { *this << CScriptNum::serialize(n); @@ -358,7 +382,6 @@ public: CScript(int64_t b) { operator<<(b); } explicit CScript(opcodetype b) { operator<<(b); } - explicit CScript(const uint256& b) { operator<<(b); } explicit CScript(const CScriptNum& b) { operator<<(b); } explicit CScript(const std::vector<unsigned char>& b) { operator<<(b); } @@ -373,28 +396,6 @@ public: return *this; } - CScript& operator<<(const uint160& b) - { - insert(end(), sizeof(b)); - insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); - return *this; - } - - CScript& operator<<(const uint256& b) - { - insert(end(), sizeof(b)); - insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); - return *this; - } - - CScript& operator<<(const CPubKey& key) - { - assert(key.size() < OP_PUSHDATA1); - insert(end(), (unsigned char)key.size()); - insert(end(), key.begin(), key.end()); - return *this; - } - CScript& operator<<(const CScriptNum& b) { *this << b.getvch(); @@ -517,7 +518,7 @@ public: return true; } - // Encode/decode small integers: + /** Encode/decode small integers: */ static int DecodeOP_N(opcodetype opcode) { if (opcode == OP_0) @@ -544,7 +545,7 @@ public: { while (end() - pc >= (long)b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) { - erase(pc, pc + b.size()); + pc = erase(pc, pc + b.size()); ++nFound; } } @@ -561,61 +562,37 @@ public: return nFound; } - // Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs - // as 20 sigops. With pay-to-script-hash, that changed: - // CHECKMULTISIGs serialized in scriptSigs are - // counted more accurately, assuming they are of the form - // ... OP_N CHECKMULTISIG ... + /** + * Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs + * as 20 sigops. With pay-to-script-hash, that changed: + * CHECKMULTISIGs serialized in scriptSigs are + * counted more accurately, assuming they are of the form + * ... OP_N CHECKMULTISIG ... + */ unsigned int GetSigOpCount(bool fAccurate) const; - // Accurately count sigOps, including sigOps in - // pay-to-script-hash transactions: + /** + * Accurately count sigOps, including sigOps in + * pay-to-script-hash transactions: + */ unsigned int GetSigOpCount(const CScript& scriptSig) const; bool IsPayToScriptHash() const; - // Called by IsStandardTx and P2SH VerifyScript (which makes it consensus-critical). + /** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */ bool IsPushOnly() const; - // Called by IsStandardTx. - bool HasCanonicalPushes() const; - - // Returns whether the script is guaranteed to fail at execution, - // regardless of the initial stack. This allows outputs to be pruned - // instantly when entering the UTXO set. + /** + * Returns whether the script is guaranteed to fail at execution, + * regardless of the initial stack. This allows outputs to be pruned + * instantly when entering the UTXO set. + */ bool IsUnspendable() const { return (size() > 0 && *begin() == OP_RETURN); } - std::string 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; - } - - CScriptID GetID() const - { - return CScriptID(Hash160(*this)); - } - + std::string ToString() const; void clear() { // The default std::vector::clear() does not release memory. @@ -623,4 +600,4 @@ public: } }; -#endif // H_BITCOIN_SCRIPT +#endif // BITCOIN_SCRIPT_SCRIPT_H diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp new file mode 100644 index 0000000000..d8ecfde1d7 --- /dev/null +++ b/src/script/script_error.cpp @@ -0,0 +1,71 @@ +// 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. + +#include "script_error.h" + +const char* ScriptErrorString(const ScriptError serror) +{ + switch (serror) + { + case SCRIPT_ERR_OK: + return "No error"; + case SCRIPT_ERR_EVAL_FALSE: + return "Script evaluated without error but finished with a false/empty top stack element"; + case SCRIPT_ERR_VERIFY: + return "Script failed an OP_VERIFY operation"; + case SCRIPT_ERR_EQUALVERIFY: + return "Script failed an OP_EQUALVERIFY operation"; + case SCRIPT_ERR_CHECKMULTISIGVERIFY: + return "Script failed an OP_CHECKMULTISIGVERIFY operation"; + case SCRIPT_ERR_CHECKSIGVERIFY: + return "Script failed an OP_CHECKSIGVERIFY operation"; + case SCRIPT_ERR_NUMEQUALVERIFY: + return "Script failed an OP_NUMEQUALVERIFY operation"; + case SCRIPT_ERR_SCRIPT_SIZE: + return "Script is too big"; + case SCRIPT_ERR_PUSH_SIZE: + return "Push value size limit exceeded"; + case SCRIPT_ERR_OP_COUNT: + return "Operation limit exceeded"; + case SCRIPT_ERR_STACK_SIZE: + return "Stack size limit exceeded"; + case SCRIPT_ERR_SIG_COUNT: + return "Signature count negative or greater than pubkey count"; + case SCRIPT_ERR_PUBKEY_COUNT: + return "Pubkey count negative or limit exceeded"; + case SCRIPT_ERR_BAD_OPCODE: + return "Opcode missing or not understood"; + case SCRIPT_ERR_DISABLED_OPCODE: + return "Attempted to use a disabled opcode"; + case SCRIPT_ERR_INVALID_STACK_OPERATION: + return "Operation not valid with the current stack size"; + case SCRIPT_ERR_INVALID_ALTSTACK_OPERATION: + return "Operation not valid with the current altstack size"; + case SCRIPT_ERR_OP_RETURN: + return "OP_RETURN was encountered"; + case SCRIPT_ERR_UNBALANCED_CONDITIONAL: + return "Invalid OP_IF construction"; + case SCRIPT_ERR_SIG_HASHTYPE: + return "Signature hash type missing or not understood"; + case SCRIPT_ERR_SIG_DER: + return "Non-canonical DER signature"; + case SCRIPT_ERR_MINIMALDATA: + return "Data push larger than necessary"; + case SCRIPT_ERR_SIG_PUSHONLY: + return "Only non-push operators allowed in signatures"; + case SCRIPT_ERR_SIG_HIGH_S: + return "Non-canonical signature: S value is unnecessarily high"; + case SCRIPT_ERR_SIG_NULLDUMMY: + return "Dummy CHECKMULTISIG argument must be zero"; + case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS: + return "NOPx reserved for soft-fork upgrades"; + case SCRIPT_ERR_PUBKEYTYPE: + return "Public key is neither compressed or uncompressed"; + case SCRIPT_ERR_UNKNOWN_ERROR: + case SCRIPT_ERR_ERROR_COUNT: + default: break; + } + return "unknown error"; +} diff --git a/src/script/script_error.h b/src/script/script_error.h new file mode 100644 index 0000000000..5c260327b6 --- /dev/null +++ b/src/script/script_error.h @@ -0,0 +1,57 @@ +// 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_SCRIPT_SCRIPT_ERROR_H +#define BITCOIN_SCRIPT_SCRIPT_ERROR_H + +typedef enum ScriptError_t +{ + SCRIPT_ERR_OK = 0, + SCRIPT_ERR_UNKNOWN_ERROR, + SCRIPT_ERR_EVAL_FALSE, + SCRIPT_ERR_OP_RETURN, + + /* Max sizes */ + SCRIPT_ERR_SCRIPT_SIZE, + SCRIPT_ERR_PUSH_SIZE, + SCRIPT_ERR_OP_COUNT, + SCRIPT_ERR_STACK_SIZE, + SCRIPT_ERR_SIG_COUNT, + SCRIPT_ERR_PUBKEY_COUNT, + + /* Failed verify operations */ + SCRIPT_ERR_VERIFY, + SCRIPT_ERR_EQUALVERIFY, + SCRIPT_ERR_CHECKMULTISIGVERIFY, + SCRIPT_ERR_CHECKSIGVERIFY, + SCRIPT_ERR_NUMEQUALVERIFY, + + /* Logical/Format/Canonical errors */ + SCRIPT_ERR_BAD_OPCODE, + SCRIPT_ERR_DISABLED_OPCODE, + SCRIPT_ERR_INVALID_STACK_OPERATION, + SCRIPT_ERR_INVALID_ALTSTACK_OPERATION, + SCRIPT_ERR_UNBALANCED_CONDITIONAL, + + /* BIP62 */ + SCRIPT_ERR_SIG_HASHTYPE, + SCRIPT_ERR_SIG_DER, + SCRIPT_ERR_MINIMALDATA, + SCRIPT_ERR_SIG_PUSHONLY, + SCRIPT_ERR_SIG_HIGH_S, + SCRIPT_ERR_SIG_NULLDUMMY, + SCRIPT_ERR_PUBKEYTYPE, + + /* softfork safeness */ + SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, + + SCRIPT_ERR_ERROR_COUNT +} ScriptError; + +#define SCRIPT_ERR_LAST SCRIPT_ERR_ERROR_COUNT + +const char* ScriptErrorString(const ScriptError error); + +#endif // BITCOIN_SCRIPT_SCRIPT_ERROR_H diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp new file mode 100644 index 0000000000..75ecdb563d --- /dev/null +++ b/src/script/sigcache.cpp @@ -0,0 +1,90 @@ +// 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. + +#include "sigcache.h" + +#include "pubkey.h" +#include "random.h" +#include "uint256.h" +#include "util.h" + +#include <boost/thread.hpp> +#include <boost/tuple/tuple_comparison.hpp> + +namespace { + +/** + * Valid signature cache, to avoid doing expensive ECDSA signature checking + * twice for every transaction (once when accepted into memory pool, and + * again when accepted into the block chain) + */ +class CSignatureCache +{ +private: + //! sigdata_type is (signature hash, signature, public key): + typedef boost::tuple<uint256, std::vector<unsigned char>, CPubKey> sigdata_type; + std::set< sigdata_type> setValid; + boost::shared_mutex cs_sigcache; + +public: + bool + Get(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey) + { + boost::shared_lock<boost::shared_mutex> lock(cs_sigcache); + + sigdata_type k(hash, vchSig, pubKey); + std::set<sigdata_type>::iterator mi = setValid.find(k); + if (mi != setValid.end()) + return true; + return false; + } + + void Set(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey) + { + // DoS prevention: limit cache size to less than 10MB + // (~200 bytes per cache entry times 50,000 entries) + // Since there are a maximum of 20,000 signature operations per block + // 50,000 is a reasonable default. + int64_t nMaxCacheSize = GetArg("-maxsigcachesize", 50000); + if (nMaxCacheSize <= 0) return; + + boost::unique_lock<boost::shared_mutex> lock(cs_sigcache); + + while (static_cast<int64_t>(setValid.size()) > nMaxCacheSize) + { + // Evict a random entry. Random because that helps + // foil would-be DoS attackers who might try to pre-generate + // and re-use a set of valid signatures just-slightly-greater + // than our cache size. + uint256 randomHash = GetRandHash(); + std::vector<unsigned char> unused; + std::set<sigdata_type>::iterator it = + setValid.lower_bound(sigdata_type(randomHash, unused, unused)); + if (it == setValid.end()) + it = setValid.begin(); + setValid.erase(*it); + } + + sigdata_type k(hash, vchSig, pubKey); + setValid.insert(k); + } +}; + +} + +bool CachingSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const +{ + static CSignatureCache signatureCache; + + if (signatureCache.Get(sighash, vchSig, pubkey)) + return true; + + if (!SignatureChecker::VerifySignature(vchSig, pubkey, sighash)) + return false; + + if (store) + signatureCache.Set(sighash, vchSig, pubkey); + return true; +} diff --git a/src/script/sigcache.h b/src/script/sigcache.h new file mode 100644 index 0000000000..3bd11caff5 --- /dev/null +++ b/src/script/sigcache.h @@ -0,0 +1,26 @@ +// 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_SCRIPT_SIGCACHE_H +#define BITCOIN_SCRIPT_SIGCACHE_H + +#include "script/interpreter.h" + +#include <vector> + +class CPubKey; + +class CachingSignatureChecker : public SignatureChecker +{ +private: + bool store; + +public: + CachingSignatureChecker(const CTransaction& txToIn, unsigned int nInIn, bool storeIn=true) : SignatureChecker(txToIn, nInIn), store(storeIn) {} + + bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; +}; + +#endif // BITCOIN_SCRIPT_SIGCACHE_H diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 8abd8d221d..adddd4ec78 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -1,11 +1,11 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "script/sign.h" -#include "core.h" +#include "primitives/transaction.h" #include "key.h" #include "keystore.h" #include "script/standard.h" @@ -46,12 +46,12 @@ bool SignN(const vector<valtype>& multisigdata, const CKeyStore& keystore, uint2 return nSigned==nRequired; } -// -// Sign scriptPubKey with private keys stored in keystore, given transaction hash and hash type. -// Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed), -// unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script. -// Returns false if scriptPubKey could not be completely satisfied. -// +/** + * Sign scriptPubKey with private keys stored in keystore, given transaction hash and hash type. + * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed), + * unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script. + * Returns false if scriptPubKey could not be completely satisfied. + */ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& scriptSigRet, txnouttype& whichTypeRet) { @@ -78,7 +78,7 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash { CPubKey vch; keystore.GetPubKey(keyID, vch); - scriptSigRet << vch; + scriptSigRet << ToByteVector(vch); } return true; case TX_SCRIPTHASH: @@ -123,7 +123,7 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutabl } // Test solution - return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, STANDARD_SCRIPT_VERIFY_FLAGS); + return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(txTo, nIn)); } bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType) @@ -144,9 +144,9 @@ static CScript PushAll(const vector<valtype>& values) return result; } -static CScript CombineMultisig(CScript scriptPubKey, const CMutableTransaction& txTo, unsigned int nIn, +static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const vector<valtype>& vSolutions, - vector<valtype>& sigs1, vector<valtype>& sigs2) + const vector<valtype>& sigs1, const vector<valtype>& sigs2) { // Combine all the signatures we've got: set<valtype> allsigs; @@ -174,7 +174,7 @@ static CScript CombineMultisig(CScript scriptPubKey, const CMutableTransaction& if (sigs.count(pubkey)) continue; // Already got a sig for this pubkey - if (CheckSig(sig, pubkey, scriptPubKey, txTo, nIn, 0)) + if (SignatureChecker(txTo, nIn).CheckSig(sig, pubkey, scriptPubKey)) { sigs[pubkey] = sig; break; @@ -199,7 +199,7 @@ static CScript CombineMultisig(CScript scriptPubKey, const CMutableTransaction& return result; } -static CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, +static CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const txnouttype txType, const vector<valtype>& vSolutions, vector<valtype>& sigs1, vector<valtype>& sigs2) { @@ -244,7 +244,7 @@ static CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, return CScript(); } -CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, +CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2) { txnouttype txType; @@ -252,9 +252,9 @@ CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsign Solver(scriptPubKey, txType, vSolutions); vector<valtype> stack1; - EvalScript(stack1, scriptSig1, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC); + EvalScript(stack1, scriptSig1, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker()); vector<valtype> stack2; - EvalScript(stack2, scriptSig2, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC); + EvalScript(stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker()); return CombineSignatures(scriptPubKey, txTo, nIn, txType, vSolutions, stack1, stack2); } diff --git a/src/script/sign.h b/src/script/sign.h index f218a64562..e197d5fab3 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -1,10 +1,10 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef H_BITCOIN_SCRIPT_SIGN -#define H_BITCOIN_SCRIPT_SIGN +#ifndef BITCOIN_SCRIPT_SIGN_H +#define BITCOIN_SCRIPT_SIGN_H #include "script/interpreter.h" @@ -17,8 +17,10 @@ struct CMutableTransaction; bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); -// Given two sets of signatures for scriptPubKey, possibly with OP_0 placeholders, -// combine them intelligently and return the result. -CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2); +/** + * Given two sets of signatures for scriptPubKey, possibly with OP_0 placeholders, + * combine them intelligently and return the result. + */ +CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2); -#endif // H_BITCOIN_SCRIPT_SIGN +#endif // BITCOIN_SCRIPT_SIGN_H diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 407baf621d..ce50e3aad8 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -1,12 +1,14 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "script/standard.h" +#include "pubkey.h" #include "script/script.h" #include "util.h" +#include "utilstrencodings.h" #include <boost/foreach.hpp> @@ -14,6 +16,10 @@ using namespace std; typedef vector<unsigned char> valtype; +unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY; + +CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {} + const char* GetTxnOutputType(txnouttype t) { switch (t) @@ -28,9 +34,9 @@ const char* GetTxnOutputType(txnouttype t) return NULL; } -// -// Return public keys or hashes from scriptPubKey, for 'standard' transaction types. -// +/** + * Return public keys or hashes from scriptPubKey, for 'standard' transaction types. + */ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsigned char> >& vSolutionsRet) { // Templates @@ -136,8 +142,8 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi } else if (opcode2 == OP_SMALLDATA) { - // small pushdata, <= MAX_OP_RETURN_RELAY bytes - if (vch1.size() > MAX_OP_RETURN_RELAY) + // small pushdata, <= nMaxDatacarrierBytes + if (vch1.size() > nMaxDatacarrierBytes) break; } else if (opcode1 != opcode2 || vch1 != vch2) @@ -203,7 +209,11 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) if (whichType == TX_PUBKEY) { - addressRet = CPubKey(vSolutions[0]).GetID(); + CPubKey pubKey(vSolutions[0]); + if (!pubKey.IsValid()) + return false; + + addressRet = pubKey.GetID(); return true; } else if (whichType == TX_PUBKEYHASH) @@ -237,9 +247,16 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vecto nRequiredRet = vSolutions.front()[0]; for (unsigned int i = 1; i < vSolutions.size()-1; i++) { - CTxDestination address = CPubKey(vSolutions[i]).GetID(); + CPubKey pubKey(vSolutions[i]); + if (!pubKey.IsValid()) + continue; + + CTxDestination address = pubKey.GetID(); addressRet.push_back(address); } + + if (addressRet.empty()) + return false; } else { @@ -269,13 +286,13 @@ public: bool operator()(const CKeyID &keyID) const { script->clear(); - *script << OP_DUP << OP_HASH160 << keyID << OP_EQUALVERIFY << OP_CHECKSIG; + *script << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG; return true; } bool operator()(const CScriptID &scriptID) const { script->clear(); - *script << OP_HASH160 << scriptID << OP_EQUAL; + *script << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL; return true; } }; @@ -295,7 +312,7 @@ CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys) script << CScript::EncodeOP_N(nRequired); BOOST_FOREACH(const CPubKey& key, keys) - script << key; + script << ToByteVector(key); script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG; return script; } diff --git a/src/script/standard.h b/src/script/standard.h index ead79b82a2..1d29ef57aa 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -1,37 +1,56 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef H_BITCOIN_SCRIPT_STANDARD -#define H_BITCOIN_SCRIPT_STANDARD +#ifndef BITCOIN_SCRIPT_STANDARD_H +#define BITCOIN_SCRIPT_STANDARD_H -#include "script/script.h" #include "script/interpreter.h" +#include "uint256.h" + +#include <boost/variant.hpp> #include <stdint.h> +class CKeyID; class CScript; -static const unsigned int MAX_OP_RETURN_RELAY = 40; // bytes +/** A reference to a CScript: the Hash160 of its serialization (see script.h) */ +class CScriptID : public uint160 +{ +public: + CScriptID() : uint160(0) {} + CScriptID(const CScript& in); + CScriptID(const uint160& in) : uint160(in) {} +}; -// Mandatory script verification flags that all new blocks must comply with for -// them to be valid. (but old blocks may not comply with) Currently just P2SH, -// but in the future other flags may be added, such as a soft-fork to enforce -// strict DER encoding. -// -// Failing one of these tests may trigger a DoS ban - see CheckInputs() for -// details. +static const unsigned int MAX_OP_RETURN_RELAY = 40; //! bytes +extern unsigned nMaxDatacarrierBytes; + +/** + * Mandatory script verification flags that all new blocks must comply with for + * them to be valid. (but old blocks may not comply with) Currently just P2SH, + * but in the future other flags may be added, such as a soft-fork to enforce + * strict DER encoding. + * + * Failing one of these tests may trigger a DoS ban - see CheckInputs() for + * details. + */ 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. +/** + * 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_STRICTENC | - SCRIPT_VERIFY_NULLDUMMY; + SCRIPT_VERIFY_MINIMALDATA | + SCRIPT_VERIFY_NULLDUMMY | + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS; -// For convenience, standard but not mandatory verify flags. +/** 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 @@ -51,7 +70,8 @@ public: friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; } }; -/** A txout script template with a specific destination. It is either: +/** + * A txout script template with a specific destination. It is either: * * CNoDestination: no destination set * * CKeyID: TX_PUBKEYHASH destination * * CScriptID: TX_SCRIPTHASH destination @@ -70,4 +90,4 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std:: CScript GetScriptForDestination(const CTxDestination& dest); CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys); -#endif // H_BITCOIN_SCRIPT_STANDARD +#endif // BITCOIN_SCRIPT_STANDARD_H diff --git a/src/secp256k1/.gitignore b/src/secp256k1/.gitignore new file mode 100644 index 0000000000..f0a54077a5 --- /dev/null +++ b/src/secp256k1/.gitignore @@ -0,0 +1,35 @@ +bench_inv +bench_sign +bench_verify +tests +*.exe +*.so +*.a +!.gitignore + +Makefile +configure +.libs/ +Makefile.in +aclocal.m4 +autom4te.cache/ +config.log +config.status +*.tar.gz +*.la +libtool +.deps/ +.dirstamp +build-aux/ +*.lo +*.o +*~ +src/libsecp256k1-config.h +src/libsecp256k1-config.h.in +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 +src/stamp-h1 +libsecp256k1.pc diff --git a/src/secp256k1/.travis.yml b/src/secp256k1/.travis.yml new file mode 100644 index 0000000000..28cd61dbc9 --- /dev/null +++ b/src/secp256k1/.travis.yml @@ -0,0 +1,34 @@ +language: c +compiler: + - clang + - gcc +install: + - sudo apt-get install -qq libssl-dev + - if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" -o "$FIELD" = "gmp" ]; 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 BUILD=check EXTRAFLAGS= HOST= EXTRAPACKAGES= + matrix: + - SCALAR=32bit + - SCALAR=64bit + - FIELD=gmp + - FIELD=gmp ENDOMORPHISM=yes + - FIELD=64bit_asm + - FIELD=64bit_asm ENDOMORPHISM=yes + - FIELD=64bit + - FIELD=64bit ENDOMORPHISM=yes + - FIELD=32bit + - FIELD=32bit ENDOMORPHISM=yes + - BIGNUM=none + - BIGNUM=none ENDOMORPHISM=yes + - BUILD=distcheck + - EXTRAFLAGS=CFLAGS=-DDETERMINISTIC + - HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib" + - HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib" ENDOMORPHISM=yes +before_script: ./autogen.sh +script: + - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi + - if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi + - ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR $EXTRAFLAGS $USE_HOST && make -j2 $BUILD +os: linux diff --git a/src/secp256k1/COPYING b/src/secp256k1/COPYING new file mode 100644 index 0000000000..4522a5990e --- /dev/null +++ b/src/secp256k1/COPYING @@ -0,0 +1,19 @@ +Copyright (c) 2013 Pieter Wuille + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/secp256k1/Makefile.am b/src/secp256k1/Makefile.am new file mode 100644 index 0000000000..390d2c9ffa --- /dev/null +++ b/src/secp256k1/Makefile.am @@ -0,0 +1,77 @@ +ACLOCAL_AMFLAGS = -I build-aux/m4 + +lib_LTLIBRARIES = libsecp256k1.la +include_HEADERS = include/secp256k1.h +noinst_HEADERS = +noinst_HEADERS += src/scalar.h +noinst_HEADERS += src/scalar_4x64.h +noinst_HEADERS += src/scalar_8x32.h +noinst_HEADERS += src/scalar_impl.h +noinst_HEADERS += src/scalar_4x64_impl.h +noinst_HEADERS += src/scalar_8x32_impl.h +noinst_HEADERS += src/group.h +noinst_HEADERS += src/group_impl.h +noinst_HEADERS += src/num_gmp.h +noinst_HEADERS += src/num_gmp_impl.h +noinst_HEADERS += src/ecdsa.h +noinst_HEADERS += src/ecdsa_impl.h +noinst_HEADERS += src/eckey.h +noinst_HEADERS += src/eckey_impl.h +noinst_HEADERS += src/ecmult.h +noinst_HEADERS += src/ecmult_impl.h +noinst_HEADERS += src/ecmult_gen.h +noinst_HEADERS += src/ecmult_gen_impl.h +noinst_HEADERS += src/num.h +noinst_HEADERS += src/num_impl.h +noinst_HEADERS += src/field_10x26.h +noinst_HEADERS += src/field_10x26_impl.h +noinst_HEADERS += src/field_5x52.h +noinst_HEADERS += src/field_5x52_impl.h +noinst_HEADERS += src/field_5x52_int128_impl.h +noinst_HEADERS += src/field_5x52_asm_impl.h +noinst_HEADERS += src/java/org_bitcoin_NativeSecp256k1.h +noinst_HEADERS += src/util.h +noinst_HEADERS += src/testrand.h +noinst_HEADERS += src/testrand_impl.h +noinst_HEADERS += src/field_gmp.h +noinst_HEADERS += src/field_gmp_impl.h +noinst_HEADERS += src/field.h +noinst_HEADERS += src/field_impl.h +noinst_HEADERS += src/bench.h + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libsecp256k1.pc + +libsecp256k1_la_SOURCES = src/secp256k1.c +libsecp256k1_la_CPPFLAGS = -I$(top_srcdir)/include $(SECP_INCLUDES) +libsecp256k1_la_LIBADD = $(SECP_LIBS) + + +noinst_PROGRAMS = +if USE_BENCHMARK +noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_inv +bench_verify_SOURCES = src/bench_verify.c +bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) +bench_verify_LDFLAGS = -static +bench_recover_SOURCES = src/bench_recover.c +bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS) +bench_recover_LDFLAGS = -static +bench_sign_SOURCES = src/bench_sign.c +bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) +bench_sign_LDFLAGS = -static +bench_inv_SOURCES = src/bench_inv.c +bench_inv_LDADD = $(SECP_LIBS) +bench_inv_LDFLAGS = -static +bench_inv_CPPFLAGS = $(SECP_INCLUDES) +endif + +if USE_TESTS +noinst_PROGRAMS += tests +tests_SOURCES = src/tests.c +tests_CPPFLAGS = -DVERIFY $(SECP_INCLUDES) $(SECP_TEST_INCLUDES) +tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) +tests_LDFLAGS = -static +TESTS = tests +endif + +EXTRA_DIST = autogen.sh diff --git a/src/secp256k1/README.md b/src/secp256k1/README.md new file mode 100644 index 0000000000..1e49f49416 --- /dev/null +++ b/src/secp256k1/README.md @@ -0,0 +1,55 @@ +libsecp256k1 +============ + +[![Build Status](https://travis-ci.org/bitcoin/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin/secp256k1) + +Optimized C library for EC operations on curve secp256k1. + +This library is experimental, so use at your own risk. + +Features: +* Low-level field and group operations on secp256k1. +* ECDSA signing/verification and key generation. +* Adding/multiplying private/public keys. +* Serialization/parsing of private keys, public keys, signatures. +* Very efficient implementation. + +Implementation details +---------------------- + +* General + * Avoid dynamic memory usage almost everywhere. +* Field operations + * Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1). + * Using 5 52-bit limbs (including hand-optimized assembly for x86_64, by Diederik Huys). + * Using 10 26-bit limbs. + * Using GMP. + * Field inverses and square roots using a sliding window over blocks of 1s (by Peter Dettman). +* Scalar operations + * Optimized implementation without data-dependent branches of arithmetic modulo the curve's order. + * Using 4 64-bit limbs (relying on __int128 support in the compiler). + * Using 8 32-bit limbs. +* Group operations + * Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7). + * Use addition between points in Jacobian and affine coordinates where possible. + * Use a unified addition/doubling formula where necessary to avoid data-dependent branches. +* Point multiplication for verification (a*P + b*G). + * Use wNAF notation for point multiplicands. + * Use a much larger window for multiples of G, using precomputed multiples. + * Use Shamir's trick to do the multiplication with the public key and the generator simultaneously. + * Optionally use secp256k1's efficiently-computable endomorphism to split the multiplicands into 4 half-sized ones first. +* Point multiplication for signing + * Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions. + * Slice the precomputed table in memory per byte, so memory access to the table becomes uniform. + * No data-dependent branches + * The precomputed tables add and eventually subtract points for which no known scalar (private key) is known, preventing even an attacker with control over the private key used to control the data internally. + +Build steps +----------- + +libsecp256k1 is built using autotools: + + $ ./autogen.sh + $ ./configure + $ make + $ sudo make install # optional diff --git a/src/secp256k1/TODO b/src/secp256k1/TODO new file mode 100644 index 0000000000..a300e1c5eb --- /dev/null +++ b/src/secp256k1/TODO @@ -0,0 +1,3 @@ +* Unit tests for fieldelem/groupelem, including ones intended to + trigger fieldelem's boundary cases. +* Complete constant-time operations for signing/keygen diff --git a/src/secp256k1/autogen.sh b/src/secp256k1/autogen.sh new file mode 100755 index 0000000000..65286b9353 --- /dev/null +++ b/src/secp256k1/autogen.sh @@ -0,0 +1,3 @@ +#!/bin/sh +set -e +autoreconf -if --warnings=all diff --git a/src/secp256k1/build-aux/m4/bitcoin_secp.m4 b/src/secp256k1/build-aux/m4/bitcoin_secp.m4 new file mode 100644 index 0000000000..1373478c9c --- /dev/null +++ b/src/secp256k1/build-aux/m4/bitcoin_secp.m4 @@ -0,0 +1,79 @@ +dnl libsecp25k1 helper checks +AC_DEFUN([SECP_INT128_CHECK],[ +has_int128=$ac_cv_type___int128 +if test x"$has_int128" != x"yes" && test x"$set_field" = x"64bit"; then + AC_MSG_ERROR([$set_field field support explicitly requested but is not compatible with this host]) +fi +if test x"$has_int128" != x"yes" && test x"$set_scalar" = x"64bit"; then + AC_MSG_ERROR([$set_scalar scalar support explicitly requested but is not compatible with this host]) +fi +]) + +dnl +AC_DEFUN([SECP_64BIT_ASM_CHECK],[ +AC_MSG_CHECKING(for x86_64 assembly availability) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include <stdint.h>]],[[ + uint64_t a = 11, tmp; + __asm__ __volatile__("movq $0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx"); + ]])],[has_64bit_asm=yes],[has_64bit_asm=no]) +AC_MSG_RESULT([$has_64bit_asm]) +if test x"$set_field" == x"64bit_asm"; then + if test x"$has_64bit_asm" == x"no"; then + AC_MSG_ERROR([$set_field field support explicitly requested but no x86_64 assembly available]) + fi +fi +]) + +dnl +AC_DEFUN([SECP_OPENSSL_CHECK],[ +if test x"$use_pkgconfig" = x"yes"; then + : #NOP + m4_ifdef([PKG_CHECK_MODULES],[ + PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes],[has_libcrypto=no]) + if test x"$has_libcrypto" = x"yes"; then + TEMP_LIBS="$LIBS" + LIBS="$LIBS $CRYPTO_LIBS" + AC_CHECK_LIB(crypto, main,[AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])],[has_libcrypto=no]) + LIBS="$TEMP_LIBS" + fi + ]) +else + AC_CHECK_HEADER(openssl/crypto.h,[AC_CHECK_LIB(crypto, main,[has_libcrypto=yes; CRYPTO_LIBS=-lcrypto; AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])] +)]) + LIBS= +fi +if test x"$has_libcrypto" == x"yes" && test x"$has_openssl_ec" = x; then + AC_MSG_CHECKING(for EC functions in libcrypto) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include <openssl/ec.h> + #include <openssl/ecdsa.h> + #include <openssl/obj_mac.h>]],[[ + EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_secp256k1); + ECDSA_sign(0, NULL, 0, NULL, NULL, eckey); + ECDSA_verify(0, NULL, 0, NULL, 0, eckey); + EC_KEY_free(eckey); + ]])],[has_openssl_ec=yes],[has_openssl_ec=no]) + AC_MSG_RESULT([$has_openssl_ec]) +fi +]) + +dnl +AC_DEFUN([SECP_GMP_CHECK],[ +if test x"$has_gmp" != x"yes"; then + CPPFLAGS_TEMP="$CPPFLAGS" + CPPFLAGS="$GMP_CPPFLAGS $CPPFLAGS" + LIBS_TEMP="$LIBS" + LIBS="$GMP_LIBS $LIBS" + AC_CHECK_HEADER(gmp.h,[AC_CHECK_LIB(gmp, __gmpz_init,[has_gmp=yes; GMP_LIBS="$GMP_LIBS -lgmp"; AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed])])]) + CPPFLAGS="$CPPFLAGS_TEMP" + LIBS="$LIBS_TEMP" +fi +if test x"$set_field" = x"gmp" && test x"$has_gmp" != x"yes"; then + AC_MSG_ERROR([$set_field field support explicitly requested but libgmp was not found]) +fi +if test x"$set_bignum" = x"gmp" && test x"$has_gmp" != x"yes"; then + AC_MSG_ERROR([$set_bignum field support explicitly requested but libgmp was not found]) +fi +]) + diff --git a/src/secp256k1/configure.ac b/src/secp256k1/configure.ac new file mode 100644 index 0000000000..40e121e806 --- /dev/null +++ b/src/secp256k1/configure.ac @@ -0,0 +1,303 @@ +AC_PREREQ([2.60]) +AC_INIT([libsecp256k1],[0.1]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_MACRO_DIR([build-aux/m4]) +AC_CANONICAL_HOST +AH_TOP([#ifndef LIBSECP256K1_CONFIG_H]) +AH_TOP([#define LIBSECP256K1_CONFIG_H]) +AH_BOTTOM([#endif //LIBSECP256K1_CONFIG_H]) +AM_INIT_AUTOMAKE([foreign]) +LT_INIT + +dnl make the compilation flags quiet unless V=1 is used +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +PKG_PROG_PKG_CONFIG + +AC_PATH_TOOL(AR, ar) +AC_PATH_TOOL(RANLIB, ranlib) +AC_PATH_TOOL(STRIP, strip) + +if test "x$CFLAGS" = "x"; then + CFLAGS="-O3 -g" +fi + +AC_PROG_CC_C99 +if test x"$ac_cv_prog_cc_c99" == x"no"; then + AC_MSG_ERROR([c99 compiler support required]) +fi + +case $host in + *mingw*) + use_pkgconfig=no + ;; + *) + use_pkgconfig=yes + ;; +esac + +case $host_os in + *darwin*) + if test x$cross_compiling != xyes; then + AC_PATH_PROG([BREW],brew,) + if test x$BREW != x; then + dnl These Homebrew packages may be keg-only, meaning that they won't be found + dnl in expected paths because they may conflict with system files. Ask + dnl Homebrew where each one is located, then adjust paths accordingly. + + openssl_prefix=`$BREW --prefix openssl 2>/dev/null` + gmp_prefix=`$BREW --prefix gmp 2>/dev/null` + if test x$openssl_prefix != x; then + PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH" + export PKG_CONFIG_PATH + fi + if test x$gmp_prefix != x; then + GMP_CPPFLAGS="-I$gmp_prefix/include" + GMP_LIBS="-L$gmp_prefix/lib" + fi + else + AC_PATH_PROG([PORT],port,) + dnl if homebrew isn't installed and macports is, add the macports default paths + dnl as a last resort. + if test x$PORT != x; then + CPPFLAGS="$CPPFLAGS -isystem /opt/local/include" + LDFLAGS="$LDFLAGS -L/opt/local/lib" + fi + fi + fi + ;; +esac + +CFLAGS="$CFLAGS -W" + +warn_CFLAGS="-Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function" +saved_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $warn_CFLAGS" +AC_MSG_CHECKING([if ${CC} supports ${warn_CFLAGS}]) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], + [ AC_MSG_RESULT([yes]) ], + [ AC_MSG_RESULT([no]) + CFLAGS="$saved_CFLAGS" + ]) + + +AC_ARG_ENABLE(benchmark, + AS_HELP_STRING([--enable-benchmark],[compile benchmark (default is yes)]), + [use_benchmark=$enableval], + [use_benchmark=yes]) + +AC_ARG_ENABLE(tests, + AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]), + [use_tests=$enableval], + [use_tests=yes]) + +AC_ARG_ENABLE(endomorphism, + AS_HELP_STRING([--enable-endomorphism],[enable endomorphism (default is no)]), + [use_endomorphism=$enableval], + [use_endomorphism=no]) + +AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=gmp|64bit|64bit_asm|32bit|auto], +[Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto]) + +AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|none|auto], +[Specify Bignum Implementation. Default is auto])],[req_bignum=$withval], [req_bignum=auto]) + +AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto], +[Specify scalar implementation. Default is auto])],[req_scalar=$withval], [req_scalar=auto]) + +AC_CHECK_TYPES([__int128]) + +AC_MSG_CHECKING([for __builtin_expect]) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])], + [ AC_MSG_RESULT([yes]);AC_DEFINE(HAVE_BUILTIN_EXPECT,1,[Define this symbol if __builtin_expect is available]) ], + [ AC_MSG_RESULT([no]) + ]) + +if test x"$req_field" = x"auto"; then + SECP_64BIT_ASM_CHECK + if test x"$has_64bit_asm" = x"yes"; then + set_field=64bit_asm + fi + + if test x"$set_field" = x; then + SECP_INT128_CHECK + if test x"$has_int128" = x"yes"; then + set_field=64bit + fi + fi + + if test x"$set_field" = x; then + SECP_GMP_CHECK + if test x"$has_gmp" = x"yes"; then + set_field=gmp + fi + fi + + if test x"$set_field" = x; then + set_field=32bit + fi +else + set_field=$req_field + case $set_field in + 64bit_asm) + SECP_64BIT_ASM_CHECK + ;; + 64bit) + SECP_INT128_CHECK + ;; + gmp) + SECP_GMP_CHECK + ;; + 32bit) + ;; + *) + AC_MSG_ERROR([invalid field implementation selection]) + ;; + esac +fi + +if test x"$req_scalar" = x"auto"; then + if test x"$set_scalar" = x; then + SECP_INT128_CHECK + if test x"$has_int128" = x"yes"; then + set_scalar=64bit + fi + fi + if test x"$set_scalar" = x; then + set_scalar=32bit + fi +else + set_scalar=$req_scalar + case $set_scalar in + 64bit) + SECP_INT128_CHECK + ;; + 32bit) + ;; + *) + AC_MSG_ERROR([invalid scalar implementation selected]) + ;; + esac +fi + +if test x"$req_bignum" = x"auto"; then + SECP_GMP_CHECK + if test x"$has_gmp" = x"yes"; then + set_bignum=gmp + fi + + if test x"$set_bignum" = x; then + set_bignum=none + fi +else + set_bignum=$req_bignum + case $set_bignum in + gmp) + SECP_GMP_CHECK + ;; + none) + ;; + *) + AC_MSG_ERROR([invalid bignum implementation selection]) + ;; + esac +fi + +# select field implementation +case $set_field in +64bit_asm) + AC_DEFINE(USE_FIELD_5X52_ASM, 1, [Define this symbol to use the assembly version for the 5x52 field implementation]) + AC_DEFINE(USE_FIELD_5X52, 1, [Define this symbol to use the FIELD_5X52 implementation]) + ;; +64bit) + AC_DEFINE(USE_FIELD_5X52_INT128, 1, [Define this symbol to use the __int128 version for the 5x52 field implementation]) + AC_DEFINE(USE_FIELD_5X52, 1, [Define this symbol to use the FIELD_5X52 implementation]) + ;; +gmp) + AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed]) + AC_DEFINE(USE_FIELD_GMP, 1, [Define this symbol to use the FIELD_GMP implementation]) + ;; +32bit) + AC_DEFINE(USE_FIELD_10X26, 1, [Define this symbol to use the FIELD_10X26 implementation]) + ;; +*) + AC_MSG_ERROR([invalid field implementation]) + ;; +esac + +# select bignum implementation +case $set_bignum in +gmp) + AC_DEFINE(HAVE_LIBGMP, 1, [Define this symbol if libgmp is installed]) + AC_DEFINE(USE_NUM_GMP, 1, [Define this symbol to use the gmp implementation for num]) + AC_DEFINE(USE_FIELD_INV_NUM, 1, [Define this symbol to use the num-based field inverse implementation]) + AC_DEFINE(USE_SCALAR_INV_NUM, 1, [Define this symbol to use the num-based scalar inverse implementation]) + ;; +none) + AC_DEFINE(USE_NUM_NONE, 1, [Define this symbol to use no num implementation]) + AC_DEFINE(USE_FIELD_INV_BUILTIN, 1, [Define this symbol to use the native field inverse implementation]) + AC_DEFINE(USE_SCALAR_INV_BUILTIN, 1, [Define this symbol to use the native scalar inverse implementation]) + ;; +*) + AC_MSG_ERROR([invalid bignum implementation]) + ;; +esac + +#select scalar implementation +case $set_scalar in +64bit) + AC_DEFINE(USE_SCALAR_4X64, 1, [Define this symbol to use the 4x64 scalar implementation]) + ;; +32bit) + AC_DEFINE(USE_SCALAR_8X32, 1, [Define this symbol to use the 8x32 scalar implementation]) + ;; +*) + AC_MSG_ERROR([invalid scalar implementation]) + ;; +esac + +if test x"$use_tests" = x"yes"; then + SECP_OPENSSL_CHECK + if test x"$has_openssl_ec" == x"yes"; then + AC_DEFINE(ENABLE_OPENSSL_TESTS, 1, [Define this symbol if OpenSSL EC functions are available]) + SECP_TEST_INCLUDES="$SSL_CFLAGS $CRYPTO_CFLAGS" + SECP_TEST_LIBS="$CRYPTO_LIBS" + + case $host in + *mingw*) + SECP_TEST_LIBS="$SECP_TEST_LIBS -lgdi32" + ;; + esac + + fi +fi + +if test x"$set_field" = x"gmp" || test x"$set_bignum" = x"gmp"; then + SECP_LIBS="$SECP_LIBS $GMP_LIBS" + SECP_INCLUDES="$SECP_INCLUDES $GMP_CPPFLAGS" +fi + +if test x"$use_endomorphism" = x"yes"; then + AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization]) +fi + +AC_MSG_NOTICE([Using field implementation: $set_field]) +AC_MSG_NOTICE([Using bignum implementation: $set_bignum]) +AC_MSG_NOTICE([Using scalar implementation: $set_scalar]) + +AC_CONFIG_HEADERS([src/libsecp256k1-config.h]) +AC_CONFIG_FILES([Makefile libsecp256k1.pc]) +AC_SUBST(SECP_INCLUDES) +AC_SUBST(SECP_LIBS) +AC_SUBST(SECP_TEST_LIBS) +AC_SUBST(SECP_TEST_INCLUDES) +AM_CONDITIONAL([USE_ASM], [test x"$set_field" == x"64bit_asm"]) +AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"]) +AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" != x"no"]) + +dnl make sure nothing new is exported so that we don't break the cache +PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH" +unset PKG_CONFIG_PATH +PKG_CONFIG_PATH="$PKGCONFIG_PATH_TEMP" + +AC_OUTPUT diff --git a/src/secp256k1/include/secp256k1.h b/src/secp256k1/include/secp256k1.h new file mode 100644 index 0000000000..dca7ca00e7 --- /dev/null +++ b/src/secp256k1/include/secp256k1.h @@ -0,0 +1,232 @@ +#ifndef _SECP256K1_ +# define _SECP256K1_ + +# ifdef __cplusplus +extern "C" { +# endif + +# if !defined(SECP256K1_GNUC_PREREQ) +# if defined(__GNUC__)&&defined(__GNUC_MINOR__) +# define SECP256K1_GNUC_PREREQ(_maj,_min) \ + ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) +# else +# define SECP256K1_GNUC_PREREQ(_maj,_min) 0 +# endif +# endif + +# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) +# if SECP256K1_GNUC_PREREQ(2,7) +# define SECP256K1_INLINE __inline__ +# elif (defined(_MSC_VER)) +# define SECP256K1_INLINE __inline +# else +# define SECP256K1_INLINE +# endif +# else +# define SECP256K1_INLINE inline +# endif + +/**Warning attributes + * NONNULL is not used if SECP256K1_BUILD is set to avoid the compiler optimizing out + * some paranoid null checks. */ +# if defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4) +# define SECP256K1_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) +# else +# define SECP256K1_WARN_UNUSED_RESULT +# endif +# if !defined(SECP256K1_BUILD) && defined(__GNUC__) && SECP256K1_GNUC_PREREQ(3, 4) +# define SECP256K1_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x))) +# else +# define SECP256K1_ARG_NONNULL(_x) +# endif + + +/** Flags to pass to secp256k1_start. */ +# define SECP256K1_START_VERIFY (1 << 0) +# define SECP256K1_START_SIGN (1 << 1) + +/** 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. + */ +void secp256k1_start(unsigned int flags); + +/** Free all memory associated with this library. After this, no + * functions can be called anymore, except secp256k1_start() + */ +void secp256k1_stop(void); + +/** 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) + * 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 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); + +/** Create an ECDSA signature. + * Returns: 1: signature created + * 0: nonce invalid, try another one + * In: msg32: the 32-byte message hash being signed (cannot be NULL) + * seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid) + * nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG) + * 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). + * Requires starting using SECP256K1_START_SIGN. + */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign( + const unsigned char *msg32, + unsigned char *sig, + int *siglen, + const unsigned char *seckey, + const unsigned char *nonce +) 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: nonce invalid, try another one + * In: msg32: the 32-byte message hash being signed (cannot be NULL) + * seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid) + * nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG) + * Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL) + * recid: pointer to an int, which will be updated to contain the recovery id (can be NULL) + * Requires starting using SECP256K1_START_SIGN. + */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign_compact( + const unsigned char *msg32, + unsigned char *sig64, + const unsigned char *seckey, + const unsigned char *nonce, + int *recid +) 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) + * 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 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); + +/** 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) + */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(const unsigned char *seckey) SECP256K1_ARG_NONNULL(1); + +/** 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). + * pubkeylen: length of pubkey + */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify(const unsigned char *pubkey, int pubkeylen) SECP256K1_ARG_NONNULL(1); + +/** Compute the public key for a secret key. + * In: 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. + */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( + unsigned char *pubkey, + int *pubkeylen, + const unsigned char *seckey, + int compressed +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Decompress a public key. + * 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) + * 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. + */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_decompress( + unsigned char *pubkey, + int *pubkeylen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); + +/** Export a private key in DER format. */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_export( + const unsigned char *seckey, + unsigned char *privkey, + int *privkeylen, + int compressed +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Import a private key in DER format. */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_import( + unsigned char *seckey, + const unsigned char *privkey, + int privkeylen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); + +/** Tweak a private key by adding tweak to it. */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( + unsigned char *seckey, + const unsigned char *tweak +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); + +/** Tweak a public key by adding tweak times the generator to it. + * Requires starting with SECP256K1_START_VERIFY. + */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( + unsigned char *pubkey, + int pubkeylen, + const unsigned char *tweak +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3); + +/** Tweak a private key by multiplying it with tweak. */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( + unsigned char *seckey, + const unsigned char *tweak +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); + +/** Tweak a public key by multiplying it with tweak. + * Requires starting with SECP256K1_START_VERIFY. + */ +SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul( + unsigned char *pubkey, + int pubkeylen, + const unsigned char *tweak +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3); + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/src/secp256k1/libsecp256k1.pc.in b/src/secp256k1/libsecp256k1.pc.in new file mode 100644 index 0000000000..1c72dd0003 --- /dev/null +++ b/src/secp256k1/libsecp256k1.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libsecp256k1 +Description: Optimized C library for EC operations on curve secp256k1 +URL: https://github.com/bitcoin/secp256k1 +Version: @PACKAGE_VERSION@ +Cflags: -I${includedir} +Libs.private: @SECP_LIBS@ +Libs: -L${libdir} -lsecp256k1 + diff --git a/src/secp256k1/.empty b/src/secp256k1/obj/.gitignore index e69de29bb2..e69de29bb2 100644 --- a/src/secp256k1/.empty +++ b/src/secp256k1/obj/.gitignore diff --git a/src/secp256k1/src/bench.h b/src/secp256k1/src/bench.h new file mode 100644 index 0000000000..668ec39f71 --- /dev/null +++ b/src/secp256k1/src/bench.h @@ -0,0 +1,37 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_BENCH_H_ +#define _SECP256K1_BENCH_H_ + +#include <stdio.h> +#include <math.h> +#include "sys/time.h" + +static double gettimedouble(void) { + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_usec * 0.000001 + tv.tv_sec; +} + +void run_benchmark(void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) { + double min = HUGE_VAL; + double sum = 0.0; + double max = 0.0; + for (int i = 0; i < count; i++) { + if (setup) setup(data); + double begin = gettimedouble(); + benchmark(data); + double total = gettimedouble() - begin; + if (teardown) teardown(data); + if (total < min) min = total; + if (total > max) max = total; + sum += total; + } + printf("min %.3fus / avg %.3fus / max %.3fus\n", min * 1000000.0 / iter, (sum / count) * 1000000.0 / iter, max * 1000000.0 / iter); +} + +#endif diff --git a/src/secp256k1/src/bench_inv.c b/src/secp256k1/src/bench_inv.c new file mode 100644 index 0000000000..3bdedea30e --- /dev/null +++ b/src/secp256k1/src/bench_inv.c @@ -0,0 +1,52 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ +#include <stdio.h> + +#include "include/secp256k1.h" + +#include "util.h" +#include "num_impl.h" +#include "field_impl.h" +#include "group_impl.h" +#include "scalar_impl.h" +#include "bench.h" + +typedef struct { + secp256k1_scalar_t base, x; +} bench_inv_t; + +void bench_inv_setup(void* arg) { + bench_inv_t *data = (bench_inv_t*)arg; + + static const unsigned char init[32] = { + 0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13, + 0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35, + 0x3b, 0x3d, 0x43, 0x47, 0x49, 0x4f, 0x53, 0x59, + 0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71, 0x7f, 0x83 + }; + + secp256k1_scalar_set_b32(&data->base, init, NULL); + secp256k1_scalar_set_b32(&data->x, init, NULL); +} + +void bench_inv(void* arg) { + bench_inv_t *data = (bench_inv_t*)arg; + + for (int i=0; i<20000; i++) { + secp256k1_scalar_inverse(&data->x, &data->x); + secp256k1_scalar_add(&data->x, &data->x, &data->base); + } +} + +int main(void) { + secp256k1_ge_start(); + + bench_inv_t data; + run_benchmark(bench_inv, bench_inv_setup, NULL, &data, 10, 20000); + + secp256k1_ge_stop(); + return 0; +} diff --git a/src/secp256k1/src/bench_recover.c b/src/secp256k1/src/bench_recover.c new file mode 100644 index 0000000000..b1e0f33efa --- /dev/null +++ b/src/secp256k1/src/bench_recover.c @@ -0,0 +1,46 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#include "include/secp256k1.h" +#include "util.h" +#include "bench.h" + +typedef struct { + unsigned char msg[32]; + unsigned char sig[64]; +} bench_recover_t; + +void bench_recover(void* arg) { + bench_recover_t *data = (bench_recover_t*)arg; + + unsigned char pubkey[33]; + for (int i=0; i<20000; i++) { + int pubkeylen = 33; + CHECK(secp256k1_ecdsa_recover_compact(data->msg, data->sig, pubkey, &pubkeylen, 1, i % 2)); + for (int 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. */ + data->sig[j] = pubkey[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */ + } + } +} + +void bench_recover_setup(void* arg) { + bench_recover_t *data = (bench_recover_t*)arg; + + for (int i = 0; i < 32; i++) data->msg[i] = 1 + i; + for (int i = 0; i < 64; i++) data->sig[i] = 65 + i; +} + +int main(void) { + secp256k1_start(SECP256K1_START_VERIFY); + + bench_recover_t data; + run_benchmark(bench_recover, bench_recover_setup, NULL, &data, 10, 20000); + + secp256k1_stop(); + return 0; +} diff --git a/src/secp256k1/src/bench_sign.c b/src/secp256k1/src/bench_sign.c new file mode 100644 index 0000000000..66e71e1ac4 --- /dev/null +++ b/src/secp256k1/src/bench_sign.c @@ -0,0 +1,48 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#include "include/secp256k1.h" +#include "util.h" +#include "bench.h" + +typedef struct { + unsigned char msg[32]; + unsigned char nonce[32]; + unsigned char key[32]; +} bench_sign_t; + +static void bench_sign_setup(void* arg) { + bench_sign_t *data = (bench_sign_t*)arg; + + for (int i = 0; i < 32; i++) data->msg[i] = i + 1; + for (int i = 0; i < 32; i++) data->nonce[i] = i + 33; + for (int i = 0; i < 32; i++) data->key[i] = i + 65; +} + +static void bench_sign(void* arg) { + bench_sign_t *data = (bench_sign_t*)arg; + + unsigned char sig[64]; + for (int i=0; i<20000; i++) { + int recid = 0; + CHECK(secp256k1_ecdsa_sign_compact(data->msg, sig, data->key, data->nonce, &recid)); + for (int j = 0; j < 32; j++) { + data->nonce[j] = data->key[j]; /* Move former key to nonce */ + data->msg[j] = sig[j]; /* Move former R to message. */ + data->key[j] = sig[j + 32]; /* Move former S to key. */ + } + } +} + +int main(void) { + secp256k1_start(SECP256K1_START_SIGN); + + bench_sign_t data; + run_benchmark(bench_sign, bench_sign_setup, NULL, &data, 10, 20000); + + secp256k1_stop(); + return 0; +} diff --git a/src/secp256k1/src/bench_verify.c b/src/secp256k1/src/bench_verify.c new file mode 100644 index 0000000000..b123c4087d --- /dev/null +++ b/src/secp256k1/src/bench_verify.c @@ -0,0 +1,55 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#include <stdio.h> +#include <string.h> + +#include "include/secp256k1.h" +#include "util.h" +#include "bench.h" + +typedef struct { + unsigned char msg[32]; + unsigned char key[32]; + unsigned char nonce[32]; + unsigned char sig[72]; + int siglen; + unsigned char pubkey[33]; + int pubkeylen; +} benchmark_verify_t; + +static void benchmark_verify(void* arg) { + benchmark_verify_t* data = (benchmark_verify_t*)arg; + + for (int i=0; i<20000; i++) { + data->sig[data->siglen - 1] ^= (i & 0xFF); + data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); + data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); + CHECK(secp256k1_ecdsa_verify(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); + } +} + +int main(void) { + secp256k1_start(SECP256K1_START_VERIFY | SECP256K1_START_SIGN); + + benchmark_verify_t data; + + for (int i = 0; i < 32; i++) data.msg[i] = 1 + i; + for (int i = 0; i < 32; i++) data.key[i] = 33 + i; + for (int i = 0; i < 32; i++) data.nonce[i] = 65 + i; + data.siglen = 72; + CHECK(secp256k1_ecdsa_sign(data.msg, data.sig, &data.siglen, data.key, data.nonce)); + data.pubkeylen = 33; + CHECK(secp256k1_ec_pubkey_create(data.pubkey, &data.pubkeylen, data.key, 1)); + + run_benchmark(benchmark_verify, NULL, NULL, &data, 10, 20000); + + secp256k1_stop(); + return 0; +} diff --git a/src/secp256k1/src/ecdsa.h b/src/secp256k1/src/ecdsa.h new file mode 100644 index 0000000000..5fc5230c36 --- /dev/null +++ b/src/secp256k1/src/ecdsa.h @@ -0,0 +1,27 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_ECDSA_ +#define _SECP256K1_ECDSA_ + +#include "scalar.h" +#include "group.h" + +static void secp256k1_ecsda_start(void); +static void secp256k1_ecdsa_stop(void); + +typedef struct { + secp256k1_scalar_t r, s; +} secp256k1_ecdsa_sig_t; + +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 void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s); + +#endif diff --git a/src/secp256k1/src/ecdsa_impl.h b/src/secp256k1/src/ecdsa_impl.h new file mode 100644 index 0000000000..8825d05fed --- /dev/null +++ b/src/secp256k1/src/ecdsa_impl.h @@ -0,0 +1,205 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + + +#ifndef _SECP256K1_ECDSA_IMPL_H_ +#define _SECP256K1_ECDSA_IMPL_H_ + +#include "scalar.h" +#include "field.h" +#include "group.h" +#include "ecmult.h" +#include "ecmult_gen.h" +#include "ecdsa.h" + +typedef struct { + secp256k1_fe_t order_as_fe; + secp256k1_fe_t p_minus_order; +} secp256k1_ecdsa_consts_t; + +static const secp256k1_ecdsa_consts_t *secp256k1_ecdsa_consts = NULL; + +static void secp256k1_ecdsa_start(void) { + if (secp256k1_ecdsa_consts != NULL) + return; + + /* Allocate. */ + secp256k1_ecdsa_consts_t *ret = (secp256k1_ecdsa_consts_t*)checked_malloc(sizeof(secp256k1_ecdsa_consts_t)); + + static const unsigned char order[] = { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, + 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, + 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 + }; + + secp256k1_fe_set_b32(&ret->order_as_fe, order); + secp256k1_fe_negate(&ret->p_minus_order, &ret->order_as_fe, 1); + secp256k1_fe_normalize_var(&ret->p_minus_order); + + /* Set the global pointer. */ + secp256k1_ecdsa_consts = ret; +} + +static void secp256k1_ecdsa_stop(void) { + if (secp256k1_ecdsa_consts == NULL) + return; + + secp256k1_ecdsa_consts_t *c = (secp256k1_ecdsa_consts_t*)secp256k1_ecdsa_consts; + secp256k1_ecdsa_consts = NULL; + free(c); +} + +static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size) { + if (sig[0] != 0x30) return 0; + int lenr = sig[3]; + if (5+lenr >= size) return 0; + int 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; + const unsigned char *sp = sig + 6 + lenr; + while (lens > 0 && sp[0] == 0) { + lens--; + sp++; + } + if (lens > 32) return 0; + const unsigned char *rp = sig + 4; + while (lenr > 0 && rp[0] == 0) { + lenr--; + rp++; + } + if (lenr > 32) return 0; + unsigned char ra[32] = {0}, sa[32] = {0}; + memcpy(ra + 32 - lenr, rp, lenr); + memcpy(sa + 32 - lens, sp, lens); + int overflow = 0; + secp256k1_scalar_set_b32(&r->r, ra, &overflow); + if (overflow) return 0; + secp256k1_scalar_set_b32(&r->s, sa, &overflow); + if (overflow) return 0; + return 1; +} + +static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a) { + unsigned char r[33] = {0}, s[33] = {0}; + secp256k1_scalar_get_b32(&r[1], &a->r); + secp256k1_scalar_get_b32(&s[1], &a->s); + unsigned char *rp = r, *sp = s; + int lenR = 33, lenS = 33; + 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) + return 0; + *size = 6 + lenS + lenR; + sig[0] = 0x30; + sig[1] = 4 + lenS + lenR; + sig[2] = 0x02; + sig[3] = lenR; + memcpy(sig+4, rp, lenR); + sig[4+lenR] = 0x02; + sig[5+lenR] = lenS; + memcpy(sig+lenR+6, sp, lenS); + return 1; +} + +static int secp256k1_ecdsa_sig_recompute(secp256k1_scalar_t *r2, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) { + if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) + return 0; + + int ret = 0; + secp256k1_scalar_t sn, u1, u2; + secp256k1_scalar_inverse_var(&sn, &sig->s); + secp256k1_scalar_mul(&u1, &sn, message); + secp256k1_scalar_mul(&u2, &sn, &sig->r); + secp256k1_gej_t pubkeyj; secp256k1_gej_set_ge(&pubkeyj, pubkey); + secp256k1_gej_t pr; secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1); + if (!secp256k1_gej_is_infinity(&pr)) { + secp256k1_fe_t xr; secp256k1_gej_get_x_var(&xr, &pr); + secp256k1_fe_normalize_var(&xr); + unsigned char xrb[32]; secp256k1_fe_get_b32(xrb, &xr); + secp256k1_scalar_set_b32(r2, xrb, NULL); + ret = 1; + } + return ret; +} + +static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) { + if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) + return 0; + + unsigned char brx[32]; + secp256k1_scalar_get_b32(brx, &sig->r); + secp256k1_fe_t fx; + 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_consts->p_minus_order) >= 0) + return 0; + secp256k1_fe_add(&fx, &secp256k1_ecdsa_consts->order_as_fe); + } + secp256k1_ge_t x; + if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) + return 0; + secp256k1_gej_t xj; + secp256k1_gej_set_ge(&xj, &x); + secp256k1_scalar_t rn, u1, u2; + 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_gej_t qj; + secp256k1_ecmult(&qj, &xj, &u2, &u1); + secp256k1_ge_set_gej_var(pubkey, &qj); + return !secp256k1_gej_is_infinity(&qj); +} + +static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) { + secp256k1_scalar_t r2; + int ret = 0; + ret = secp256k1_ecdsa_sig_recompute(&r2, sig, pubkey, message) && secp256k1_scalar_eq(&sig->r, &r2); + return ret; +} + +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) { + secp256k1_gej_t rp; + secp256k1_ecmult_gen(&rp, nonce); + secp256k1_ge_t r; + secp256k1_ge_set_gej(&r, &rp); + unsigned char b[32]; + secp256k1_fe_normalize(&r.x); + secp256k1_fe_normalize(&r.y); + secp256k1_fe_get_b32(b, &r.x); + int overflow = 0; + secp256k1_scalar_set_b32(&sig->r, b, &overflow); + if (recid) + *recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0); + secp256k1_scalar_t n; + secp256k1_scalar_mul(&n, &sig->r, seckey); + secp256k1_scalar_add(&n, &n, message); + secp256k1_scalar_inverse(&sig->s, nonce); + secp256k1_scalar_mul(&sig->s, &sig->s, &n); + secp256k1_scalar_clear(&n); + secp256k1_gej_clear(&rp); + secp256k1_ge_clear(&r); + 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) + *recid ^= 1; + } + return 1; +} + +static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s) { + sig->r = *r; + sig->s = *s; +} + +#endif diff --git a/src/secp256k1/src/eckey.h b/src/secp256k1/src/eckey.h new file mode 100644 index 0000000000..6de5dc0a59 --- /dev/null +++ b/src/secp256k1/src/eckey.h @@ -0,0 +1,24 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_ECKEY_ +#define _SECP256K1_ECKEY_ + +#include "group.h" +#include "scalar.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_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_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); + +#endif diff --git a/src/secp256k1/src/eckey_impl.h b/src/secp256k1/src/eckey_impl.h new file mode 100644 index 0000000000..b3fa7d9bd2 --- /dev/null +++ b/src/secp256k1/src/eckey_impl.h @@ -0,0 +1,191 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_ECKEY_IMPL_H_ +#define _SECP256K1_ECKEY_IMPL_H_ + +#include "eckey.h" + +#include "scalar.h" +#include "field.h" +#include "group.h" +#include "ecmult_gen.h" + +static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size) { + if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) { + secp256k1_fe_t x; + return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == 0x03); + } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) { + secp256k1_fe_t x, y; + if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) { + return 0; + } + secp256k1_ge_set_xy(elem, &x, &y); + 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; + } +} + +static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed) { + if (secp256k1_ge_is_infinity(elem)) { + return 0; + } + secp256k1_fe_normalize_var(&elem->x); + secp256k1_fe_normalize_var(&elem->y); + secp256k1_fe_get_b32(&pub[1], &elem->x); + if (compressed) { + *size = 33; + pub[0] = 0x02 | (secp256k1_fe_is_odd(&elem->y) ? 0x01 : 0x00); + } else { + *size = 65; + pub[0] = 0x04; + secp256k1_fe_get_b32(&pub[33], &elem->y); + } + return 1; +} + +static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen) { + const unsigned char *end = privkey + privkeylen; + /* sequence header */ + if (end < privkey+1 || *privkey != 0x30) + return 0; + privkey++; + /* sequence length constructor */ + int lenb = 0; + if (end < privkey+1 || !(*privkey & 0x80)) + return 0; + lenb = *privkey & ~0x80; privkey++; + if (lenb < 1 || lenb > 2) + return 0; + if (end < privkey+lenb) + return 0; + /* sequence length */ + int len = 0; + len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0); + privkey += lenb; + 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) + 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]) + return 0; + int overflow = 0; + unsigned char c[32] = {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) { + secp256k1_gej_t rp; + secp256k1_ecmult_gen(&rp, key); + secp256k1_ge_t r; + secp256k1_ge_set_gej(&r, &rp); + if (compressed) { + static const unsigned char begin[] = { + 0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20 + }; + static const unsigned char middle[] = { + 0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, + 0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, + 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, + 0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, + 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00 + }; + unsigned char *ptr = privkey; + memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); + secp256k1_scalar_get_b32(ptr, key); ptr += 32; + memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); + int pubkeylen = 0; + if (!secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 1)) { + return 0; + } + ptr += pubkeylen; + *privkeylen = ptr - privkey; + } else { + static const unsigned char begin[] = { + 0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20 + }; + static const unsigned char middle[] = { + 0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, + 0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, + 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, + 0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11, + 0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10, + 0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, + 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00 + }; + unsigned char *ptr = privkey; + memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); + secp256k1_scalar_get_b32(ptr, key); ptr += 32; + memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); + int pubkeylen = 0; + if (!secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 0)) { + return 0; + } + ptr += pubkeylen; + *privkeylen = ptr - privkey; + } + return 1; +} + +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)) + return 0; + return 1; +} + +static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) { + secp256k1_gej_t pt; + secp256k1_gej_set_ge(&pt, key); + secp256k1_scalar_t one; + secp256k1_scalar_set_int(&one, 1); + secp256k1_ecmult(&pt, &pt, &one, tweak); + + 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)) + 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) { + if (secp256k1_scalar_is_zero(tweak)) + return 0; + + secp256k1_scalar_t zero; + secp256k1_scalar_set_int(&zero, 0); + secp256k1_gej_t pt; + secp256k1_gej_set_ge(&pt, key); + secp256k1_ecmult(&pt, &pt, tweak, &zero); + secp256k1_ge_set_gej(key, &pt); + return 1; +} + +#endif diff --git a/src/secp256k1/src/ecmult.h b/src/secp256k1/src/ecmult.h new file mode 100644 index 0000000000..15a7100a4a --- /dev/null +++ b/src/secp256k1/src/ecmult.h @@ -0,0 +1,19 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_ECMULT_ +#define _SECP256K1_ECMULT_ + +#include "num.h" +#include "group.h" + +static void secp256k1_ecmult_start(void); +static void secp256k1_ecmult_stop(void); + +/** 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); + +#endif diff --git a/src/secp256k1/src/ecmult_gen.h b/src/secp256k1/src/ecmult_gen.h new file mode 100644 index 0000000000..42f822f9ce --- /dev/null +++ b/src/secp256k1/src/ecmult_gen.h @@ -0,0 +1,19 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_ECMULT_GEN_ +#define _SECP256K1_ECMULT_GEN_ + +#include "scalar.h" +#include "group.h" + +static void secp256k1_ecmult_gen_start(void); +static void secp256k1_ecmult_gen_stop(void); + +/** Multiply with the generator: R = a*G */ +static void secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_scalar_t *a); + +#endif diff --git a/src/secp256k1/src/ecmult_gen_impl.h b/src/secp256k1/src/ecmult_gen_impl.h new file mode 100644 index 0000000000..5a5b16ce14 --- /dev/null +++ b/src/secp256k1/src/ecmult_gen_impl.h @@ -0,0 +1,121 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_ECMULT_GEN_IMPL_H_ +#define _SECP256K1_ECMULT_GEN_IMPL_H_ + +#include "scalar.h" +#include "group.h" +#include "ecmult_gen.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_fe_t prec[64][16][2]; /* prec[j][i] = (16^j * i * G + U_i).{x,y} */ +} secp256k1_ecmult_gen_consts_t; + +static const secp256k1_ecmult_gen_consts_t *secp256k1_ecmult_gen_consts = NULL; + +static void secp256k1_ecmult_gen_start(void) { + if (secp256k1_ecmult_gen_consts != NULL) + return; + + /* Allocate the precomputation table. */ + secp256k1_ecmult_gen_consts_t *ret = (secp256k1_ecmult_gen_consts_t*)checked_malloc(sizeof(secp256k1_ecmult_gen_consts_t)); + + /* get the generator */ + const secp256k1_ge_t *g = &secp256k1_ge_consts->g; + secp256k1_gej_t gj; secp256k1_gej_set_ge(&gj, g); + + /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */ + secp256k1_gej_t nums_gej; + { + static const unsigned char nums_b32[32] = "The scalar for this x is unknown"; + secp256k1_fe_t nums_x; + VERIFY_CHECK(secp256k1_fe_set_b32(&nums_x, nums_b32)); + secp256k1_ge_t nums_ge; + VERIFY_CHECK(secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0)); + secp256k1_gej_set_ge(&nums_gej, &nums_ge); + /* Add G to make the bits in x uniformly distributed. */ + secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, g); + } + + /* compute prec. */ + secp256k1_ge_t prec[1024]; + { + secp256k1_gej_t precj[1024]; /* Jacobian versions of prec. */ + secp256k1_gej_t gbase; gbase = gj; /* 16^j * G */ + secp256k1_gej_t numsbase; numsbase = nums_gej; /* 2^j * nums. */ + for (int j=0; j<64; j++) { + /* Set precj[j*16 .. j*16+15] to (numsbase, numsbase + gbase, ..., numsbase + 15*gbase). */ + precj[j*16] = numsbase; + for (int i=1; i<16; i++) { + secp256k1_gej_add_var(&precj[j*16 + i], &precj[j*16 + i - 1], &gbase); + } + /* Multiply gbase by 16. */ + for (int i=0; i<4; i++) { + secp256k1_gej_double_var(&gbase, &gbase); + } + /* Multiply numbase by 2. */ + secp256k1_gej_double_var(&numsbase, &numsbase); + if (j == 62) { + /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ + secp256k1_gej_neg_var(&numsbase, &numsbase); + secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej); + } + } + secp256k1_ge_set_all_gej_var(1024, prec, precj); + } + for (int j=0; j<64; j++) { + for (int i=0; i<16; i++) { + VERIFY_CHECK(!secp256k1_ge_is_infinity(&prec[j*16 + i])); + ret->prec[j][i][0] = prec[j*16 + i].x; + ret->prec[j][i][1] = prec[j*16 + i].y; + } + } + + /* Set the global pointer to the precomputation table. */ + secp256k1_ecmult_gen_consts = ret; +} + +static void secp256k1_ecmult_gen_stop(void) { + if (secp256k1_ecmult_gen_consts == NULL) + return; + + secp256k1_ecmult_gen_consts_t *c = (secp256k1_ecmult_gen_consts_t*)secp256k1_ecmult_gen_consts; + secp256k1_ecmult_gen_consts = NULL; + free(c); +} + +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; + secp256k1_gej_set_infinity(r); + secp256k1_ge_t add; + add.infinity = 0; + int bits; + for (int j=0; j<64; j++) { + bits = secp256k1_scalar_get_bits(gn, j * 4, 4); + for (int i=0; i<16; i++) { + secp256k1_fe_cmov(&add.x, &c->prec[j][i][0], i == bits); + secp256k1_fe_cmov(&add.y, &c->prec[j][i][1], i == bits); + } + secp256k1_gej_add_ge(r, r, &add); + } + bits = 0; + secp256k1_ge_clear(&add); +} + +#endif diff --git a/src/secp256k1/src/ecmult_impl.h b/src/secp256k1/src/ecmult_impl.h new file mode 100644 index 0000000000..6536771046 --- /dev/null +++ b/src/secp256k1/src/ecmult_impl.h @@ -0,0 +1,248 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_ECMULT_IMPL_H_ +#define _SECP256K1_ECMULT_IMPL_H_ + +#include "group.h" +#include "scalar.h" +#include "ecmult.h" + +/* optimal for 128-bit and 256-bit exponents. */ +#define WINDOW_A 5 + +/** larger numbers may result in slightly better performance, at the cost of + exponentially larger precomputed tables. */ +#ifdef USE_ENDOMORPHISM +/** Two tables for window size 15: 1.375 MiB. */ +#define WINDOW_G 15 +#else +/** One table for window size 16: 1.375 MiB. */ +#define WINDOW_G 16 +#endif + +/** Fill a table 'pre' with precomputed odd multiples of a. W determines the size of the table. + * pre will contains the values [1*a,3*a,5*a,...,(2^(w-1)-1)*a], so it needs place for + * 2^(w-2) entries. + * + * There are two versions of this function: + * - secp256k1_ecmult_precomp_wnaf_gej, which operates on group elements in jacobian notation, + * fast to precompute, but slower to use in later additions. + * - secp256k1_ecmult_precomp_wnaf_ge, which operates on group elements in affine notations, + * (much) slower to precompute, but a bit faster to use in later additions. + * To compute a*P + b*G, we use the jacobian version for P, and the affine version for G, as + * G is constant, so it only needs to be done once in advance. + */ +static void secp256k1_ecmult_table_precomp_gej_var(secp256k1_gej_t *pre, const secp256k1_gej_t *a, int w) { + pre[0] = *a; + secp256k1_gej_t d; secp256k1_gej_double_var(&d, &pre[0]); + for (int i=1; i<(1 << (w-2)); i++) + secp256k1_gej_add_var(&pre[i], &d, &pre[i-1]); +} + +static void secp256k1_ecmult_table_precomp_ge_var(secp256k1_ge_t *pre, const secp256k1_gej_t *a, int w) { + const int table_size = 1 << (w-2); + secp256k1_gej_t *prej = checked_malloc(sizeof(secp256k1_gej_t) * table_size); + prej[0] = *a; + secp256k1_gej_t d; secp256k1_gej_double_var(&d, a); + for (int i=1; i<table_size; i++) { + secp256k1_gej_add_var(&prej[i], &d, &prej[i-1]); + } + secp256k1_ge_set_all_gej_var(table_size, pre, prej); + free(prej); +} + +/** The number of entries a table with precomputed multiples needs to have. */ +#define ECMULT_TABLE_SIZE(w) (1 << ((w)-2)) + +/** The following two macro retrieves a particular odd multiple from a table + * of precomputed multiples. */ +#define ECMULT_TABLE_GET(r,pre,n,w,neg) do { \ + VERIFY_CHECK(((n) & 1) == 1); \ + VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ + VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ + if ((n) > 0) \ + *(r) = (pre)[((n)-1)/2]; \ + else \ + (neg)((r), &(pre)[(-(n)-1)/2]); \ +} while(0) + +#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_gej_neg_var) +#define ECMULT_TABLE_GET_GE(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_ge_neg_var) + +typedef struct { + /* For accelerating the computation of a*P + b*G: */ + secp256k1_ge_t pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of the generator */ +#ifdef USE_ENDOMORPHISM + secp256k1_ge_t pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of 2^128*generator */ +#endif +} secp256k1_ecmult_consts_t; + +static const secp256k1_ecmult_consts_t *secp256k1_ecmult_consts = NULL; + +static void secp256k1_ecmult_start(void) { + if (secp256k1_ecmult_consts != NULL) + return; + + /* Allocate the precomputation table. */ + secp256k1_ecmult_consts_t *ret = (secp256k1_ecmult_consts_t*)checked_malloc(sizeof(secp256k1_ecmult_consts_t)); + + /* get the generator */ + const secp256k1_ge_t *g = &secp256k1_ge_consts->g; + secp256k1_gej_t gj; secp256k1_gej_set_ge(&gj, g); + +#ifdef USE_ENDOMORPHISM + /* calculate 2^128*generator */ + secp256k1_gej_t g_128j = gj; + for (int i=0; i<128; i++) + secp256k1_gej_double_var(&g_128j, &g_128j); +#endif + + /* precompute the tables with odd multiples */ + secp256k1_ecmult_table_precomp_ge_var(ret->pre_g, &gj, WINDOW_G); +#ifdef USE_ENDOMORPHISM + secp256k1_ecmult_table_precomp_ge_var(ret->pre_g_128, &g_128j, WINDOW_G); +#endif + + /* Set the global pointer to the precomputation table. */ + secp256k1_ecmult_consts = ret; +} + +static void secp256k1_ecmult_stop(void) { + if (secp256k1_ecmult_consts == NULL) + return; + + secp256k1_ecmult_consts_t *c = (secp256k1_ecmult_consts_t*)secp256k1_ecmult_consts; + secp256k1_ecmult_consts = NULL; + free(c); +} + +/** Convert a number to WNAF notation. The number becomes represented by sum(2^i * wnaf[i], i=0..bits), + * with the following guarantees: + * - each wnaf[i] is either 0, or an odd integer between -(1<<(w-1) - 1) and (1<<(w-1) - 1) + * - two non-zero entries in wnaf are separated by at least w-1 zeroes. + * - the number of set values in wnaf is returned. This number is at most 256, and at most one more + * - than the number of bits in the (absolute value) of the input. + */ +static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w) { + secp256k1_scalar_t s = *a; + + int sign = 1; + if (secp256k1_scalar_get_bits(&s, 255, 1)) { + secp256k1_scalar_negate(&s, &s); + sign = -1; + } + + int set_bits = 0; + int bit = 0; + while (bit < 256) { + if (secp256k1_scalar_get_bits(&s, bit, 1) == 0) { + bit++; + continue; + } + while (set_bits < bit) { + wnaf[set_bits++] = 0; + } + int now = w; + if (bit + now > 256) { + now = 256 - bit; + } + int word = secp256k1_scalar_get_bits_var(&s, bit, now); + if (word & (1 << (w-1))) { + secp256k1_scalar_add_bit(&s, bit + w); + wnaf[set_bits++] = sign * (word - (1 << w)); + } else { + wnaf[set_bits++] = sign * word; + } + bit += now; + } + 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) { + const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts; + +#ifdef USE_ENDOMORPHISM + secp256k1_scalar_t na_1, na_lam; + /* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */ + secp256k1_scalar_split_lambda_var(&na_1, &na_lam, na); + + /* build wnaf representation for na_1 and na_lam. */ + int wnaf_na_1[130]; int bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A); + int wnaf_na_lam[130]; int bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, &na_lam, WINDOW_A); + VERIFY_CHECK(bits_na_1 <= 130); + VERIFY_CHECK(bits_na_lam <= 130); + int bits = bits_na_1; + if (bits_na_lam > bits) bits = bits_na_lam; +#else + /* build wnaf representation for na. */ + int wnaf_na[256]; int bits_na = secp256k1_ecmult_wnaf(wnaf_na, na, WINDOW_A); + int bits = bits_na; +#endif + + /* calculate odd multiples of a */ + secp256k1_gej_t pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_ecmult_table_precomp_gej_var(pre_a, a, WINDOW_A); + +#ifdef USE_ENDOMORPHISM + secp256k1_gej_t pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; + for (int i=0; i<ECMULT_TABLE_SIZE(WINDOW_A); i++) + secp256k1_gej_mul_lambda(&pre_a_lam[i], &pre_a[i]); + + /* Splitted G factors. */ + secp256k1_scalar_t ng_1, ng_128; + + /* 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); + + /* Build wnaf representation for ng_1 and ng_128 */ + int wnaf_ng_1[129]; int bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G); + int wnaf_ng_128[129]; int 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; +#else + int wnaf_ng[257]; int bits_ng = secp256k1_ecmult_wnaf(wnaf_ng, ng, WINDOW_G); + if (bits_ng > bits) bits = bits_ng; +#endif + + secp256k1_gej_set_infinity(r); + secp256k1_gej_t tmpj; + secp256k1_ge_t tmpa; + + for (int i=bits-1; i>=0; i--) { + secp256k1_gej_double_var(r, r); + int n; +#ifdef USE_ENDOMORPHISM + if (i < bits_na_1 && (n = wnaf_na_1[i])) { + ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A); + secp256k1_gej_add_var(r, r, &tmpj); + } + if (i < bits_na_lam && (n = wnaf_na_lam[i])) { + ECMULT_TABLE_GET_GEJ(&tmpj, pre_a_lam, n, WINDOW_A); + secp256k1_gej_add_var(r, r, &tmpj); + } + if (i < bits_ng_1 && (n = wnaf_ng_1[i])) { + ECMULT_TABLE_GET_GE(&tmpa, c->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(&tmpa, c->pre_g_128, n, WINDOW_G); + secp256k1_gej_add_ge_var(r, r, &tmpa); + } +#else + if (i < bits_na && (n = wnaf_na[i])) { + ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A); + secp256k1_gej_add_var(r, r, &tmpj); + } + if (i < bits_ng && (n = wnaf_ng[i])) { + ECMULT_TABLE_GET_GE(&tmpa, c->pre_g, n, WINDOW_G); + secp256k1_gej_add_ge_var(r, r, &tmpa); + } +#endif + } +} + +#endif diff --git a/src/secp256k1/src/field.h b/src/secp256k1/src/field.h new file mode 100644 index 0000000000..53aa29e13f --- /dev/null +++ b/src/secp256k1/src/field.h @@ -0,0 +1,122 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_FIELD_ +#define _SECP256K1_FIELD_ + +/** Field element module. + * + * Field elements can be represented in several ways, but code accessing + * it (and implementations) need to take certain properaties into account: + * - Each field element can be normalized or not. + * - Each field element has a magnitude, which represents how far away + * its representation is away from normalization. Normalized elements + * always have a magnitude of 1, but a magnitude of 1 doesn't imply + * normality. + */ + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#if defined(USE_FIELD_GMP) +#include "field_gmp.h" +#elif defined(USE_FIELD_10X26) +#include "field_10x26.h" +#elif defined(USE_FIELD_5X52) +#include "field_5x52.h" +#else +#error "Please select field implementation" +#endif + +typedef struct { +#ifndef USE_NUM_NONE + secp256k1_num_t p; +#endif + secp256k1_fe_t order; +} secp256k1_fe_consts_t; + +static const secp256k1_fe_consts_t *secp256k1_fe_consts = NULL; + +/** Initialize field element precomputation data. */ +static void secp256k1_fe_start(void); + +/** Unload field element precomputation data. */ +static void secp256k1_fe_stop(void); + +/** Normalize a field element. */ +static void secp256k1_fe_normalize(secp256k1_fe_t *r); + +/** Normalize a field element, without constant-time guarantee. */ +static void secp256k1_fe_normalize_var(secp256k1_fe_t *r); + +/** Set a field element equal to a small integer. Resulting field element is normalized. */ +static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a); + +/** Verify whether a field element is zero. Requires the input to be normalized. */ +static int secp256k1_fe_is_zero(const secp256k1_fe_t *a); + +/** Check the "oddness" of a field element. Requires the input to be normalized. */ +static int secp256k1_fe_is_odd(const secp256k1_fe_t *a); + +/** Compare two field elements. Requires both inputs to be normalized */ +static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b); + +/** Compare two field elements. Requires both inputs to be normalized */ +static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b); + +/** Set a field element equal to 32-byte big endian value. If succesful, the resulting field element is normalized. */ +static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a); + +/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ +static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a); + +/** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input + * as an argument. The magnitude of the output is one higher. */ +static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m); + +/** Multiplies the passed field element with a small integer constant. Multiplies the magnitude by that + * small integer. */ +static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a); + +/** Adds a field element to another. The result has the sum of the inputs' magnitudes as magnitude. */ +static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a); + +/** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8. + * The output magnitude is 1 (but not guaranteed to be normalized). */ +static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b); + +/** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8. + * The output magnitude is 1 (but not guaranteed to be normalized). */ +static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a); + +/** Sets a field element to be the (modular) square root (if any exist) of another. Requires the + * input's magnitude to be at most 8. The output magnitude is 1 (but not guaranteed to be + * normalized). Return value indicates whether a square root was found. */ +static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a); + +/** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be + * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */ +static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a); + +/** Potentially faster version of secp256k1_fe_inv, without constant-time guarantee. */ +static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a); + +/** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be + * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and + * outputs must not overlap in memory. */ +static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t r[len], const secp256k1_fe_t a[len]); + +/** Convert a field element to a hexadecimal string. */ +static void secp256k1_fe_get_hex(char *r, int *rlen, const secp256k1_fe_t *a); + +/** Convert a hexadecimal string to a field element. */ +static int secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen); + +/** 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.h b/src/secp256k1/src/field_10x26.h new file mode 100644 index 0000000000..66fb3f2563 --- /dev/null +++ b/src/secp256k1/src/field_10x26.h @@ -0,0 +1,21 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_FIELD_REPR_ +#define _SECP256K1_FIELD_REPR_ + +#include <stdint.h> + +typedef struct { + /* X = sum(i=0..9, elem[i]*2^26) mod n */ + uint32_t n[10]; +#ifdef VERIFY + int magnitude; + int normalized; +#endif +} secp256k1_fe_t; + +#endif diff --git a/src/secp256k1/src/field_10x26_impl.h b/src/secp256k1/src/field_10x26_impl.h new file mode 100644 index 0000000000..d20229cda6 --- /dev/null +++ b/src/secp256k1/src/field_10x26_impl.h @@ -0,0 +1,979 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_FIELD_REPR_IMPL_H_ +#define _SECP256K1_FIELD_REPR_IMPL_H_ + +#include <stdio.h> +#include <string.h> +#include "util.h" +#include "num.h" +#include "field.h" + +static void secp256k1_fe_inner_start(void) {} +static void secp256k1_fe_inner_stop(void) {} + +#ifdef VERIFY +static void secp256k1_fe_verify(const secp256k1_fe_t *a) { + const uint32_t *d = a->n; + int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; + r &= (d[0] <= 0x3FFFFFFUL * m); + r &= (d[1] <= 0x3FFFFFFUL * m); + r &= (d[2] <= 0x3FFFFFFUL * m); + r &= (d[3] <= 0x3FFFFFFUL * m); + r &= (d[4] <= 0x3FFFFFFUL * m); + r &= (d[5] <= 0x3FFFFFFUL * m); + r &= (d[6] <= 0x3FFFFFFUL * m); + r &= (d[7] <= 0x3FFFFFFUL * m); + r &= (d[8] <= 0x3FFFFFFUL * m); + r &= (d[9] <= 0x03FFFFFUL * m); + r &= (a->magnitude >= 0); + if (a->normalized) { + r &= (a->magnitude <= 1); + if (r && (d[9] == 0x03FFFFFUL)) { + uint32_t mid = d[8] & d[7] & d[6] & d[5] & d[4] & d[3] & d[2]; + if (mid == 0x3FFFFFFUL) { + r &= ((d[1] + 0x40UL + ((d[0] + 0x3D1UL) >> 26)) <= 0x3FFFFFFUL); + } + } + } + VERIFY_CHECK(r == 1); +} +#else +static void secp256k1_fe_verify(const secp256k1_fe_t *a) { + (void)a; +} +#endif + +static void secp256k1_fe_normalize(secp256k1_fe_t *r) { + uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], + t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; + + /* Reduce t9 at the start so there will be at most a single carry from the first pass */ + uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; + uint32_t m; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8; + + /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t9 >> 23 == 0); + + /* At most a single final reduction is needed; check if the value is >= the field characteristic */ + x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL) + & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL)); + + /* Apply the final reduction (for constant-time behaviour, we do it always) */ + t0 += x * 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; + + /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */ + VERIFY_CHECK(t9 >> 22 == x); + + /* Mask off the possible multiple of 2^256 from the final reduction */ + t9 &= 0x03FFFFFUL; + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; + +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { + uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], + t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; + + /* Reduce t9 at the start so there will be at most a single carry from the first pass */ + uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL; + uint32_t m; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8; + + /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t9 >> 23 == 0); + + /* At most a single final reduction is needed; check if the value is >= the field characteristic */ + x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL) + & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL)); + + if (x) { + t0 += 0x3D1UL; t1 += (x << 6); + t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; + t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; + t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; + t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; + t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; + t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; + t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; + t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; + t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; + + /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */ + VERIFY_CHECK(t9 >> 22 == x); + + /* Mask off the possible multiple of 2^256 from the final reduction */ + t9 &= 0x03FFFFFUL; + } + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9; + +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { + r->n[0] = a; + r->n[1] = r->n[2] = r->n[3] = r->n[4] = r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0; +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + secp256k1_fe_verify(a); +#endif + const uint32_t *t = a->n; + return (t[0] | t[1] | t[2] | t[3] | t[4] | t[5] | t[6] | t[7] | t[8] | t[9]) == 0; +} + +SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + secp256k1_fe_verify(a); +#endif + return a->n[0] & 1; +} + +SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { +#ifdef VERIFY + a->magnitude = 0; + a->normalized = 1; +#endif + for (int i=0; i<10; i++) { + a->n[i] = 0; + } +} + +SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + VERIFY_CHECK(b->normalized); + secp256k1_fe_verify(a); + secp256k1_fe_verify(b); +#endif + const uint32_t *t = a->n, *u = b->n; + return ((t[0]^u[0]) | (t[1]^u[1]) | (t[2]^u[2]) | (t[3]^u[3]) | (t[4]^u[4]) + | (t[5]^u[5]) | (t[6]^u[6]) | (t[7]^u[7]) | (t[8]^u[8]) | (t[9]^u[9])) == 0; +} + +static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + VERIFY_CHECK(b->normalized); + secp256k1_fe_verify(a); + secp256k1_fe_verify(b); +#endif + for (int i = 9; i >= 0; i--) { + if (a->n[i] > b->n[i]) return 1; + if (a->n[i] < b->n[i]) return -1; + } + return 0; +} + +static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { + r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; + r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0; + for (int i=0; i<32; i++) { + for (int j=0; j<4; j++) { + int limb = (8*i+2*j)/26; + int shift = (8*i+2*j)%26; + r->n[limb] |= (uint32_t)((a[31-i] >> (2*j)) & 0x3) << shift; + } + } + if (r->n[9] == 0x3FFFFFUL && (r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL && (r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL) { + return 0; + } +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif + return 1; +} + +/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ +static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + secp256k1_fe_verify(a); +#endif + for (int i=0; i<32; i++) { + int c = 0; + for (int j=0; j<4; j++) { + int limb = (8*i+2*j)/26; + int shift = (8*i+2*j)%26; + c |= ((a->n[limb] >> shift) & 0x3) << (2 * j); + } + r[31-i] = c; + } +} + +SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) { +#ifdef VERIFY + VERIFY_CHECK(a->magnitude <= m); + secp256k1_fe_verify(a); +#endif + r->n[0] = 0x3FFFC2FUL * 2 * (m + 1) - a->n[0]; + r->n[1] = 0x3FFFFBFUL * 2 * (m + 1) - a->n[1]; + r->n[2] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[2]; + r->n[3] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[3]; + r->n[4] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[4]; + r->n[5] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[5]; + r->n[6] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[6]; + r->n[7] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[7]; + r->n[8] = 0x3FFFFFFUL * 2 * (m + 1) - a->n[8]; + r->n[9] = 0x03FFFFFUL * 2 * (m + 1) - a->n[9]; +#ifdef VERIFY + r->magnitude = m + 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) { + r->n[0] *= a; + r->n[1] *= a; + r->n[2] *= a; + r->n[3] *= a; + r->n[4] *= a; + r->n[5] *= a; + r->n[6] *= a; + r->n[7] *= a; + r->n[8] *= a; + r->n[9] *= a; +#ifdef VERIFY + r->magnitude *= a; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +#ifdef VERIFY + secp256k1_fe_verify(a); +#endif + r->n[0] += a->n[0]; + r->n[1] += a->n[1]; + r->n[2] += a->n[2]; + r->n[3] += a->n[3]; + r->n[4] += a->n[4]; + r->n[5] += a->n[5]; + r->n[6] += a->n[6]; + r->n[7] += a->n[7]; + r->n[8] += a->n[8]; + r->n[9] += a->n[9]; +#ifdef VERIFY + r->magnitude += a->magnitude; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +#ifdef VERIFY +#define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) +#else +#define VERIFY_BITS(x, n) do { } while(0) +#endif + +SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b) { + VERIFY_BITS(a[0], 30); + VERIFY_BITS(a[1], 30); + VERIFY_BITS(a[2], 30); + VERIFY_BITS(a[3], 30); + VERIFY_BITS(a[4], 30); + VERIFY_BITS(a[5], 30); + VERIFY_BITS(a[6], 30); + VERIFY_BITS(a[7], 30); + VERIFY_BITS(a[8], 30); + VERIFY_BITS(a[9], 26); + VERIFY_BITS(b[0], 30); + VERIFY_BITS(b[1], 30); + VERIFY_BITS(b[2], 30); + VERIFY_BITS(b[3], 30); + VERIFY_BITS(b[4], 30); + VERIFY_BITS(b[5], 30); + VERIFY_BITS(b[6], 30); + VERIFY_BITS(b[7], 30); + VERIFY_BITS(b[8], 30); + VERIFY_BITS(b[9], 26); + + const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; + /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n. + * px is a shorthand for sum(a[i]*b[x-i], i=0..x). + * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0]. + */ + + uint64_t c, d; + + d = (uint64_t)a[0] * b[9] + + (uint64_t)a[1] * b[8] + + (uint64_t)a[2] * b[7] + + (uint64_t)a[3] * b[6] + + (uint64_t)a[4] * b[5] + + (uint64_t)a[5] * b[4] + + (uint64_t)a[6] * b[3] + + (uint64_t)a[7] * b[2] + + (uint64_t)a[8] * b[1] + + (uint64_t)a[9] * b[0]; + /* VERIFY_BITS(d, 64); */ + /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ + uint32_t t9 = d & M; d >>= 26; + VERIFY_BITS(t9, 26); + VERIFY_BITS(d, 38); + /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ + + c = (uint64_t)a[0] * b[0]; + VERIFY_BITS(c, 60); + /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */ + d += (uint64_t)a[1] * b[9] + + (uint64_t)a[2] * b[8] + + (uint64_t)a[3] * b[7] + + (uint64_t)a[4] * b[6] + + (uint64_t)a[5] * b[5] + + (uint64_t)a[6] * b[4] + + (uint64_t)a[7] * b[3] + + (uint64_t)a[8] * b[2] + + (uint64_t)a[9] * b[1]; + VERIFY_BITS(d, 63); + /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + uint64_t u0 = d & M; d >>= 26; c += u0 * R0; + VERIFY_BITS(u0, 26); + VERIFY_BITS(d, 37); + VERIFY_BITS(c, 61); + /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + uint32_t t0 = c & M; c >>= 26; c += u0 * R1; + VERIFY_BITS(t0, 26); + VERIFY_BITS(c, 37); + /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + + c += (uint64_t)a[0] * b[1] + + (uint64_t)a[1] * b[0]; + VERIFY_BITS(c, 62); + /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */ + d += (uint64_t)a[2] * b[9] + + (uint64_t)a[3] * b[8] + + (uint64_t)a[4] * b[7] + + (uint64_t)a[5] * b[6] + + (uint64_t)a[6] * b[5] + + (uint64_t)a[7] * b[4] + + (uint64_t)a[8] * b[3] + + (uint64_t)a[9] * b[2]; + VERIFY_BITS(d, 63); + /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + uint64_t u1 = d & M; d >>= 26; c += u1 * R0; + VERIFY_BITS(u1, 26); + VERIFY_BITS(d, 37); + VERIFY_BITS(c, 63); + /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + uint32_t t1 = c & M; c >>= 26; c += u1 * R1; + VERIFY_BITS(t1, 26); + VERIFY_BITS(c, 38); + /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + + c += (uint64_t)a[0] * b[2] + + (uint64_t)a[1] * b[1] + + (uint64_t)a[2] * b[0]; + VERIFY_BITS(c, 62); + /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + d += (uint64_t)a[3] * b[9] + + (uint64_t)a[4] * b[8] + + (uint64_t)a[5] * b[7] + + (uint64_t)a[6] * b[6] + + (uint64_t)a[7] * b[5] + + (uint64_t)a[8] * b[4] + + (uint64_t)a[9] * b[3]; + VERIFY_BITS(d, 63); + /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + uint64_t u2 = d & M; d >>= 26; c += u2 * R0; + VERIFY_BITS(u2, 26); + VERIFY_BITS(d, 37); + VERIFY_BITS(c, 63); + /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + uint32_t t2 = c & M; c >>= 26; c += u2 * R1; + VERIFY_BITS(t2, 26); + VERIFY_BITS(c, 38); + /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + + c += (uint64_t)a[0] * b[3] + + (uint64_t)a[1] * b[2] + + (uint64_t)a[2] * b[1] + + (uint64_t)a[3] * b[0]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + d += (uint64_t)a[4] * b[9] + + (uint64_t)a[5] * b[8] + + (uint64_t)a[6] * b[7] + + (uint64_t)a[7] * b[6] + + (uint64_t)a[8] * b[5] + + (uint64_t)a[9] * b[4]; + VERIFY_BITS(d, 63); + /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + uint64_t u3 = d & M; d >>= 26; c += u3 * R0; + VERIFY_BITS(u3, 26); + VERIFY_BITS(d, 37); + /* VERIFY_BITS(c, 64); */ + /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + uint32_t t3 = c & M; c >>= 26; c += u3 * R1; + VERIFY_BITS(t3, 26); + VERIFY_BITS(c, 39); + /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + + c += (uint64_t)a[0] * b[4] + + (uint64_t)a[1] * b[3] + + (uint64_t)a[2] * b[2] + + (uint64_t)a[3] * b[1] + + (uint64_t)a[4] * b[0]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + d += (uint64_t)a[5] * b[9] + + (uint64_t)a[6] * b[8] + + (uint64_t)a[7] * b[7] + + (uint64_t)a[8] * b[6] + + (uint64_t)a[9] * b[5]; + VERIFY_BITS(d, 62); + /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + uint64_t u4 = d & M; d >>= 26; c += u4 * R0; + VERIFY_BITS(u4, 26); + VERIFY_BITS(d, 36); + /* VERIFY_BITS(c, 64); */ + /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + uint32_t t4 = c & M; c >>= 26; c += u4 * R1; + VERIFY_BITS(t4, 26); + VERIFY_BITS(c, 39); + /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + + c += (uint64_t)a[0] * b[5] + + (uint64_t)a[1] * b[4] + + (uint64_t)a[2] * b[3] + + (uint64_t)a[3] * b[2] + + (uint64_t)a[4] * b[1] + + (uint64_t)a[5] * b[0]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)a[6] * b[9] + + (uint64_t)a[7] * b[8] + + (uint64_t)a[8] * b[7] + + (uint64_t)a[9] * b[6]; + VERIFY_BITS(d, 62); + /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + uint64_t u5 = d & M; d >>= 26; c += u5 * R0; + VERIFY_BITS(u5, 26); + VERIFY_BITS(d, 36); + /* VERIFY_BITS(c, 64); */ + /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + uint32_t t5 = c & M; c >>= 26; c += u5 * R1; + VERIFY_BITS(t5, 26); + VERIFY_BITS(c, 39); + /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + + c += (uint64_t)a[0] * b[6] + + (uint64_t)a[1] * b[5] + + (uint64_t)a[2] * b[4] + + (uint64_t)a[3] * b[3] + + (uint64_t)a[4] * b[2] + + (uint64_t)a[5] * b[1] + + (uint64_t)a[6] * b[0]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)a[7] * b[9] + + (uint64_t)a[8] * b[8] + + (uint64_t)a[9] * b[7]; + VERIFY_BITS(d, 61); + /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + uint64_t u6 = d & M; d >>= 26; c += u6 * R0; + VERIFY_BITS(u6, 26); + VERIFY_BITS(d, 35); + /* VERIFY_BITS(c, 64); */ + /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + uint32_t t6 = c & M; c >>= 26; c += u6 * R1; + VERIFY_BITS(t6, 26); + VERIFY_BITS(c, 39); + /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + + c += (uint64_t)a[0] * b[7] + + (uint64_t)a[1] * b[6] + + (uint64_t)a[2] * b[5] + + (uint64_t)a[3] * b[4] + + (uint64_t)a[4] * b[3] + + (uint64_t)a[5] * b[2] + + (uint64_t)a[6] * b[1] + + (uint64_t)a[7] * b[0]; + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x8000007C00000007ULL); + /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)a[8] * b[9] + + (uint64_t)a[9] * b[8]; + VERIFY_BITS(d, 58); + /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + uint64_t u7 = d & M; d >>= 26; c += u7 * R0; + VERIFY_BITS(u7, 26); + VERIFY_BITS(d, 32); + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL); + /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + uint32_t t7 = c & M; c >>= 26; c += u7 * R1; + VERIFY_BITS(t7, 26); + VERIFY_BITS(c, 38); + /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + + c += (uint64_t)a[0] * b[8] + + (uint64_t)a[1] * b[7] + + (uint64_t)a[2] * b[6] + + (uint64_t)a[3] * b[5] + + (uint64_t)a[4] * b[4] + + (uint64_t)a[5] * b[3] + + (uint64_t)a[6] * b[2] + + (uint64_t)a[7] * b[1] + + (uint64_t)a[8] * b[0]; + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x9000007B80000008ULL); + /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)a[9] * b[9]; + VERIFY_BITS(d, 57); + /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + uint64_t u8 = d & M; d >>= 26; c += u8 * R0; + VERIFY_BITS(u8, 26); + VERIFY_BITS(d, 31); + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + r[3] = t3; + VERIFY_BITS(r[3], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[4] = t4; + VERIFY_BITS(r[4], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[5] = t5; + VERIFY_BITS(r[5], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[6] = t6; + VERIFY_BITS(r[6], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[7] = t7; + VERIFY_BITS(r[7], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + r[8] = c & M; c >>= 26; c += u8 * R1; + VERIFY_BITS(r[8], 26); + VERIFY_BITS(c, 39); + /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += d * R0 + t9; + VERIFY_BITS(c, 45); + /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4); + VERIFY_BITS(r[9], 22); + VERIFY_BITS(c, 46); + /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + d = c * (R0 >> 4) + t0; + VERIFY_BITS(d, 56); + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[0] = d & M; d >>= 26; + VERIFY_BITS(r[0], 26); + VERIFY_BITS(d, 30); + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += c * (R1 >> 4) + t1; + VERIFY_BITS(d, 53); + VERIFY_CHECK(d <= 0x10000003FFFFBFULL); + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[1] = d & M; d >>= 26; + VERIFY_BITS(r[1], 26); + VERIFY_BITS(d, 27); + VERIFY_CHECK(d <= 0x4000000ULL); + /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += t2; + VERIFY_BITS(d, 27); + /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[2] = d; + VERIFY_BITS(r[2], 27); + /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ +} + +SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a) { + VERIFY_BITS(a[0], 30); + VERIFY_BITS(a[1], 30); + VERIFY_BITS(a[2], 30); + VERIFY_BITS(a[3], 30); + VERIFY_BITS(a[4], 30); + VERIFY_BITS(a[5], 30); + VERIFY_BITS(a[6], 30); + VERIFY_BITS(a[7], 30); + VERIFY_BITS(a[8], 30); + VERIFY_BITS(a[9], 26); + + const uint32_t M = 0x3FFFFFFUL, R0 = 0x3D10UL, R1 = 0x400UL; + /** [... a b c] is a shorthand for ... + a<<52 + b<<26 + c<<0 mod n. + * px is a shorthand for sum(a[i]*a[x-i], i=0..x). + * Note that [x 0 0 0 0 0 0 0 0 0 0] = [x*R1 x*R0]. + */ + + uint64_t c, d; + + d = (uint64_t)(a[0]*2) * a[9] + + (uint64_t)(a[1]*2) * a[8] + + (uint64_t)(a[2]*2) * a[7] + + (uint64_t)(a[3]*2) * a[6] + + (uint64_t)(a[4]*2) * a[5]; + /* VERIFY_BITS(d, 64); */ + /* [d 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ + uint32_t t9 = d & M; d >>= 26; + VERIFY_BITS(t9, 26); + VERIFY_BITS(d, 38); + /* [d t9 0 0 0 0 0 0 0 0 0] = [p9 0 0 0 0 0 0 0 0 0] */ + + c = (uint64_t)a[0] * a[0]; + VERIFY_BITS(c, 60); + /* [d t9 0 0 0 0 0 0 0 0 c] = [p9 0 0 0 0 0 0 0 0 p0] */ + d += (uint64_t)(a[1]*2) * a[9] + + (uint64_t)(a[2]*2) * a[8] + + (uint64_t)(a[3]*2) * a[7] + + (uint64_t)(a[4]*2) * a[6] + + (uint64_t)a[5] * a[5]; + VERIFY_BITS(d, 63); + /* [d t9 0 0 0 0 0 0 0 0 c] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + uint64_t u0 = d & M; d >>= 26; c += u0 * R0; + VERIFY_BITS(u0, 26); + VERIFY_BITS(d, 37); + VERIFY_BITS(c, 61); + /* [d u0 t9 0 0 0 0 0 0 0 0 c-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + uint32_t t0 = c & M; c >>= 26; c += u0 * R1; + VERIFY_BITS(t0, 26); + VERIFY_BITS(c, 37); + /* [d u0 t9 0 0 0 0 0 0 0 c-u0*R1 t0-u0*R0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 0 p0] */ + + c += (uint64_t)(a[0]*2) * a[1]; + VERIFY_BITS(c, 62); + /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p10 p9 0 0 0 0 0 0 0 p1 p0] */ + d += (uint64_t)(a[2]*2) * a[9] + + (uint64_t)(a[3]*2) * a[8] + + (uint64_t)(a[4]*2) * a[7] + + (uint64_t)(a[5]*2) * a[6]; + VERIFY_BITS(d, 63); + /* [d 0 t9 0 0 0 0 0 0 0 c t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + uint64_t u1 = d & M; d >>= 26; c += u1 * R0; + VERIFY_BITS(u1, 26); + VERIFY_BITS(d, 37); + VERIFY_BITS(c, 63); + /* [d u1 0 t9 0 0 0 0 0 0 0 c-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + uint32_t t1 = c & M; c >>= 26; c += u1 * R1; + VERIFY_BITS(t1, 26); + VERIFY_BITS(c, 38); + /* [d u1 0 t9 0 0 0 0 0 0 c-u1*R1 t1-u1*R0 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 0 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[2] + + (uint64_t)a[1] * a[1]; + VERIFY_BITS(c, 62); + /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + d += (uint64_t)(a[3]*2) * a[9] + + (uint64_t)(a[4]*2) * a[8] + + (uint64_t)(a[5]*2) * a[7] + + (uint64_t)a[6] * a[6]; + VERIFY_BITS(d, 63); + /* [d 0 0 t9 0 0 0 0 0 0 c t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + uint64_t u2 = d & M; d >>= 26; c += u2 * R0; + VERIFY_BITS(u2, 26); + VERIFY_BITS(d, 37); + VERIFY_BITS(c, 63); + /* [d u2 0 0 t9 0 0 0 0 0 0 c-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + uint32_t t2 = c & M; c >>= 26; c += u2 * R1; + VERIFY_BITS(t2, 26); + VERIFY_BITS(c, 38); + /* [d u2 0 0 t9 0 0 0 0 0 c-u2*R1 t2-u2*R0 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 0 p2 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[3] + + (uint64_t)(a[1]*2) * a[2]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + d += (uint64_t)(a[4]*2) * a[9] + + (uint64_t)(a[5]*2) * a[8] + + (uint64_t)(a[6]*2) * a[7]; + VERIFY_BITS(d, 63); + /* [d 0 0 0 t9 0 0 0 0 0 c t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + uint64_t u3 = d & M; d >>= 26; c += u3 * R0; + VERIFY_BITS(u3, 26); + VERIFY_BITS(d, 37); + /* VERIFY_BITS(c, 64); */ + /* [d u3 0 0 0 t9 0 0 0 0 0 c-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + uint32_t t3 = c & M; c >>= 26; c += u3 * R1; + VERIFY_BITS(t3, 26); + VERIFY_BITS(c, 39); + /* [d u3 0 0 0 t9 0 0 0 0 c-u3*R1 t3-u3*R0 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 0 p3 p2 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[4] + + (uint64_t)(a[1]*2) * a[3] + + (uint64_t)a[2] * a[2]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + d += (uint64_t)(a[5]*2) * a[9] + + (uint64_t)(a[6]*2) * a[8] + + (uint64_t)a[7] * a[7]; + VERIFY_BITS(d, 62); + /* [d 0 0 0 0 t9 0 0 0 0 c t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + uint64_t u4 = d & M; d >>= 26; c += u4 * R0; + VERIFY_BITS(u4, 26); + VERIFY_BITS(d, 36); + /* VERIFY_BITS(c, 64); */ + /* [d u4 0 0 0 0 t9 0 0 0 0 c-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + uint32_t t4 = c & M; c >>= 26; c += u4 * R1; + VERIFY_BITS(t4, 26); + VERIFY_BITS(c, 39); + /* [d u4 0 0 0 0 t9 0 0 0 c-u4*R1 t4-u4*R0 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 0 p4 p3 p2 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[5] + + (uint64_t)(a[1]*2) * a[4] + + (uint64_t)(a[2]*2) * a[3]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)(a[6]*2) * a[9] + + (uint64_t)(a[7]*2) * a[8]; + VERIFY_BITS(d, 62); + /* [d 0 0 0 0 0 t9 0 0 0 c t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + uint64_t u5 = d & M; d >>= 26; c += u5 * R0; + VERIFY_BITS(u5, 26); + VERIFY_BITS(d, 36); + /* VERIFY_BITS(c, 64); */ + /* [d u5 0 0 0 0 0 t9 0 0 0 c-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + uint32_t t5 = c & M; c >>= 26; c += u5 * R1; + VERIFY_BITS(t5, 26); + VERIFY_BITS(c, 39); + /* [d u5 0 0 0 0 0 t9 0 0 c-u5*R1 t5-u5*R0 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 0 p5 p4 p3 p2 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[6] + + (uint64_t)(a[1]*2) * a[5] + + (uint64_t)(a[2]*2) * a[4] + + (uint64_t)a[3] * a[3]; + VERIFY_BITS(c, 63); + /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)(a[7]*2) * a[9] + + (uint64_t)a[8] * a[8]; + VERIFY_BITS(d, 61); + /* [d 0 0 0 0 0 0 t9 0 0 c t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + uint64_t u6 = d & M; d >>= 26; c += u6 * R0; + VERIFY_BITS(u6, 26); + VERIFY_BITS(d, 35); + /* VERIFY_BITS(c, 64); */ + /* [d u6 0 0 0 0 0 0 t9 0 0 c-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + uint32_t t6 = c & M; c >>= 26; c += u6 * R1; + VERIFY_BITS(t6, 26); + VERIFY_BITS(c, 39); + /* [d u6 0 0 0 0 0 0 t9 0 c-u6*R1 t6-u6*R0 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 0 p6 p5 p4 p3 p2 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[7] + + (uint64_t)(a[1]*2) * a[6] + + (uint64_t)(a[2]*2) * a[5] + + (uint64_t)(a[3]*2) * a[4]; + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x8000007C00000007ULL); + /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)(a[8]*2) * a[9]; + VERIFY_BITS(d, 58); + /* [d 0 0 0 0 0 0 0 t9 0 c t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + uint64_t u7 = d & M; d >>= 26; c += u7 * R0; + VERIFY_BITS(u7, 26); + VERIFY_BITS(d, 32); + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x800001703FFFC2F7ULL); + /* [d u7 0 0 0 0 0 0 0 t9 0 c-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + uint32_t t7 = c & M; c >>= 26; c += u7 * R1; + VERIFY_BITS(t7, 26); + VERIFY_BITS(c, 38); + /* [d u7 0 0 0 0 0 0 0 t9 c-u7*R1 t7-u7*R0 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 0 p7 p6 p5 p4 p3 p2 p1 p0] */ + + c += (uint64_t)(a[0]*2) * a[8] + + (uint64_t)(a[1]*2) * a[7] + + (uint64_t)(a[2]*2) * a[6] + + (uint64_t)(a[3]*2) * a[5] + + (uint64_t)a[4] * a[4]; + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x9000007B80000008ULL); + /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += (uint64_t)a[9] * a[9]; + VERIFY_BITS(d, 57); + /* [d 0 0 0 0 0 0 0 0 t9 c t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + uint64_t u8 = d & M; d >>= 26; c += u8 * R0; + VERIFY_BITS(u8, 26); + VERIFY_BITS(d, 31); + /* VERIFY_BITS(c, 64); */ + VERIFY_CHECK(c <= 0x9000016FBFFFC2F8ULL); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 t3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + r[3] = t3; + VERIFY_BITS(r[3], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 t4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[4] = t4; + VERIFY_BITS(r[4], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 t5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[5] = t5; + VERIFY_BITS(r[5], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 t6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[6] = t6; + VERIFY_BITS(r[6], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 t7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[7] = t7; + VERIFY_BITS(r[7], 26); + /* [d u8 0 0 0 0 0 0 0 0 t9 c-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + r[8] = c & M; c >>= 26; c += u8 * R1; + VERIFY_BITS(r[8], 26); + VERIFY_BITS(c, 39); + /* [d u8 0 0 0 0 0 0 0 0 t9+c-u8*R1 r8-u8*R0 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 0 0 t9+c r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += d * R0 + t9; + VERIFY_BITS(c, 45); + /* [d 0 0 0 0 0 0 0 0 0 c-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[9] = c & (M >> 4); c >>= 22; c += d * (R1 << 4); + VERIFY_BITS(r[9], 22); + VERIFY_BITS(c, 46); + /* [d 0 0 0 0 0 0 0 0 r9+((c-d*R1<<4)<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [d 0 0 0 0 0 0 0 -d*R1 r9+(c<<22)-d*R0 r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 t0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + d = c * (R0 >> 4) + t0; + VERIFY_BITS(d, 56); + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1 d-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[0] = d & M; d >>= 26; + VERIFY_BITS(r[0], 26); + VERIFY_BITS(d, 30); + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 t1+d r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += c * (R1 >> 4) + t1; + VERIFY_BITS(d, 53); + VERIFY_CHECK(d <= 0x10000003FFFFBFULL); + /* [r9+(c<<22) r8 r7 r6 r5 r4 r3 t2 d-c*R1>>4 r0-c*R0>>4] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + /* [r9 r8 r7 r6 r5 r4 r3 t2 d r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[1] = d & M; d >>= 26; + VERIFY_BITS(r[1], 26); + VERIFY_BITS(d, 27); + VERIFY_CHECK(d <= 0x4000000ULL); + /* [r9 r8 r7 r6 r5 r4 r3 t2+d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + d += t2; + VERIFY_BITS(d, 27); + /* [r9 r8 r7 r6 r5 r4 r3 d r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[2] = d; + VERIFY_BITS(r[2], 27); + /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ +} + + +static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) { +#ifdef VERIFY + VERIFY_CHECK(a->magnitude <= 8); + VERIFY_CHECK(b->magnitude <= 8); + secp256k1_fe_verify(a); + secp256k1_fe_verify(b); + VERIFY_CHECK(r != b); +#endif + secp256k1_fe_mul_inner(r->n, a->n, b->n); +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +#ifdef VERIFY + VERIFY_CHECK(a->magnitude <= 8); + secp256k1_fe_verify(a); +#endif + secp256k1_fe_sqr_inner(r->n, a->n); +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) { + uint32_t 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 + if (flag) { + r->magnitude = a->magnitude; + r->normalized = a->normalized; + } +#endif +} + +#endif diff --git a/src/secp256k1/src/field_5x52.h b/src/secp256k1/src/field_5x52.h new file mode 100644 index 0000000000..aeb0a6a1e8 --- /dev/null +++ b/src/secp256k1/src/field_5x52.h @@ -0,0 +1,21 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_FIELD_REPR_ +#define _SECP256K1_FIELD_REPR_ + +#include <stdint.h> + +typedef struct { + /* X = sum(i=0..4, elem[i]*2^52) mod n */ + uint64_t n[5]; +#ifdef VERIFY + int magnitude; + int normalized; +#endif +} secp256k1_fe_t; + +#endif diff --git a/src/secp256k1/src/field_5x52_asm_impl.h b/src/secp256k1/src/field_5x52_asm_impl.h new file mode 100644 index 0000000000..98cc004bf0 --- /dev/null +++ b/src/secp256k1/src/field_5x52_asm_impl.h @@ -0,0 +1,502 @@ +/********************************************************************** + * Copyright (c) 2013-2014 Diederik Huys, Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +/** + * Changelog: + * - March 2013, Diederik Huys: original version + * - November 2014, Pieter Wuille: updated to use Peter Dettman's parallel multiplication algorithm + * - December 2014, Pieter Wuille: converted from YASM to GCC inline assembly + */ + +#ifndef _SECP256K1_FIELD_INNER5X52_IMPL_H_ +#define _SECP256K1_FIELD_INNER5X52_IMPL_H_ + +SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) { +/** + * Registers: rdx:rax = multiplication accumulator + * r9:r8 = c + * r15:rcx = d + * r10-r14 = a0-a4 + * rbx = b + * rdi = r + * rsi = a / t? + */ + uint64_t tmp1, tmp2, tmp3; +__asm__ __volatile__( + "movq 0(%%rsi),%%r10\n" + "movq 8(%%rsi),%%r11\n" + "movq 16(%%rsi),%%r12\n" + "movq 24(%%rsi),%%r13\n" + "movq 32(%%rsi),%%r14\n" + + /* d += a3 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r13\n" + "movq %%rax,%%rcx\n" + "movq %%rdx,%%r15\n" + /* d += a2 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a1 * b2 */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d = a0 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r10\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* c = a4 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r14\n" + "movq %%rax,%%r8\n" + "movq %%rdx,%%r9\n" + /* d += (c & M) * R */ + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* c >>= 52 (%%r8 only) */ + "shrdq $52,%%r9,%%r8\n" + /* t3 (tmp1) = d & M */ + "movq %%rcx,%%rsi\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rsi\n" + "movq %%rsi,%q1\n" + /* d >>= 52 */ + "shrdq $52,%%r15,%%rcx\n" + "xorq %%r15,%%r15\n" + /* d += a4 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a3 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a2 * b2 */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a1 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a0 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r10\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += c * R */ + "movq %%r8,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* t4 = d & M (%%rsi) */ + "movq %%rcx,%%rsi\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rsi\n" + /* d >>= 52 */ + "shrdq $52,%%r15,%%rcx\n" + "xorq %%r15,%%r15\n" + /* tx = t4 >> 48 (tmp3) */ + "movq %%rsi,%%rax\n" + "shrq $48,%%rax\n" + "movq %%rax,%q3\n" + /* t4 &= (M >> 4) (tmp2) */ + "movq $0xffffffffffff,%%rax\n" + "andq %%rax,%%rsi\n" + "movq %%rsi,%q2\n" + /* c = a0 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r10\n" + "movq %%rax,%%r8\n" + "movq %%rdx,%%r9\n" + /* d += a4 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a3 * b2 */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a2 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a1 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* u0 = d & M (%%rsi) */ + "movq %%rcx,%%rsi\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rsi\n" + /* d >>= 52 */ + "shrdq $52,%%r15,%%rcx\n" + "xorq %%r15,%%r15\n" + /* u0 = (u0 << 4) | tx (%%rsi) */ + "shlq $4,%%rsi\n" + "movq %q3,%%rax\n" + "orq %%rax,%%rsi\n" + /* c += u0 * (R >> 4) */ + "movq $0x1000003d1,%%rax\n" + "mulq %%rsi\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* r[0] = c & M */ + "movq %%r8,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq %%rax,0(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += a1 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* c += a0 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r10\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d += a4 * b2 */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a3 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a2 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* c += (d & M) * R */ + "movq %%rcx,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d >>= 52 */ + "shrdq $52,%%r15,%%rcx\n" + "xorq %%r15,%%r15\n" + /* r[1] = c & M */ + "movq %%r8,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq %%rax,8(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += a2 * b0 */ + "movq 0(%%rbx),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* c += a1 * b1 */ + "movq 8(%%rbx),%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* c += a0 * b2 (last use of %%r10 = a0) */ + "movq 16(%%rbx),%%rax\n" + "mulq %%r10\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* fetch t3 (%%r10, overwrites a0), t4 (%%rsi) */ + "movq %q2,%%rsi\n" + "movq %q1,%%r10\n" + /* d += a4 * b3 */ + "movq 24(%%rbx),%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* d += a3 * b4 */ + "movq 32(%%rbx),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rcx\n" + "adcq %%rdx,%%r15\n" + /* c += (d & M) * R */ + "movq %%rcx,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d >>= 52 (%%rcx only) */ + "shrdq $52,%%r15,%%rcx\n" + /* r[2] = c & M */ + "movq %%r8,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq %%rax,16(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += t3 */ + "addq %%r10,%%r8\n" + /* c += d * R */ + "movq %%rcx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* r[3] = c & M */ + "movq %%r8,%%rax\n" + "movq $0xfffffffffffff,%%rdx\n" + "andq %%rdx,%%rax\n" + "movq %%rax,24(%%rdi)\n" + /* c >>= 52 (%%r8 only) */ + "shrdq $52,%%r9,%%r8\n" + /* c += t4 (%%r8 only) */ + "addq %%rsi,%%r8\n" + /* r[4] = c */ + "movq %%r8,32(%%rdi)\n" +: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3) +: "b"(b), "D"(r) +: "%rax", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory" +); +} + +SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) { +/** + * Registers: rdx:rax = multiplication accumulator + * r9:r8 = c + * rcx:rbx = d + * r10-r14 = a0-a4 + * r15 = M (0xfffffffffffff) + * rdi = r + * rsi = a / t? + */ + uint64_t tmp1, tmp2, tmp3; +__asm__ __volatile__( + "movq 0(%%rsi),%%r10\n" + "movq 8(%%rsi),%%r11\n" + "movq 16(%%rsi),%%r12\n" + "movq 24(%%rsi),%%r13\n" + "movq 32(%%rsi),%%r14\n" + "movq $0xfffffffffffff,%%r15\n" + + /* d = (a0*2) * a3 */ + "leaq (%%r10,%%r10,1),%%rax\n" + "mulq %%r13\n" + "movq %%rax,%%rbx\n" + "movq %%rdx,%%rcx\n" + /* d += (a1*2) * a2 */ + "leaq (%%r11,%%r11,1),%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* c = a4 * a4 */ + "movq %%r14,%%rax\n" + "mulq %%r14\n" + "movq %%rax,%%r8\n" + "movq %%rdx,%%r9\n" + /* d += (c & M) * R */ + "andq %%r15,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* c >>= 52 (%%r8 only) */ + "shrdq $52,%%r9,%%r8\n" + /* t3 (tmp1) = d & M */ + "movq %%rbx,%%rsi\n" + "andq %%r15,%%rsi\n" + "movq %%rsi,%q1\n" + /* d >>= 52 */ + "shrdq $52,%%rcx,%%rbx\n" + "xorq %%rcx,%%rcx\n" + /* a4 *= 2 */ + "addq %%r14,%%r14\n" + /* d += a0 * a4 */ + "movq %%r10,%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d+= (a1*2) * a3 */ + "leaq (%%r11,%%r11,1),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d += a2 * a2 */ + "movq %%r12,%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d += c * R */ + "movq %%r8,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* t4 = d & M (%%rsi) */ + "movq %%rbx,%%rsi\n" + "andq %%r15,%%rsi\n" + /* d >>= 52 */ + "shrdq $52,%%rcx,%%rbx\n" + "xorq %%rcx,%%rcx\n" + /* tx = t4 >> 48 (tmp3) */ + "movq %%rsi,%%rax\n" + "shrq $48,%%rax\n" + "movq %%rax,%q3\n" + /* t4 &= (M >> 4) (tmp2) */ + "movq $0xffffffffffff,%%rax\n" + "andq %%rax,%%rsi\n" + "movq %%rsi,%q2\n" + /* c = a0 * a0 */ + "movq %%r10,%%rax\n" + "mulq %%r10\n" + "movq %%rax,%%r8\n" + "movq %%rdx,%%r9\n" + /* d += a1 * a4 */ + "movq %%r11,%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d += (a2*2) * a3 */ + "leaq (%%r12,%%r12,1),%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* u0 = d & M (%%rsi) */ + "movq %%rbx,%%rsi\n" + "andq %%r15,%%rsi\n" + /* d >>= 52 */ + "shrdq $52,%%rcx,%%rbx\n" + "xorq %%rcx,%%rcx\n" + /* u0 = (u0 << 4) | tx (%%rsi) */ + "shlq $4,%%rsi\n" + "movq %q3,%%rax\n" + "orq %%rax,%%rsi\n" + /* c += u0 * (R >> 4) */ + "movq $0x1000003d1,%%rax\n" + "mulq %%rsi\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* r[0] = c & M */ + "movq %%r8,%%rax\n" + "andq %%r15,%%rax\n" + "movq %%rax,0(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* a0 *= 2 */ + "addq %%r10,%%r10\n" + /* c += a0 * a1 */ + "movq %%r10,%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d += a2 * a4 */ + "movq %%r12,%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* d += a3 * a3 */ + "movq %%r13,%%rax\n" + "mulq %%r13\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* c += (d & M) * R */ + "movq %%rbx,%%rax\n" + "andq %%r15,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d >>= 52 */ + "shrdq $52,%%rcx,%%rbx\n" + "xorq %%rcx,%%rcx\n" + /* r[1] = c & M */ + "movq %%r8,%%rax\n" + "andq %%r15,%%rax\n" + "movq %%rax,8(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += a0 * a2 (last use of %%r10) */ + "movq %%r10,%%rax\n" + "mulq %%r12\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* fetch t3 (%%r10, overwrites a0),t4 (%%rsi) */ + "movq %q2,%%rsi\n" + "movq %q1,%%r10\n" + /* c += a1 * a1 */ + "movq %%r11,%%rax\n" + "mulq %%r11\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d += a3 * a4 */ + "movq %%r13,%%rax\n" + "mulq %%r14\n" + "addq %%rax,%%rbx\n" + "adcq %%rdx,%%rcx\n" + /* c += (d & M) * R */ + "movq %%rbx,%%rax\n" + "andq %%r15,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* d >>= 52 (%%rbx only) */ + "shrdq $52,%%rcx,%%rbx\n" + /* r[2] = c & M */ + "movq %%r8,%%rax\n" + "andq %%r15,%%rax\n" + "movq %%rax,16(%%rdi)\n" + /* c >>= 52 */ + "shrdq $52,%%r9,%%r8\n" + "xorq %%r9,%%r9\n" + /* c += t3 */ + "addq %%r10,%%r8\n" + /* c += d * R */ + "movq %%rbx,%%rax\n" + "movq $0x1000003d10,%%rdx\n" + "mulq %%rdx\n" + "addq %%rax,%%r8\n" + "adcq %%rdx,%%r9\n" + /* r[3] = c & M */ + "movq %%r8,%%rax\n" + "andq %%r15,%%rax\n" + "movq %%rax,24(%%rdi)\n" + /* c >>= 52 (%%r8 only) */ + "shrdq $52,%%r9,%%r8\n" + /* c += t4 (%%r8 only) */ + "addq %%rsi,%%r8\n" + /* r[4] = c */ + "movq %%r8,32(%%rdi)\n" +: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3) +: "D"(r) +: "%rax", "%rbx", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory" +); +} + +#endif diff --git a/src/secp256k1/src/field_5x52_impl.h b/src/secp256k1/src/field_5x52_impl.h new file mode 100644 index 0000000000..63176d6de4 --- /dev/null +++ b/src/secp256k1/src/field_5x52_impl.h @@ -0,0 +1,338 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_FIELD_REPR_IMPL_H_ +#define _SECP256K1_FIELD_REPR_IMPL_H_ + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include <string.h> +#include "util.h" +#include "num.h" +#include "field.h" + +#if defined(USE_FIELD_5X52_ASM) +#include "field_5x52_asm_impl.h" +#elif defined(USE_FIELD_5X52_INT128) +#include "field_5x52_int128_impl.h" +#else +#error "Please select field_5x52 implementation" +#endif + +/** Implements arithmetic modulo FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F, + * represented as 5 uint64_t's in base 2^52. The values are allowed to contain >52 each. In particular, + * each FieldElem has a 'magnitude' associated with it. Internally, a magnitude M means each element + * is at most M*(2^53-1), except the most significant one, which is limited to M*(2^49-1). All operations + * accept any input with magnitude at most M, and have different rules for propagating magnitude to their + * output. + */ + +static void secp256k1_fe_inner_start(void) {} +static void secp256k1_fe_inner_stop(void) {} + +#ifdef VERIFY +static void secp256k1_fe_verify(const secp256k1_fe_t *a) { + const uint64_t *d = a->n; + int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; + r &= (d[0] <= 0xFFFFFFFFFFFFFULL * m); + r &= (d[1] <= 0xFFFFFFFFFFFFFULL * m); + r &= (d[2] <= 0xFFFFFFFFFFFFFULL * m); + r &= (d[3] <= 0xFFFFFFFFFFFFFULL * m); + r &= (d[4] <= 0x0FFFFFFFFFFFFULL * m); + r &= (a->magnitude >= 0); + if (a->normalized) { + r &= (a->magnitude <= 1); + if (r && (d[4] == 0x0FFFFFFFFFFFFULL) && ((d[3] & d[2] & d[1]) == 0xFFFFFFFFFFFFFULL)) { + r &= (d[0] < 0xFFFFEFFFFFC2FULL); + } + } + VERIFY_CHECK(r == 1); +} +#else +static void secp256k1_fe_verify(const secp256k1_fe_t *a) { + (void)a; +} +#endif + +static void secp256k1_fe_normalize(secp256k1_fe_t *r) { + uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; + + /* Reduce t4 at the start so there will be at most a single carry from the first pass */ + uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; + uint64_t m; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3; + + /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t4 >> 49 == 0); + + /* At most a single final reduction is needed; check if the value is >= the field characteristic */ + x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL) + & (t0 >= 0xFFFFEFFFFFC2FULL)); + + /* Apply the final reduction (for constant-time behaviour, we do it always) */ + t0 += x * 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; + + /* If t4 didn't carry to bit 48 already, then it should have after any final reduction */ + VERIFY_CHECK(t4 >> 48 == x); + + /* Mask off the possible multiple of 2^256 from the final reduction */ + t4 &= 0x0FFFFFFFFFFFFULL; + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { + uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; + + /* Reduce t4 at the start so there will be at most a single carry from the first pass */ + uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL; + uint64_t m; + + /* The first pass ensures the magnitude is 1, ... */ + t0 += x * 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3; + + /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */ + VERIFY_CHECK(t4 >> 49 == 0); + + /* At most a single final reduction is needed; check if the value is >= the field characteristic */ + x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL) + & (t0 >= 0xFFFFEFFFFFC2FULL)); + + if (x) { + t0 += 0x1000003D1ULL; + t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; + t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; + t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; + t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; + + /* If t4 didn't carry to bit 48 already, then it should have after any final reduction */ + VERIFY_CHECK(t4 >> 48 == x); + + /* Mask off the possible multiple of 2^256 from the final reduction */ + t4 &= 0x0FFFFFFFFFFFFULL; + } + + r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4; + +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { + r->n[0] = a; + r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + secp256k1_fe_verify(a); +#endif + const uint64_t *t = a->n; + return (t[0] | t[1] | t[2] | t[3] | t[4]) == 0; +} + +SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + secp256k1_fe_verify(a); +#endif + return a->n[0] & 1; +} + +SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { +#ifdef VERIFY + a->magnitude = 0; + a->normalized = 1; +#endif + for (int i=0; i<5; i++) { + a->n[i] = 0; + } +} + +SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + VERIFY_CHECK(b->normalized); + secp256k1_fe_verify(a); + secp256k1_fe_verify(b); +#endif + const uint64_t *t = a->n, *u = b->n; + return ((t[0]^u[0]) | (t[1]^u[1]) | (t[2]^u[2]) | (t[3]^u[3]) | (t[4]^u[4])) == 0; +} + +static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + VERIFY_CHECK(b->normalized); + secp256k1_fe_verify(a); + secp256k1_fe_verify(b); +#endif + for (int i = 4; i >= 0; i--) { + if (a->n[i] > b->n[i]) return 1; + if (a->n[i] < b->n[i]) return -1; + } + return 0; +} + +static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { + r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; + for (int i=0; i<32; i++) { + for (int j=0; j<2; j++) { + int limb = (8*i+4*j)/52; + int shift = (8*i+4*j)%52; + r->n[limb] |= (uint64_t)((a[31-i] >> (4*j)) & 0xF) << shift; + } + } + if (r->n[4] == 0x0FFFFFFFFFFFFULL && (r->n[3] & r->n[2] & r->n[1]) == 0xFFFFFFFFFFFFFULL && r->n[0] >= 0xFFFFEFFFFFC2FULL) { + return 0; + } +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 1; + secp256k1_fe_verify(r); +#endif + return 1; +} + +/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ +static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { +#ifdef VERIFY + VERIFY_CHECK(a->normalized); + secp256k1_fe_verify(a); +#endif + for (int i=0; i<32; i++) { + int c = 0; + for (int j=0; j<2; j++) { + int limb = (8*i+4*j)/52; + int shift = (8*i+4*j)%52; + c |= ((a->n[limb] >> shift) & 0xF) << (4 * j); + } + r[31-i] = c; + } +} + +SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) { +#ifdef VERIFY + VERIFY_CHECK(a->magnitude <= m); + secp256k1_fe_verify(a); +#endif + r->n[0] = 0xFFFFEFFFFFC2FULL * 2 * (m + 1) - a->n[0]; + r->n[1] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[1]; + r->n[2] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[2]; + r->n[3] = 0xFFFFFFFFFFFFFULL * 2 * (m + 1) - a->n[3]; + r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * (m + 1) - a->n[4]; +#ifdef VERIFY + r->magnitude = m + 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) { + r->n[0] *= a; + r->n[1] *= a; + r->n[2] *= a; + r->n[3] *= a; + r->n[4] *= a; +#ifdef VERIFY + r->magnitude *= a; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +#ifdef VERIFY + secp256k1_fe_verify(a); +#endif + r->n[0] += a->n[0]; + r->n[1] += a->n[1]; + r->n[2] += a->n[2]; + r->n[3] += a->n[3]; + r->n[4] += a->n[4]; +#ifdef VERIFY + r->magnitude += a->magnitude; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) { +#ifdef VERIFY + VERIFY_CHECK(a->magnitude <= 8); + VERIFY_CHECK(b->magnitude <= 8); + secp256k1_fe_verify(a); + secp256k1_fe_verify(b); + VERIFY_CHECK(r != b); +#endif + secp256k1_fe_mul_inner(r->n, a->n, b->n); +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +#ifdef VERIFY + VERIFY_CHECK(a->magnitude <= 8); + secp256k1_fe_verify(a); +#endif + secp256k1_fe_sqr_inner(r->n, a->n); +#ifdef VERIFY + r->magnitude = 1; + r->normalized = 0; + secp256k1_fe_verify(r); +#endif +} + +static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) { + uint64_t 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 + if (flag) { + r->magnitude = a->magnitude; + r->normalized = a->normalized; + } +#endif +} + +#endif diff --git a/src/secp256k1/src/field_5x52_int128_impl.h b/src/secp256k1/src/field_5x52_int128_impl.h new file mode 100644 index 0000000000..ec631833cf --- /dev/null +++ b/src/secp256k1/src/field_5x52_int128_impl.h @@ -0,0 +1,277 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_FIELD_INNER5X52_IMPL_H_ +#define _SECP256K1_FIELD_INNER5X52_IMPL_H_ + +#include <stdint.h> + +#ifdef VERIFY +#define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) +#else +#define VERIFY_BITS(x, n) do { } while(0) +#endif + +SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) { + VERIFY_BITS(a[0], 56); + VERIFY_BITS(a[1], 56); + VERIFY_BITS(a[2], 56); + VERIFY_BITS(a[3], 56); + VERIFY_BITS(a[4], 52); + VERIFY_BITS(b[0], 56); + VERIFY_BITS(b[1], 56); + VERIFY_BITS(b[2], 56); + VERIFY_BITS(b[3], 56); + VERIFY_BITS(b[4], 52); + VERIFY_CHECK(r != b); + + const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; + /* [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n. + * px is a shorthand for sum(a[i]*b[x-i], i=0..x). + * Note that [x 0 0 0 0 0] = [x*R]. + */ + + uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; + + __int128 c, d; + + d = (__int128)a0 * b[3] + + (__int128)a1 * b[2] + + (__int128)a2 * b[1] + + (__int128)a3 * b[0]; + VERIFY_BITS(d, 114); + /* [d 0 0 0] = [p3 0 0 0] */ + c = (__int128)a4 * b[4]; + VERIFY_BITS(c, 112); + /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + d += (c & M) * R; c >>= 52; + VERIFY_BITS(d, 115); + VERIFY_BITS(c, 60); + /* [c 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + uint64_t t3 = d & M; d >>= 52; + VERIFY_BITS(t3, 52); + VERIFY_BITS(d, 63); + /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + + d += (__int128)a0 * b[4] + + (__int128)a1 * b[3] + + (__int128)a2 * b[2] + + (__int128)a3 * b[1] + + (__int128)a4 * b[0]; + VERIFY_BITS(d, 115); + /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + d += c * R; + VERIFY_BITS(d, 116); + /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + uint64_t t4 = d & M; d >>= 52; + VERIFY_BITS(t4, 52); + VERIFY_BITS(d, 64); + /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + uint64_t tx = (t4 >> 48); t4 &= (M >> 4); + VERIFY_BITS(tx, 4); + VERIFY_BITS(t4, 48); + /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + + c = (__int128)a0 * b[0]; + VERIFY_BITS(c, 112); + /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */ + d += (__int128)a1 * b[4] + + (__int128)a2 * b[3] + + (__int128)a3 * b[2] + + (__int128)a4 * b[1]; + VERIFY_BITS(d, 115); + /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + uint64_t u0 = d & M; d >>= 52; + VERIFY_BITS(u0, 52); + VERIFY_BITS(d, 63); + /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + /* [d 0 t4+(tx<<48)+(u0<<52) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + u0 = (u0 << 4) | tx; + VERIFY_BITS(u0, 56); + /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + c += (__int128)u0 * (R >> 4); + VERIFY_BITS(c, 115); + /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + r[0] = c & M; c >>= 52; + VERIFY_BITS(r[0], 52); + VERIFY_BITS(c, 61); + /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */ + + c += (__int128)a0 * b[1] + + (__int128)a1 * b[0]; + VERIFY_BITS(c, 114); + /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */ + d += (__int128)a2 * b[4] + + (__int128)a3 * b[3] + + (__int128)a4 * b[2]; + VERIFY_BITS(d, 114); + /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ + c += (d & M) * R; d >>= 52; + VERIFY_BITS(c, 115); + VERIFY_BITS(d, 62); + /* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ + r[1] = c & M; c >>= 52; + VERIFY_BITS(r[1], 52); + VERIFY_BITS(c, 63); + /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ + + c += (__int128)a0 * b[2] + + (__int128)a1 * b[1] + + (__int128)a2 * b[0]; + VERIFY_BITS(c, 114); + /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */ + d += (__int128)a3 * b[4] + + (__int128)a4 * b[3]; + VERIFY_BITS(d, 114); + /* [d 0 0 t4 t3 c t1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += (d & M) * R; d >>= 52; + VERIFY_BITS(c, 115); + VERIFY_BITS(d, 62); + /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[2] = c & M; c >>= 52; + VERIFY_BITS(r[2], 52); + VERIFY_BITS(c, 63); + /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += d * R + t3;; + VERIFY_BITS(c, 100); + /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[3] = c & M; c >>= 52; + VERIFY_BITS(r[3], 52); + VERIFY_BITS(c, 48); + /* [t4+c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += t4; + VERIFY_BITS(c, 49); + /* [c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[4] = c; + VERIFY_BITS(r[4], 49); + /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ +} + +SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) { + VERIFY_BITS(a[0], 56); + VERIFY_BITS(a[1], 56); + VERIFY_BITS(a[2], 56); + VERIFY_BITS(a[3], 56); + VERIFY_BITS(a[4], 52); + + const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL; + /** [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n. + * px is a shorthand for sum(a[i]*a[x-i], i=0..x). + * Note that [x 0 0 0 0 0] = [x*R]. + */ + + __int128 c, d; + + uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4]; + + d = (__int128)(a0*2) * a3 + + (__int128)(a1*2) * a2; + VERIFY_BITS(d, 114); + /* [d 0 0 0] = [p3 0 0 0] */ + c = (__int128)a4 * a4; + VERIFY_BITS(c, 112); + /* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + d += (c & M) * R; c >>= 52; + VERIFY_BITS(d, 115); + VERIFY_BITS(c, 60); + /* [c 0 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + uint64_t t3 = d & M; d >>= 52; + VERIFY_BITS(t3, 52); + VERIFY_BITS(d, 63); + /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */ + + a4 *= 2; + d += (__int128)a0 * a4 + + (__int128)(a1*2) * a3 + + (__int128)a2 * a2; + VERIFY_BITS(d, 115); + /* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + d += c * R; + VERIFY_BITS(d, 116); + /* [d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + uint64_t t4 = d & M; d >>= 52; + VERIFY_BITS(t4, 52); + VERIFY_BITS(d, 64); + /* [d t4 t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + uint64_t tx = (t4 >> 48); t4 &= (M >> 4); + VERIFY_BITS(tx, 4); + VERIFY_BITS(t4, 48); + /* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */ + + c = (__int128)a0 * a0; + VERIFY_BITS(c, 112); + /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */ + d += (__int128)a1 * a4 + + (__int128)(a2*2) * a3; + VERIFY_BITS(d, 114); + /* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + uint64_t u0 = d & M; d >>= 52; + VERIFY_BITS(u0, 52); + VERIFY_BITS(d, 62); + /* [d u0 t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + /* [d 0 t4+(tx<<48)+(u0<<52) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + u0 = (u0 << 4) | tx; + VERIFY_BITS(u0, 56); + /* [d 0 t4+(u0<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + c += (__int128)u0 * (R >> 4); + VERIFY_BITS(c, 113); + /* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */ + r[0] = c & M; c >>= 52; + VERIFY_BITS(r[0], 52); + VERIFY_BITS(c, 61); + /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */ + + a0 *= 2; + c += (__int128)a0 * a1; + VERIFY_BITS(c, 114); + /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */ + d += (__int128)a2 * a4 + + (__int128)a3 * a3; + VERIFY_BITS(d, 114); + /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ + c += (d & M) * R; d >>= 52; + VERIFY_BITS(c, 115); + VERIFY_BITS(d, 62); + /* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ + r[1] = c & M; c >>= 52; + VERIFY_BITS(r[1], 52); + VERIFY_BITS(c, 63); + /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */ + + c += (__int128)a0 * a2 + + (__int128)a1 * a1; + VERIFY_BITS(c, 114); + /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */ + d += (__int128)a3 * a4; + VERIFY_BITS(d, 114); + /* [d 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += (d & M) * R; d >>= 52; + VERIFY_BITS(c, 115); + VERIFY_BITS(d, 62); + /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[2] = c & M; c >>= 52; + VERIFY_BITS(r[2], 52); + VERIFY_BITS(c, 63); + /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + + c += d * R + t3;; + VERIFY_BITS(c, 100); + /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[3] = c & M; c >>= 52; + VERIFY_BITS(r[3], 52); + VERIFY_BITS(c, 48); + /* [t4+c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + c += t4; + VERIFY_BITS(c, 49); + /* [c r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ + r[4] = c; + VERIFY_BITS(r[4], 49); + /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ +} + +#endif diff --git a/src/secp256k1/src/field_gmp.h b/src/secp256k1/src/field_gmp.h new file mode 100644 index 0000000000..b390fd9de8 --- /dev/null +++ b/src/secp256k1/src/field_gmp.h @@ -0,0 +1,18 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_FIELD_REPR_ +#define _SECP256K1_FIELD_REPR_ + +#include <gmp.h> + +#define FIELD_LIMBS ((256 + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS) + +typedef struct { + mp_limb_t n[FIELD_LIMBS+1]; +} secp256k1_fe_t; + +#endif diff --git a/src/secp256k1/src/field_gmp_impl.h b/src/secp256k1/src/field_gmp_impl.h new file mode 100644 index 0000000000..73a55c4f00 --- /dev/null +++ b/src/secp256k1/src/field_gmp_impl.h @@ -0,0 +1,184 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_FIELD_REPR_IMPL_H_ +#define _SECP256K1_FIELD_REPR_IMPL_H_ + +#include <stdio.h> +#include <string.h> +#include "num.h" +#include "field.h" + +static mp_limb_t secp256k1_field_p[FIELD_LIMBS]; +static mp_limb_t secp256k1_field_pc[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS]; + +static void secp256k1_fe_inner_start(void) { + for (int i=0; i<(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; i++) + secp256k1_field_pc[i] = 0; + secp256k1_field_pc[0] += 0x3D1UL; + secp256k1_field_pc[32/GMP_NUMB_BITS] += (((mp_limb_t)1) << (32 % GMP_NUMB_BITS)); + for (int i=0; i<FIELD_LIMBS; i++) { + secp256k1_field_p[i] = 0; + } + mpn_sub(secp256k1_field_p, secp256k1_field_p, FIELD_LIMBS, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS); +} + +static void secp256k1_fe_inner_stop(void) { +} + +static void secp256k1_fe_normalize(secp256k1_fe_t *r) { + if (r->n[FIELD_LIMBS] != 0) { +#if (GMP_NUMB_BITS >= 40) + mp_limb_t carry = mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x1000003D1ULL * r->n[FIELD_LIMBS]); + mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x1000003D1ULL * carry); +#else + mp_limb_t carry = mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x3D1UL * r->n[FIELD_LIMBS]) + + mpn_add_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), r->n[FIELD_LIMBS] << (32 % GMP_NUMB_BITS)); + mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x3D1UL * carry); + mpn_add_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), carry << (32%GMP_NUMB_BITS)); +#endif + r->n[FIELD_LIMBS] = 0; + } + if (mpn_cmp(r->n, secp256k1_field_p, FIELD_LIMBS) >= 0) + mpn_sub(r->n, r->n, FIELD_LIMBS, secp256k1_field_p, FIELD_LIMBS); +} + +static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { + secp256k1_fe_normalize(r); +} + +SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { + r->n[0] = a; + for (int i=1; i<FIELD_LIMBS+1; i++) + r->n[i] = 0; +} + +SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *r) { + for (int i=0; i<FIELD_LIMBS+1; i++) + r->n[i] = 0; +} + +SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { + int ret = 1; + for (int i=0; i<FIELD_LIMBS+1; i++) + ret &= (a->n[i] == 0); + return ret; +} + +SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) { + return a->n[0] & 1; +} + +SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { + int ret = 1; + for (int i=0; i<FIELD_LIMBS+1; i++) + ret &= (a->n[i] == b->n[i]); + return ret; +} + +SECP256K1_INLINE static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { + for (int i=FIELD_LIMBS; i>=0; i--) { + if (a->n[i] > b->n[i]) return 1; + if (a->n[i] < b->n[i]) return -1; + } + return 0; +} + +static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { + for (int i=0; i<FIELD_LIMBS+1; i++) + r->n[i] = 0; + for (int i=0; i<256; i++) { + int limb = i/GMP_NUMB_BITS; + int shift = i%GMP_NUMB_BITS; + r->n[limb] |= (mp_limb_t)((a[31-i/8] >> (i%8)) & 0x1) << shift; + } + return (mpn_cmp(r->n, secp256k1_field_p, FIELD_LIMBS) < 0); +} + +/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ +static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { + for (int i=0; i<32; i++) { + int c = 0; + for (int j=0; j<8; j++) { + int limb = (8*i+j)/GMP_NUMB_BITS; + int shift = (8*i+j)%GMP_NUMB_BITS; + c |= ((a->n[limb] >> shift) & 0x1) << j; + } + r[31-i] = c; + } +} + +SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) { + (void)m; + *r = *a; + secp256k1_fe_normalize(r); + for (int i=0; i<FIELD_LIMBS; i++) + r->n[i] = ~(r->n[i]); +#if (GMP_NUMB_BITS >= 33) + mpn_sub_1(r->n, r->n, FIELD_LIMBS, 0x1000003D0ULL); +#else + mpn_sub_1(r->n, r->n, FIELD_LIMBS, 0x3D0UL); + mpn_sub_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), 0x1UL << (32%GMP_NUMB_BITS)); +#endif +} + +SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) { + mpn_mul_1(r->n, r->n, FIELD_LIMBS+1, a); +} + +SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) { + mpn_add(r->n, r->n, FIELD_LIMBS+1, a->n, FIELD_LIMBS+1); +} + +static void secp256k1_fe_reduce(secp256k1_fe_t *r, mp_limb_t *tmp) { + /** <A1 A2 A3 A4> <B1 B2 B3 B4> + * B1 B2 B3 B4 + * + C * A1 A2 A3 A4 + * + A1 A2 A3 A4 + */ + +#if (GMP_NUMB_BITS >= 33) + mp_limb_t o = mpn_addmul_1(tmp, tmp+FIELD_LIMBS, FIELD_LIMBS, 0x1000003D1ULL); +#else + mp_limb_t o = mpn_addmul_1(tmp, tmp+FIELD_LIMBS, FIELD_LIMBS, 0x3D1UL) + + mpn_addmul_1(tmp+(32/GMP_NUMB_BITS), tmp+FIELD_LIMBS, FIELD_LIMBS-(32/GMP_NUMB_BITS), 0x1UL << (32%GMP_NUMB_BITS)); +#endif + mp_limb_t q[1+(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS]; + q[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS] = mpn_mul_1(q, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS, o); +#if (GMP_NUMB_BITS <= 32) + mp_limb_t o2 = tmp[2*FIELD_LIMBS-(32/GMP_NUMB_BITS)] << (32%GMP_NUMB_BITS); + q[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS] += mpn_addmul_1(q, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS, o2); +#endif + r->n[FIELD_LIMBS] = mpn_add(r->n, tmp, FIELD_LIMBS, q, 1+(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS); +} + +static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) { + VERIFY_CHECK(r != b); + secp256k1_fe_t ac = *a; + secp256k1_fe_t bc = *b; + secp256k1_fe_normalize(&ac); + secp256k1_fe_normalize(&bc); + mp_limb_t tmp[2*FIELD_LIMBS]; + mpn_mul_n(tmp, ac.n, bc.n, FIELD_LIMBS); + secp256k1_fe_reduce(r, tmp); +} + +static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { + secp256k1_fe_t ac = *a; + secp256k1_fe_normalize(&ac); + mp_limb_t tmp[2*FIELD_LIMBS]; + mpn_sqr(tmp, ac.n, FIELD_LIMBS); + secp256k1_fe_reduce(r, tmp); +} + +static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) { + mp_limb_t mask0 = flag + ~((mp_limb_t)0), mask1 = ~mask0; + for (int i = 0; i <= FIELD_LIMBS; i++) { + r->n[i] = (r->n[i] & mask0) | (a->n[i] & mask1); + } +} + +#endif diff --git a/src/secp256k1/src/field_impl.h b/src/secp256k1/src/field_impl.h new file mode 100644 index 0000000000..24d3104ed1 --- /dev/null +++ b/src/secp256k1/src/field_impl.h @@ -0,0 +1,273 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_FIELD_IMPL_H_ +#define _SECP256K1_FIELD_IMPL_H_ + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include "util.h" + +#if defined(USE_FIELD_GMP) +#include "field_gmp_impl.h" +#elif defined(USE_FIELD_10X26) +#include "field_10x26_impl.h" +#elif defined(USE_FIELD_5X52) +#include "field_5x52_impl.h" +#else +#error "Please select field implementation" +#endif + +static void secp256k1_fe_get_hex(char *r, int *rlen, const secp256k1_fe_t *a) { + if (*rlen < 65) { + *rlen = 65; + return; + } + *rlen = 65; + unsigned char tmp[32]; + secp256k1_fe_t b = *a; + secp256k1_fe_normalize(&b); + secp256k1_fe_get_b32(tmp, &b); + for (int i=0; i<32; i++) { + static const char *c = "0123456789ABCDEF"; + r[2*i] = c[(tmp[i] >> 4) & 0xF]; + r[2*i+1] = c[(tmp[i]) & 0xF]; + } + r[64] = 0x00; +} + +static int secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen) { + unsigned char tmp[32] = {}; + static const int cvt[256] = {0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, + 0, 1, 2, 3, 4, 5, 6,7,8,9,0,0,0,0,0,0, + 0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, + 0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}; + for (int i=0; i<32; i++) { + if (alen > i*2) + tmp[32 - alen/2 + i] = (cvt[(unsigned char)a[2*i]] << 4) + cvt[(unsigned char)a[2*i+1]]; + } + return secp256k1_fe_set_b32(r, tmp); +} + +static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { + + /** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in + * { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: + * 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] + */ + + secp256k1_fe_t x2; + secp256k1_fe_sqr(&x2, a); + secp256k1_fe_mul(&x2, &x2, a); + + secp256k1_fe_t x3; + secp256k1_fe_sqr(&x3, &x2); + secp256k1_fe_mul(&x3, &x3, a); + + secp256k1_fe_t x6 = x3; + for (int j=0; j<3; j++) secp256k1_fe_sqr(&x6, &x6); + secp256k1_fe_mul(&x6, &x6, &x3); + + secp256k1_fe_t x9 = x6; + for (int j=0; j<3; j++) secp256k1_fe_sqr(&x9, &x9); + secp256k1_fe_mul(&x9, &x9, &x3); + + secp256k1_fe_t x11 = x9; + for (int j=0; j<2; j++) secp256k1_fe_sqr(&x11, &x11); + secp256k1_fe_mul(&x11, &x11, &x2); + + secp256k1_fe_t x22 = x11; + for (int j=0; j<11; j++) secp256k1_fe_sqr(&x22, &x22); + secp256k1_fe_mul(&x22, &x22, &x11); + + secp256k1_fe_t x44 = x22; + for (int j=0; j<22; j++) secp256k1_fe_sqr(&x44, &x44); + secp256k1_fe_mul(&x44, &x44, &x22); + + secp256k1_fe_t x88 = x44; + for (int j=0; j<44; j++) secp256k1_fe_sqr(&x88, &x88); + secp256k1_fe_mul(&x88, &x88, &x44); + + secp256k1_fe_t x176 = x88; + for (int j=0; j<88; j++) secp256k1_fe_sqr(&x176, &x176); + secp256k1_fe_mul(&x176, &x176, &x88); + + secp256k1_fe_t x220 = x176; + for (int j=0; j<44; j++) secp256k1_fe_sqr(&x220, &x220); + secp256k1_fe_mul(&x220, &x220, &x44); + + secp256k1_fe_t x223 = x220; + for (int 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. */ + + secp256k1_fe_t t1 = x223; + for (int j=0; j<23; j++) secp256k1_fe_sqr(&t1, &t1); + secp256k1_fe_mul(&t1, &t1, &x22); + for (int 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); + + /* Check that a square root was actually calculated */ + + secp256k1_fe_sqr(&t1, r); + secp256k1_fe_negate(&t1, &t1, 1); + secp256k1_fe_add(&t1, a); + secp256k1_fe_normalize_var(&t1); + return secp256k1_fe_is_zero(&t1); +} + +static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a) { + + /** The binary representation of (p - 2) has 5 blocks of 1s, with lengths in + * { 1, 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block: + * [1], [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223] + */ + + secp256k1_fe_t x2; + secp256k1_fe_sqr(&x2, a); + secp256k1_fe_mul(&x2, &x2, a); + + secp256k1_fe_t x3; + secp256k1_fe_sqr(&x3, &x2); + secp256k1_fe_mul(&x3, &x3, a); + + secp256k1_fe_t x6 = x3; + for (int j=0; j<3; j++) secp256k1_fe_sqr(&x6, &x6); + secp256k1_fe_mul(&x6, &x6, &x3); + + secp256k1_fe_t x9 = x6; + for (int j=0; j<3; j++) secp256k1_fe_sqr(&x9, &x9); + secp256k1_fe_mul(&x9, &x9, &x3); + + secp256k1_fe_t x11 = x9; + for (int j=0; j<2; j++) secp256k1_fe_sqr(&x11, &x11); + secp256k1_fe_mul(&x11, &x11, &x2); + + secp256k1_fe_t x22 = x11; + for (int j=0; j<11; j++) secp256k1_fe_sqr(&x22, &x22); + secp256k1_fe_mul(&x22, &x22, &x11); + + secp256k1_fe_t x44 = x22; + for (int j=0; j<22; j++) secp256k1_fe_sqr(&x44, &x44); + secp256k1_fe_mul(&x44, &x44, &x22); + + secp256k1_fe_t x88 = x44; + for (int j=0; j<44; j++) secp256k1_fe_sqr(&x88, &x88); + secp256k1_fe_mul(&x88, &x88, &x44); + + secp256k1_fe_t x176 = x88; + for (int j=0; j<88; j++) secp256k1_fe_sqr(&x176, &x176); + secp256k1_fe_mul(&x176, &x176, &x88); + + secp256k1_fe_t x220 = x176; + for (int j=0; j<44; j++) secp256k1_fe_sqr(&x220, &x220); + secp256k1_fe_mul(&x220, &x220, &x44); + + secp256k1_fe_t x223 = x220; + for (int 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. */ + + secp256k1_fe_t t1 = x223; + for (int j=0; j<23; j++) secp256k1_fe_sqr(&t1, &t1); + secp256k1_fe_mul(&t1, &t1, &x22); + for (int j=0; j<5; j++) secp256k1_fe_sqr(&t1, &t1); + secp256k1_fe_mul(&t1, &t1, a); + for (int j=0; j<3; j++) secp256k1_fe_sqr(&t1, &t1); + secp256k1_fe_mul(&t1, &t1, &x2); + for (int j=0; j<2; j++) secp256k1_fe_sqr(&t1, &t1); + secp256k1_fe_mul(r, a, &t1); +} + +static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +#if defined(USE_FIELD_INV_BUILTIN) + secp256k1_fe_inv(r, a); +#elif defined(USE_FIELD_INV_NUM) + unsigned char b[32]; + secp256k1_fe_t c = *a; + secp256k1_fe_normalize_var(&c); + secp256k1_fe_get_b32(b, &c); + secp256k1_num_t n; + secp256k1_num_set_bin(&n, b, 32); + secp256k1_num_mod_inverse(&n, &n, &secp256k1_fe_consts->p); + secp256k1_num_get_bin(b, 32, &n); + VERIFY_CHECK(secp256k1_fe_set_b32(r, b)); +#else +#error "Please select field inverse implementation" +#endif +} + +static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t r[len], const secp256k1_fe_t a[len]) { + if (len < 1) + return; + + VERIFY_CHECK((r + len <= a) || (a + len <= r)); + + r[0] = a[0]; + + size_t i = 0; + while (++i < len) { + secp256k1_fe_mul(&r[i], &r[i - 1], &a[i]); + } + + secp256k1_fe_t u; secp256k1_fe_inv_var(&u, &r[--i]); + + while (i > 0) { + int j = i--; + secp256k1_fe_mul(&r[j], &r[i], &u); + secp256k1_fe_mul(&u, &u, &a[j]); + } + + r[0] = u; +} + +static void secp256k1_fe_start(void) { +#ifndef USE_NUM_NONE + static const unsigned char secp256k1_fe_consts_p[] = { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F + }; +#endif + if (secp256k1_fe_consts == NULL) { + secp256k1_fe_inner_start(); + secp256k1_fe_consts_t *ret = (secp256k1_fe_consts_t*)checked_malloc(sizeof(secp256k1_fe_consts_t)); +#ifndef USE_NUM_NONE + secp256k1_num_set_bin(&ret->p, secp256k1_fe_consts_p, sizeof(secp256k1_fe_consts_p)); +#endif + secp256k1_fe_consts = ret; + } +} + +static void secp256k1_fe_stop(void) { + if (secp256k1_fe_consts != NULL) { + secp256k1_fe_consts_t *c = (secp256k1_fe_consts_t*)secp256k1_fe_consts; + free((void*)c); + secp256k1_fe_consts = NULL; + secp256k1_fe_inner_stop(); + } +} + +#endif diff --git a/src/secp256k1/src/group.h b/src/secp256k1/src/group.h new file mode 100644 index 0000000000..ecfebcdc0c --- /dev/null +++ b/src/secp256k1/src/group.h @@ -0,0 +1,121 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_GROUP_ +#define _SECP256K1_GROUP_ + +#include "num.h" +#include "field.h" + +/** A group element of the secp256k1 curve, in affine coordinates. */ +typedef struct { + secp256k1_fe_t x; + secp256k1_fe_t y; + int infinity; /* whether this represents the point at infinity */ +} secp256k1_ge_t; + +/** A group element of the secp256k1 curve, in jacobian coordinates. */ +typedef struct { + secp256k1_fe_t x; /* actual X: x/z^2 */ + secp256k1_fe_t y; /* actual Y: y/z^3 */ + secp256k1_fe_t z; + int infinity; /* whether this represents the point at infinity */ +} secp256k1_gej_t; + +/** Global constants related to the group */ +typedef struct { + secp256k1_ge_t g; /* the generator point */ + +#ifdef USE_ENDOMORPHISM + /* constants related to secp256k1's efficiently computable endomorphism */ + secp256k1_fe_t beta; +#endif +} secp256k1_ge_consts_t; + +static const secp256k1_ge_consts_t *secp256k1_ge_consts = NULL; + +/** Initialize the group module. */ +static void secp256k1_ge_start(void); + +/** De-initialize the group module. */ +static void secp256k1_ge_stop(void); + +/** Set a group element equal to the point at infinity */ +static void secp256k1_ge_set_infinity(secp256k1_ge_t *r); + +/** Set a group element equal to the point with given X and Y coordinates */ +static void secp256k1_ge_set_xy(secp256k1_ge_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y); + +/** Set a group element (affine) equal to the point with the given X coordinate, and given oddness + * for Y. Return value indicates whether the result is valid. */ +static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd); + +/** Check whether a group element is the point at infinity. */ +static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a); + +/** Check whether a group element is valid (i.e., on the curve). */ +static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a); + +static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a); +static void secp256k1_ge_neg_var(secp256k1_ge_t *r, const secp256k1_ge_t *a); + +/** Get a hex representation of a point. *rlen will be overwritten with the real length. */ +static void secp256k1_ge_get_hex(char *r, int *rlen, const secp256k1_ge_t *a); + +/** Set a group element equal to another which is given in jacobian coordinates */ +static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a); + +/** Set a batch of group elements equal to the inputs given in jacobian coordinates */ +static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t r[len], const secp256k1_gej_t a[len]); + + +/** Set a group element (jacobian) equal to the point at infinity. */ +static void secp256k1_gej_set_infinity(secp256k1_gej_t *r); + +/** Set a group element (jacobian) equal to the point with given X and Y coordinates. */ +static void secp256k1_gej_set_xy(secp256k1_gej_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y); + +/** Set a group element (jacobian) equal to another which is given in affine coordinates. */ +static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a); + +/** Get the X coordinate of a group element (jacobian). */ +static void secp256k1_gej_get_x_var(secp256k1_fe_t *r, const secp256k1_gej_t *a); + +/** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ +static void secp256k1_gej_neg_var(secp256k1_gej_t *r, const secp256k1_gej_t *a); + +/** Check whether a group element is the point at infinity. */ +static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a); + +/** Set r equal to the double of a. */ +static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a); + +/** Set r equal to the sum of a and b. */ +static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_t *b); + +/** Set r equal to the sum of a and b (with b given in affine coordinates, and not infinity). */ +static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b); + +/** Set r equal to the sum of a and b (with b given in affine coordinates). This is more efficient + than secp256k1_gej_add_var. It is identical to secp256k1_gej_add_ge but without constant-time + guarantee, and b is allowed to be infinity. */ +static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b); + +/** Get a hex representation of a point. *rlen will be overwritten with the real length. */ +static void secp256k1_gej_get_hex(char *r, int *rlen, const secp256k1_gej_t *a); + +#ifdef USE_ENDOMORPHISM +/** Set r to be equal to lambda times a, where lambda is chosen in a way such that this is very fast. */ +static void secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a); +#endif + +/** Clear a secp256k1_gej_t to prevent leaking sensitive information. */ +static void secp256k1_gej_clear(secp256k1_gej_t *r); + +/** Clear a secp256k1_ge_t to prevent leaking sensitive information. */ +static void secp256k1_ge_clear(secp256k1_ge_t *r); + +#endif diff --git a/src/secp256k1/src/group_impl.h b/src/secp256k1/src/group_impl.h new file mode 100644 index 0000000000..1ab5d5fe7b --- /dev/null +++ b/src/secp256k1/src/group_impl.h @@ -0,0 +1,462 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_GROUP_IMPL_H_ +#define _SECP256K1_GROUP_IMPL_H_ + +#include <string.h> + +#include "num.h" +#include "field.h" +#include "group.h" + +static void secp256k1_ge_set_infinity(secp256k1_ge_t *r) { + r->infinity = 1; +} + +static void secp256k1_ge_set_xy(secp256k1_ge_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y) { + r->infinity = 0; + r->x = *x; + r->y = *y; +} + +static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a) { + return a->infinity; +} + +static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a) { + *r = *a; + secp256k1_fe_normalize(&r->y); + secp256k1_fe_negate(&r->y, &r->y, 1); +} + +static void secp256k1_ge_neg_var(secp256k1_ge_t *r, const secp256k1_ge_t *a) { + *r = *a; + secp256k1_fe_normalize_var(&r->y); + secp256k1_fe_negate(&r->y, &r->y, 1); +} + +static void secp256k1_ge_get_hex(char *r, int *rlen, const secp256k1_ge_t *a) { + char cx[65]; int lx=65; + char cy[65]; int ly=65; + secp256k1_fe_get_hex(cx, &lx, &a->x); + secp256k1_fe_get_hex(cy, &ly, &a->y); + lx = strlen(cx); + ly = strlen(cy); + int len = lx + ly + 3 + 1; + if (*rlen < len) { + *rlen = len; + return; + } + *rlen = len; + r[0] = '('; + memcpy(r+1, cx, lx); + r[1+lx] = ','; + memcpy(r+2+lx, cy, ly); + r[2+lx+ly] = ')'; + r[3+lx+ly] = 0; +} + +static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a) { + r->infinity = a->infinity; + secp256k1_fe_inv(&a->z, &a->z); + secp256k1_fe_t z2; secp256k1_fe_sqr(&z2, &a->z); + secp256k1_fe_t z3; secp256k1_fe_mul(&z3, &a->z, &z2); + secp256k1_fe_mul(&a->x, &a->x, &z2); + secp256k1_fe_mul(&a->y, &a->y, &z3); + secp256k1_fe_set_int(&a->z, 1); + r->x = a->x; + r->y = a->y; +} + +static void secp256k1_ge_set_gej_var(secp256k1_ge_t *r, secp256k1_gej_t *a) { + r->infinity = a->infinity; + if (a->infinity) { + return; + } + secp256k1_fe_inv_var(&a->z, &a->z); + secp256k1_fe_t z2; secp256k1_fe_sqr(&z2, &a->z); + secp256k1_fe_t z3; secp256k1_fe_mul(&z3, &a->z, &z2); + secp256k1_fe_mul(&a->x, &a->x, &z2); + secp256k1_fe_mul(&a->y, &a->y, &z3); + secp256k1_fe_set_int(&a->z, 1); + r->x = a->x; + r->y = a->y; +} + +static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t r[len], const secp256k1_gej_t a[len]) { + size_t count = 0; + secp256k1_fe_t *az = checked_malloc(sizeof(secp256k1_fe_t) * len); + for (size_t i=0; i<len; i++) { + if (!a[i].infinity) { + az[count++] = a[i].z; + } + } + + secp256k1_fe_t *azi = checked_malloc(sizeof(secp256k1_fe_t) * count); + secp256k1_fe_inv_all_var(count, azi, az); + free(az); + + count = 0; + for (size_t i=0; i<len; i++) { + r[i].infinity = a[i].infinity; + if (!a[i].infinity) { + secp256k1_fe_t *zi = &azi[count++]; + secp256k1_fe_t zi2; secp256k1_fe_sqr(&zi2, zi); + secp256k1_fe_t zi3; secp256k1_fe_mul(&zi3, &zi2, zi); + secp256k1_fe_mul(&r[i].x, &a[i].x, &zi2); + secp256k1_fe_mul(&r[i].y, &a[i].y, &zi3); + } + } + free(azi); +} + +static void secp256k1_gej_set_infinity(secp256k1_gej_t *r) { + r->infinity = 1; + secp256k1_fe_set_int(&r->x, 0); + secp256k1_fe_set_int(&r->y, 0); + secp256k1_fe_set_int(&r->z, 0); +} + +static void secp256k1_gej_set_xy(secp256k1_gej_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y) { + r->infinity = 0; + r->x = *x; + r->y = *y; + secp256k1_fe_set_int(&r->z, 1); +} + +static void secp256k1_gej_clear(secp256k1_gej_t *r) { + r->infinity = 0; + secp256k1_fe_clear(&r->x); + secp256k1_fe_clear(&r->y); + secp256k1_fe_clear(&r->z); +} + +static void secp256k1_ge_clear(secp256k1_ge_t *r) { + r->infinity = 0; + secp256k1_fe_clear(&r->x); + secp256k1_fe_clear(&r->y); +} + +static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd) { + r->x = *x; + secp256k1_fe_t x2; secp256k1_fe_sqr(&x2, x); + secp256k1_fe_t x3; secp256k1_fe_mul(&x3, x, &x2); + r->infinity = 0; + secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7); + secp256k1_fe_add(&c, &x3); + if (!secp256k1_fe_sqrt_var(&r->y, &c)) + return 0; + secp256k1_fe_normalize_var(&r->y); + if (secp256k1_fe_is_odd(&r->y) != odd) + secp256k1_fe_negate(&r->y, &r->y, 1); + return 1; +} + +static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a) { + r->infinity = a->infinity; + r->x = a->x; + r->y = a->y; + secp256k1_fe_set_int(&r->z, 1); +} + +static void secp256k1_gej_get_x_var(secp256k1_fe_t *r, const secp256k1_gej_t *a) { + secp256k1_fe_t zi2; secp256k1_fe_inv_var(&zi2, &a->z); secp256k1_fe_sqr(&zi2, &zi2); + secp256k1_fe_mul(r, &a->x, &zi2); +} + +static void secp256k1_gej_neg_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) { + r->infinity = a->infinity; + r->x = a->x; + r->y = a->y; + r->z = a->z; + secp256k1_fe_normalize_var(&r->y); + secp256k1_fe_negate(&r->y, &r->y, 1); +} + +static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a) { + return a->infinity; +} + +static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) { + 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 + * Y^2 = X^3 + 7*Z^6 + */ + secp256k1_fe_t y2; secp256k1_fe_sqr(&y2, &a->y); + secp256k1_fe_t x3; secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); + secp256k1_fe_t z2; secp256k1_fe_sqr(&z2, &a->z); + secp256k1_fe_t z6; secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2); + secp256k1_fe_mul_int(&z6, 7); + secp256k1_fe_add(&x3, &z6); + secp256k1_fe_normalize_var(&y2); + secp256k1_fe_normalize_var(&x3); + return secp256k1_fe_equal(&y2, &x3); +} + +static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) { + if (a->infinity) + return 0; + /* y^2 = x^3 + 7 */ + secp256k1_fe_t y2; secp256k1_fe_sqr(&y2, &a->y); + secp256k1_fe_t x3; secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); + secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7); + secp256k1_fe_add(&x3, &c); + secp256k1_fe_normalize_var(&y2); + secp256k1_fe_normalize_var(&x3); + return secp256k1_fe_equal(&y2, &x3); +} + +static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) { + // For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity, + // Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have + // y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p. + r->infinity = a->infinity; + if (r->infinity) { + return; + } + + secp256k1_fe_t t1,t2,t3,t4; + secp256k1_fe_mul(&r->z, &a->z, &a->y); + secp256k1_fe_mul_int(&r->z, 2); /* Z' = 2*Y*Z (2) */ + secp256k1_fe_sqr(&t1, &a->x); + secp256k1_fe_mul_int(&t1, 3); /* T1 = 3*X^2 (3) */ + secp256k1_fe_sqr(&t2, &t1); /* T2 = 9*X^4 (1) */ + secp256k1_fe_sqr(&t3, &a->y); + secp256k1_fe_mul_int(&t3, 2); /* T3 = 2*Y^2 (2) */ + secp256k1_fe_sqr(&t4, &t3); + secp256k1_fe_mul_int(&t4, 2); /* T4 = 8*Y^4 (2) */ + secp256k1_fe_mul(&t3, &t3, &a->x); /* T3 = 2*X*Y^2 (1) */ + r->x = t3; + secp256k1_fe_mul_int(&r->x, 4); /* X' = 8*X*Y^2 (4) */ + secp256k1_fe_negate(&r->x, &r->x, 4); /* X' = -8*X*Y^2 (5) */ + secp256k1_fe_add(&r->x, &t2); /* X' = 9*X^4 - 8*X*Y^2 (6) */ + secp256k1_fe_negate(&t2, &t2, 1); /* T2 = -9*X^4 (2) */ + secp256k1_fe_mul_int(&t3, 6); /* T3 = 12*X*Y^2 (6) */ + secp256k1_fe_add(&t3, &t2); /* T3 = 12*X*Y^2 - 9*X^4 (8) */ + secp256k1_fe_mul(&r->y, &t1, &t3); /* Y' = 36*X^3*Y^2 - 27*X^6 (1) */ + secp256k1_fe_negate(&t2, &t4, 2); /* T2 = -8*Y^4 (3) */ + secp256k1_fe_add(&r->y, &t2); /* Y' = 36*X^3*Y^2 - 27*X^6 - 8*Y^4 (4) */ +} + +static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_t *b) { + if (a->infinity) { + *r = *b; + return; + } + if (b->infinity) { + *r = *a; + return; + } + r->infinity = 0; + secp256k1_fe_t z22; secp256k1_fe_sqr(&z22, &b->z); + secp256k1_fe_t z12; secp256k1_fe_sqr(&z12, &a->z); + secp256k1_fe_t u1; secp256k1_fe_mul(&u1, &a->x, &z22); + secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12); + secp256k1_fe_t s1; secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z); + secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); + secp256k1_fe_normalize_var(&u1); + secp256k1_fe_normalize_var(&u2); + if (secp256k1_fe_equal(&u1, &u2)) { + secp256k1_fe_normalize_var(&s1); + secp256k1_fe_normalize_var(&s2); + if (secp256k1_fe_equal(&s1, &s2)) { + secp256k1_gej_double_var(r, a); + } else { + r->infinity = 1; + } + return; + } + secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); + secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); + secp256k1_fe_t i2; secp256k1_fe_sqr(&i2, &i); + secp256k1_fe_t h2; secp256k1_fe_sqr(&h2, &h); + secp256k1_fe_t h3; secp256k1_fe_mul(&h3, &h, &h2); + secp256k1_fe_mul(&r->z, &a->z, &b->z); secp256k1_fe_mul(&r->z, &r->z, &h); + secp256k1_fe_t t; secp256k1_fe_mul(&t, &u1, &h2); + r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); + secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); + secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); + secp256k1_fe_add(&r->y, &h3); +} + +static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) { + if (a->infinity) { + r->infinity = b->infinity; + r->x = b->x; + r->y = b->y; + secp256k1_fe_set_int(&r->z, 1); + return; + } + if (b->infinity) { + *r = *a; + return; + } + r->infinity = 0; + secp256k1_fe_t z12; secp256k1_fe_sqr(&z12, &a->z); + secp256k1_fe_t u1 = a->x; + secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12); + secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_var(&s1); + secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); + secp256k1_fe_normalize_var(&u1); + secp256k1_fe_normalize_var(&u2); + if (secp256k1_fe_equal(&u1, &u2)) { + secp256k1_fe_normalize_var(&s2); + if (secp256k1_fe_equal(&s1, &s2)) { + secp256k1_gej_double_var(r, a); + } else { + r->infinity = 1; + } + return; + } + secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); + secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); + secp256k1_fe_t i2; secp256k1_fe_sqr(&i2, &i); + secp256k1_fe_t h2; secp256k1_fe_sqr(&h2, &h); + secp256k1_fe_t h3; secp256k1_fe_mul(&h3, &h, &h2); + r->z = a->z; secp256k1_fe_mul(&r->z, &r->z, &h); + secp256k1_fe_t t; secp256k1_fe_mul(&t, &u1, &h2); + r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); + secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); + secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); + secp256k1_fe_add(&r->y, &h3); +} + +static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) { + VERIFY_CHECK(!b->infinity); + VERIFY_CHECK(a->infinity == 0 || a->infinity == 1); + + /** In: + * Eric Brier and Marc Joye, Weierstrass Elliptic Curves and Side-Channel Attacks. + * In D. Naccache and P. Paillier, Eds., Public Key Cryptography, vol. 2274 of Lecture Notes in Computer Science, pages 335-345. Springer-Verlag, 2002. + * we find as solution for a unified addition/doubling formula: + * lambda = ((x1 + x2)^2 - x1 * x2 + a) / (y1 + y2), with a = 0 for secp256k1's curve equation. + * x3 = lambda^2 - (x1 + x2) + * 2*y3 = lambda * (x1 + x2 - 2 * x3) - (y1 + y2). + * + * Substituting x_i = Xi / Zi^2 and yi = Yi / Zi^3, for i=1,2,3, gives: + * U1 = X1*Z2^2, U2 = X2*Z1^2 + * S1 = Y1*Z2^3, S2 = Y2*Z1^3 + * Z = Z1*Z2 + * T = U1+U2 + * M = S1+S2 + * Q = T*M^2 + * R = T^2-U1*U2 + * X3 = 4*(R^2-Q) + * Y3 = 4*(R*(3*Q-2*R^2)-M^4) + * Z3 = 2*M*Z + * (Note that the paper uses xi = Xi / Zi and yi = Yi / Zi instead.) + */ + + secp256k1_fe_t zz; secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */ + secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize(&u1); /* u1 = U1 = X1*Z2^2 (1) */ + secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */ + secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize(&s1); /* s1 = S1 = Y1*Z2^3 (1) */ + secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z2^2 (1) */ + secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */ + secp256k1_fe_t z = a->z; /* z = Z = Z1*Z2 (8) */ + secp256k1_fe_t t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (2) */ + secp256k1_fe_t m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (2) */ + secp256k1_fe_t n; secp256k1_fe_sqr(&n, &m); /* n = M^2 (1) */ + secp256k1_fe_t q; secp256k1_fe_mul(&q, &n, &t); /* q = Q = T*M^2 (1) */ + secp256k1_fe_sqr(&n, &n); /* n = M^4 (1) */ + secp256k1_fe_t rr; secp256k1_fe_sqr(&rr, &t); /* rr = T^2 (1) */ + secp256k1_fe_mul(&t, &u1, &u2); secp256k1_fe_negate(&t, &t, 1); /* t = -U1*U2 (2) */ + secp256k1_fe_add(&rr, &t); /* rr = R = T^2-U1*U2 (3) */ + secp256k1_fe_sqr(&t, &rr); /* t = R^2 (1) */ + secp256k1_fe_mul(&r->z, &m, &z); /* r->z = M*Z (1) */ + secp256k1_fe_normalize(&r->z); + int infinity = secp256k1_fe_is_zero(&r->z) * (1 - a->infinity); + secp256k1_fe_mul_int(&r->z, 2 * (1 - a->infinity)); /* r->z = Z3 = 2*M*Z (2) */ + r->x = t; /* r->x = R^2 (1) */ + secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */ + secp256k1_fe_add(&r->x, &q); /* r->x = R^2-Q (3) */ + secp256k1_fe_normalize(&r->x); + secp256k1_fe_mul_int(&q, 3); /* q = -3*Q (6) */ + secp256k1_fe_mul_int(&t, 2); /* t = 2*R^2 (2) */ + secp256k1_fe_add(&t, &q); /* t = 2*R^2-3*Q (8) */ + secp256k1_fe_mul(&t, &t, &rr); /* t = R*(2*R^2-3*Q) (1) */ + secp256k1_fe_add(&t, &n); /* t = R*(2*R^2-3*Q)+M^4 (2) */ + secp256k1_fe_negate(&r->y, &t, 2); /* r->y = R*(3*Q-2*R^2)-M^4 (3) */ + secp256k1_fe_normalize(&r->y); + secp256k1_fe_mul_int(&r->x, 4 * (1 - a->infinity)); /* r->x = X3 = 4*(R^2-Q) */ + 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. + */ + 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); + r->infinity = infinity; +} + + + +static void secp256k1_gej_get_hex(char *r, int *rlen, const secp256k1_gej_t *a) { + secp256k1_gej_t c = *a; + secp256k1_ge_t t; secp256k1_ge_set_gej(&t, &c); + secp256k1_ge_get_hex(r, rlen, &t); +} + +#ifdef USE_ENDOMORPHISM +static void secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a) { + const secp256k1_fe_t *beta = &secp256k1_ge_consts->beta; + *r = *a; + secp256k1_fe_mul(&r->x, &r->x, beta); +} +#endif + +static void secp256k1_ge_start(void) { + static const unsigned char secp256k1_ge_consts_g_x[] = { + 0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC, + 0x55,0xA0,0x62,0x95,0xCE,0x87,0x0B,0x07, + 0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9, + 0x59,0xF2,0x81,0x5B,0x16,0xF8,0x17,0x98 + }; + static const unsigned char secp256k1_ge_consts_g_y[] = { + 0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65, + 0x5D,0xA4,0xFB,0xFC,0x0E,0x11,0x08,0xA8, + 0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19, + 0x9C,0x47,0xD0,0x8F,0xFB,0x10,0xD4,0xB8 + }; +#ifdef USE_ENDOMORPHISM + /* properties of secp256k1's efficiently computable endomorphism */ + static const unsigned char secp256k1_ge_consts_beta[] = { + 0x7a,0xe9,0x6a,0x2b,0x65,0x7c,0x07,0x10, + 0x6e,0x64,0x47,0x9e,0xac,0x34,0x34,0xe9, + 0x9c,0xf0,0x49,0x75,0x12,0xf5,0x89,0x95, + 0xc1,0x39,0x6c,0x28,0x71,0x95,0x01,0xee + }; +#endif + if (secp256k1_ge_consts == NULL) { + secp256k1_ge_consts_t *ret = (secp256k1_ge_consts_t*)checked_malloc(sizeof(secp256k1_ge_consts_t)); +#ifdef USE_ENDOMORPHISM + VERIFY_CHECK(secp256k1_fe_set_b32(&ret->beta, secp256k1_ge_consts_beta)); +#endif + secp256k1_fe_t g_x, g_y; + VERIFY_CHECK(secp256k1_fe_set_b32(&g_x, secp256k1_ge_consts_g_x)); + VERIFY_CHECK(secp256k1_fe_set_b32(&g_y, secp256k1_ge_consts_g_y)); + secp256k1_ge_set_xy(&ret->g, &g_x, &g_y); + secp256k1_ge_consts = ret; + } +} + +static void secp256k1_ge_stop(void) { + if (secp256k1_ge_consts != NULL) { + secp256k1_ge_consts_t *c = (secp256k1_ge_consts_t*)secp256k1_ge_consts; + free((void*)c); + secp256k1_ge_consts = NULL; + } +} + +#endif diff --git a/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java new file mode 100644 index 0000000000..90a498eaa2 --- /dev/null +++ b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java @@ -0,0 +1,60 @@ +package org.bitcoin; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import com.google.common.base.Preconditions; + + +/** + * This class holds native methods to handle ECDSA verification. + * You can find an example library that can be used for this at + * https://github.com/sipa/secp256k1 + */ +public class NativeSecp256k1 { + public static final boolean enabled; + static { + boolean isEnabled = true; + try { + System.loadLibrary("javasecp256k1"); + } catch (UnsatisfiedLinkError e) { + isEnabled = false; + } + enabled = isEnabled; + } + + private static ThreadLocal<ByteBuffer> nativeECDSABuffer = new ThreadLocal<ByteBuffer>(); + /** + * Verifies the given secp256k1 signature in native code. + * Calling when enabled == false is undefined (probably library not loaded) + * + * @param data The data which was signed, must be exactly 32 bytes + * @param signature The signature + * @param pub The public key which did the signing + */ + public static boolean verify(byte[] data, byte[] signature, byte[] pub) { + Preconditions.checkArgument(data.length == 32 && signature.length <= 520 && pub.length <= 520); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null) { + byteBuff = ByteBuffer.allocateDirect(32 + 8 + 520 + 520); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(data); + byteBuff.putInt(signature.length); + byteBuff.putInt(pub.length); + byteBuff.put(signature); + byteBuff.put(pub); + return secp256k1_ecdsa_verify(byteBuff) == 1; + } + + /** + * @param byteBuff signature format is byte[32] data, + * native-endian int signatureLength, native-endian int pubkeyLength, + * byte[signatureLength] signature, byte[pubkeyLength] pub + * @returns 1 for valid signature, anything else for invalid + */ + private static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff); +} diff --git a/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c new file mode 100644 index 0000000000..bb4cd70728 --- /dev/null +++ b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c @@ -0,0 +1,23 @@ +#include "org_bitcoin_NativeSecp256k1.h" +#include "include/secp256k1.h" + +JNIEXPORT jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify + (JNIEnv* env, jclass classObject, jobject byteBufferObject) +{ + unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + int sigLen = *((int*)(data + 32)); + int pubLen = *((int*)(data + 32 + 4)); + + return secp256k1_ecdsa_verify(data, 32, data+32+8, sigLen, data+32+8+sigLen, pubLen); +} + +static void __javasecp256k1_attach(void) __attribute__((constructor)); +static void __javasecp256k1_detach(void) __attribute__((destructor)); + +static void __javasecp256k1_attach(void) { + secp256k1_start(SECP256K1_START_VERIFY); +} + +static void __javasecp256k1_detach(void) { + secp256k1_stop(); +} diff --git a/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h new file mode 100644 index 0000000000..d7fb004fa8 --- /dev/null +++ b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h @@ -0,0 +1,21 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class org_bitcoin_NativeSecp256k1 */ + +#ifndef _Included_org_bitcoin_NativeSecp256k1 +#define _Included_org_bitcoin_NativeSecp256k1 +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ecdsa_verify + * Signature: (Ljava/nio/ByteBuffer;)I + */ +JNIEXPORT jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify + (JNIEnv *, jclass, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/secp256k1/src/num.h b/src/secp256k1/src/num.h new file mode 100644 index 0000000000..339b6bb6ec --- /dev/null +++ b/src/secp256k1/src/num.h @@ -0,0 +1,68 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_NUM_ +#define _SECP256K1_NUM_ + +#ifndef USE_NUM_NONE + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#if defined(USE_NUM_GMP) +#include "num_gmp.h" +#else +#error "Please select num implementation" +#endif + +/** Copy a number. */ +static void secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a); + +/** Convert a number's absolute value to a binary big-endian string. + * There must be enough place. */ +static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a); + +/** Set a number to the value of a binary big-endian string. */ +static void secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen); + +/** Compute a modular inverse. The input must be less than the modulus. */ +static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m); + +/** Compare the absolute value of two numbers. */ +static int secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b); + +/** Test whether two number are equal (including sign). */ +static int secp256k1_num_eq(const secp256k1_num_t *a, const secp256k1_num_t *b); + +/** Add two (signed) numbers. */ +static void secp256k1_num_add(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); + +/** Subtract two (signed) numbers. */ +static void secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); + +/** Multiply two (signed) numbers. */ +static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); + +/** Replace a number by its remainder modulo m. M's sign is ignored. The result is a number between 0 and m-1, + even if r was negative. */ +static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m); + +/** Right-shift the passed number by bits bits. */ +static void secp256k1_num_shift(secp256k1_num_t *r, int bits); + +/** Check whether a number is zero. */ +static int secp256k1_num_is_zero(const secp256k1_num_t *a); + +/** Check whether a number is strictly negative. */ +static int secp256k1_num_is_neg(const secp256k1_num_t *a); + +/** Change a number's sign. */ +static void secp256k1_num_negate(secp256k1_num_t *r); + +#endif + +#endif diff --git a/src/secp256k1/src/num_gmp.h b/src/secp256k1/src/num_gmp.h new file mode 100644 index 0000000000..baa1f2bf2e --- /dev/null +++ b/src/secp256k1/src/num_gmp.h @@ -0,0 +1,20 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_NUM_REPR_ +#define _SECP256K1_NUM_REPR_ + +#include <gmp.h> + +#define NUM_LIMBS ((256+GMP_NUMB_BITS-1)/GMP_NUMB_BITS) + +typedef struct { + mp_limb_t data[2*NUM_LIMBS]; + int neg; + int limbs; +} secp256k1_num_t; + +#endif diff --git a/src/secp256k1/src/num_gmp_impl.h b/src/secp256k1/src/num_gmp_impl.h new file mode 100644 index 0000000000..19d474e59f --- /dev/null +++ b/src/secp256k1/src/num_gmp_impl.h @@ -0,0 +1,232 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_NUM_REPR_IMPL_H_ +#define _SECP256K1_NUM_REPR_IMPL_H_ + +#include <string.h> +#include <stdlib.h> +#include <gmp.h> + +#include "util.h" +#include "num.h" + +#ifdef VERIFY +static void secp256k1_num_sanity(const secp256k1_num_t *a) { + VERIFY_CHECK(a->limbs == 1 || (a->limbs > 1 && a->data[a->limbs-1] != 0)); +} +#else +#define secp256k1_num_sanity(a) do { } while(0) +#endif + +static void secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a) { + *r = *a; +} + +static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a) { + unsigned char tmp[65]; + int len = 0; + if (a->limbs>1 || a->data[0] != 0) { + len = mpn_get_str(tmp, 256, (mp_limb_t*)a->data, a->limbs); + } + int shift = 0; + while (shift < len && tmp[shift] == 0) shift++; + VERIFY_CHECK(len-shift <= (int)rlen); + memset(r, 0, rlen - len + shift); + if (len > shift) { + memcpy(r + rlen - len + shift, tmp + shift, len - shift); + } + memset(tmp, 0, sizeof(tmp)); +} + +static void secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen) { + VERIFY_CHECK(alen > 0); + VERIFY_CHECK(alen <= 64); + int len = mpn_set_str(r->data, a, alen, 256); + if (len == 0) { + r->data[0] = 0; + len = 1; + } + VERIFY_CHECK(len <= NUM_LIMBS*2); + r->limbs = len; + r->neg = 0; + 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) { + mp_limb_t c = mpn_add(r->data, a->data, a->limbs, b->data, b->limbs); + r->limbs = a->limbs; + if (c != 0) { + VERIFY_CHECK(r->limbs < 2*NUM_LIMBS); + r->data[r->limbs++] = c; + } +} + +static void secp256k1_num_sub_abs(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { + 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--; +} + +static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m) { + secp256k1_num_sanity(r); + secp256k1_num_sanity(m); + + if (r->limbs >= m->limbs) { + mp_limb_t t[2*NUM_LIMBS]; + 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--; + } + + if (r->neg && (r->limbs > 1 || r->data[0] != 0)) { + secp256k1_num_sub_abs(r, m, r); + r->neg = 0; + } +} + +static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m) { + secp256k1_num_sanity(a); + secp256k1_num_sanity(m); + + /** mpn_gcdext computes: (G,S) = gcdext(U,V), where + * * G = gcd(U,V) + * * G = U*S + V*T + * * U has equal or more limbs than V, and V has no padding + * If we set U to be (a padded version of) a, and V = m: + * G = a*S + m*T + * G = a*S mod m + * Assuming G=1: + * S = 1/a mod m + */ + VERIFY_CHECK(m->limbs <= NUM_LIMBS); + VERIFY_CHECK(m->data[m->limbs-1] != 0); + mp_limb_t g[NUM_LIMBS+1]; + mp_limb_t u[NUM_LIMBS+1]; + mp_limb_t v[NUM_LIMBS+1]; + for (int i=0; i < m->limbs; i++) { + u[i] = (i < a->limbs) ? a->data[i] : 0; + v[i] = m->data[i]; + } + mp_size_t sn = NUM_LIMBS+1; + mp_size_t gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs); + VERIFY_CHECK(gn == 1); + VERIFY_CHECK(g[0] == 1); + r->neg = a->neg ^ m->neg; + 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--; + } else { + r->limbs = sn; + } + memset(g, 0, sizeof(g)); + memset(u, 0, sizeof(u)); + memset(v, 0, sizeof(v)); +} + +static int secp256k1_num_is_zero(const secp256k1_num_t *a) { + return (a->limbs == 1 && a->data[0] == 0); +} + +static int secp256k1_num_is_neg(const secp256k1_num_t *a) { + return (a->limbs > 1 || a->data[0] != 0) && a->neg; +} + +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; + 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; + return mpn_cmp(a->data, b->data, a->limbs) == 0; +} + +static void secp256k1_num_subadd(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b, int bneg) { + if (!(b->neg ^ bneg ^ a->neg)) { /* a and b have the same sign */ + r->neg = a->neg; + if (a->limbs >= b->limbs) { + secp256k1_num_add_abs(r, a, b); + } else { + secp256k1_num_add_abs(r, b, a); + } + } else { + if (secp256k1_num_cmp(a, b) > 0) { + r->neg = a->neg; + secp256k1_num_sub_abs(r, a, b); + } else { + r->neg = b->neg ^ bneg; + secp256k1_num_sub_abs(r, b, a); + } + } +} + +static void secp256k1_num_add(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { + secp256k1_num_sanity(a); + secp256k1_num_sanity(b); + secp256k1_num_subadd(r, a, b, 0); +} + +static void secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { + secp256k1_num_sanity(a); + secp256k1_num_sanity(b); + secp256k1_num_subadd(r, a, b, 1); +} + +static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { + secp256k1_num_sanity(a); + secp256k1_num_sanity(b); + + mp_limb_t tmp[2*NUM_LIMBS+1]; + VERIFY_CHECK(a->limbs + b->limbs <= 2*NUM_LIMBS+1); + if ((a->limbs==1 && a->data[0]==0) || (b->limbs==1 && b->data[0]==0)) { + r->limbs = 1; + r->neg = 0; + r->data[0] = 0; + return; + } + if (a->limbs >= b->limbs) + mpn_mul(tmp, a->data, a->limbs, b->data, b->limbs); + 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--; + VERIFY_CHECK(r->limbs <= 2*NUM_LIMBS); + mpn_copyi(r->data, tmp, r->limbs); + r->neg = a->neg ^ b->neg; + memset(tmp, 0, sizeof(tmp)); +} + +static void secp256k1_num_shift(secp256k1_num_t *r, int bits) { + if (bits % GMP_NUMB_BITS) { + // Shift within limbs. + mpn_rshift(r->data, r->data, r->limbs, bits % GMP_NUMB_BITS); + } + if (bits >= GMP_NUMB_BITS) { + // Shift full limbs. + for (int i = 0; i < r->limbs; i++) { + int index = i + (bits / GMP_NUMB_BITS); + if (index < r->limbs && index < 2*NUM_LIMBS) { + r->data[i] = r->data[index]; + } else { + r->data[i] = 0; + } + } + } + while (r->limbs>1 && r->data[r->limbs-1]==0) r->limbs--; +} + +static void secp256k1_num_negate(secp256k1_num_t *r) { + r->neg ^= 1; +} + +#endif diff --git a/src/secp256k1/src/num_impl.h b/src/secp256k1/src/num_impl.h new file mode 100644 index 0000000000..0b0e3a072a --- /dev/null +++ b/src/secp256k1/src/num_impl.h @@ -0,0 +1,24 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_NUM_IMPL_H_ +#define _SECP256K1_NUM_IMPL_H_ + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include "num.h" + +#if defined(USE_NUM_GMP) +#include "num_gmp_impl.h" +#elif defined(USE_NUM_NONE) +/* Nothing. */ +#else +#error "Please select num implementation" +#endif + +#endif diff --git a/src/secp256k1/src/scalar.h b/src/secp256k1/src/scalar.h new file mode 100644 index 0000000000..2f5ba0d447 --- /dev/null +++ b/src/secp256k1/src/scalar.h @@ -0,0 +1,96 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_SCALAR_ +#define _SECP256K1_SCALAR_ + +#include "num.h" + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#if defined(USE_SCALAR_4X64) +#include "scalar_4x64.h" +#elif defined(USE_SCALAR_8X32) +#include "scalar_8x32.h" +#else +#error "Please select scalar implementation" +#endif + +static void secp256k1_scalar_start(void); +static void secp256k1_scalar_stop(void); + +/** Clear a scalar to prevent the leak of sensitive data. */ +static void secp256k1_scalar_clear(secp256k1_scalar_t *r); + +/** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */ +static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count); + +/** Access bits from a scalar. Not constant time. */ +static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count); + +/** Set a scalar from a big endian byte array. */ +static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *bin, int *overflow); + +/** Set a scalar to an unsigned integer. */ +static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, unsigned int v); + +/** Convert a scalar to a byte array. */ +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_t* a); + +/** Add two scalars together (modulo the group order). Returns whether it overflowed. */ +static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b); + +/** Add a power of two to a scalar. The result is not allowed to overflow. */ +static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit); + +/** Multiply two scalars (modulo the group order). */ +static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b); + +/** Compute the square of a scalar (modulo the group order). */ +static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a); + +/** Compute the inverse of a scalar (modulo the group order). */ +static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scalar_t *a); + +/** Compute the inverse of a scalar (modulo the group order), without constant-time guarantee. */ +static void secp256k1_scalar_inverse_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a); + +/** Compute the complement of a scalar (modulo the group order). */ +static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scalar_t *a); + +/** Check whether a scalar equals zero. */ +static int secp256k1_scalar_is_zero(const secp256k1_scalar_t *a); + +/** Check whether a scalar equals one. */ +static int secp256k1_scalar_is_one(const secp256k1_scalar_t *a); + +/** Check whether a scalar is higher than the group order divided by 2. */ +static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a); + +#ifndef USE_NUM_NONE +/** Convert a scalar to a number. */ +static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a); + +/** Get the order of the group as a number. */ +static void secp256k1_scalar_order_get_num(secp256k1_num_t *r); +#endif + +/** Compare two scalars. */ +static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b); + +static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a); + +#ifdef USE_ENDOMORPHISM +/** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (see secp256k1_gej_mul_lambda). */ +static void secp256k1_scalar_split_lambda_var(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a); +#endif + +/** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */ +static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift); + +#endif diff --git a/src/secp256k1/src/scalar_4x64.h b/src/secp256k1/src/scalar_4x64.h new file mode 100644 index 0000000000..5a751c6862 --- /dev/null +++ b/src/secp256k1/src/scalar_4x64.h @@ -0,0 +1,17 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_SCALAR_REPR_ +#define _SECP256K1_SCALAR_REPR_ + +#include <stdint.h> + +/** A scalar modulo the group order of the secp256k1 curve. */ +typedef struct { + uint64_t d[4]; +} secp256k1_scalar_t; + +#endif diff --git a/src/secp256k1/src/scalar_4x64_impl.h b/src/secp256k1/src/scalar_4x64_impl.h new file mode 100644 index 0000000000..d144775220 --- /dev/null +++ b/src/secp256k1/src/scalar_4x64_impl.h @@ -0,0 +1,431 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_SCALAR_REPR_IMPL_H_ +#define _SECP256K1_SCALAR_REPR_IMPL_H_ + +typedef unsigned __int128 uint128_t; + +/* Limbs of the secp256k1 order. */ +#define SECP256K1_N_0 ((uint64_t)0xBFD25E8CD0364141ULL) +#define SECP256K1_N_1 ((uint64_t)0xBAAEDCE6AF48A03BULL) +#define SECP256K1_N_2 ((uint64_t)0xFFFFFFFFFFFFFFFEULL) +#define SECP256K1_N_3 ((uint64_t)0xFFFFFFFFFFFFFFFFULL) + +/* Limbs of 2^256 minus the secp256k1 order. */ +#define SECP256K1_N_C_0 (~SECP256K1_N_0 + 1) +#define SECP256K1_N_C_1 (~SECP256K1_N_1) +#define SECP256K1_N_C_2 (1) + +/* Limbs of half the secp256k1 order. */ +#define SECP256K1_N_H_0 ((uint64_t)0xDFE92F46681B20A0ULL) +#define SECP256K1_N_H_1 ((uint64_t)0x5D576E7357A4501DULL) +#define SECP256K1_N_H_2 ((uint64_t)0xFFFFFFFFFFFFFFFFULL) +#define SECP256K1_N_H_3 ((uint64_t)0x7FFFFFFFFFFFFFFFULL) + +SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar_t *r) { + r->d[0] = 0; + r->d[1] = 0; + r->d[2] = 0; + r->d[3] = 0; +} + +SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, unsigned int v) { + r->d[0] = v; + r->d[1] = 0; + r->d[2] = 0; + r->d[3] = 0; +} + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) { + VERIFY_CHECK((offset + count - 1) >> 6 == offset >> 6); + return (a->d[offset >> 6] >> (offset & 0x3F)) & ((((uint64_t)1) << count) - 1); +} + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) { + VERIFY_CHECK(count < 32); + VERIFY_CHECK(offset + count <= 256); + if ((offset + count - 1) >> 6 == offset >> 6) { + return secp256k1_scalar_get_bits(a, offset, count); + } else { + VERIFY_CHECK((offset >> 6) + 1 < 4); + return ((a->d[offset >> 6] >> (offset & 0x3F)) | (a->d[(offset >> 6) + 1] << (64 - (offset & 0x3F)))) & ((((uint64_t)1) << count) - 1); + } +} + +SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar_t *a) { + int yes = 0; + int no = 0; + no |= (a->d[3] < SECP256K1_N_3); /* No need for a > check. */ + no |= (a->d[2] < SECP256K1_N_2); + yes |= (a->d[2] > SECP256K1_N_2) & ~no; + no |= (a->d[1] < SECP256K1_N_1); + yes |= (a->d[1] > SECP256K1_N_1) & ~no; + yes |= (a->d[0] >= SECP256K1_N_0) & ~no; + return yes; +} + +SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, unsigned int overflow) { + VERIFY_CHECK(overflow <= 1); + uint128_t t = (uint128_t)r->d[0] + overflow * SECP256K1_N_C_0; + r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)r->d[1] + overflow * SECP256K1_N_C_1; + r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)r->d[2] + overflow * SECP256K1_N_C_2; + r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint64_t)r->d[3]; + r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; + return overflow; +} + +static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { + uint128_t t = (uint128_t)a->d[0] + b->d[0]; + r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)a->d[1] + b->d[1]; + r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)a->d[2] + b->d[2]; + r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)a->d[3] + b->d[3]; + r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + int overflow = t + secp256k1_scalar_check_overflow(r); + VERIFY_CHECK(overflow == 0 || overflow == 1); + secp256k1_scalar_reduce(r, overflow); + return overflow; +} + +static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { + VERIFY_CHECK(bit < 256); + uint128_t t = (uint128_t)r->d[0] + (((uint64_t)((bit >> 6) == 0)) << (bit & 0x3F)); + r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)r->d[1] + (((uint64_t)((bit >> 6) == 1)) << (bit & 0x3F)); + r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)r->d[2] + (((uint64_t)((bit >> 6) == 2)) << (bit & 0x3F)); + r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; + t += (uint128_t)r->d[3] + (((uint64_t)((bit >> 6) == 3)) << (bit & 0x3F)); + r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; +#ifdef VERIFY + VERIFY_CHECK((t >> 64) == 0); + VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); +#endif +} + +static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *b32, int *overflow) { + r->d[0] = (uint64_t)b32[31] | (uint64_t)b32[30] << 8 | (uint64_t)b32[29] << 16 | (uint64_t)b32[28] << 24 | (uint64_t)b32[27] << 32 | (uint64_t)b32[26] << 40 | (uint64_t)b32[25] << 48 | (uint64_t)b32[24] << 56; + r->d[1] = (uint64_t)b32[23] | (uint64_t)b32[22] << 8 | (uint64_t)b32[21] << 16 | (uint64_t)b32[20] << 24 | (uint64_t)b32[19] << 32 | (uint64_t)b32[18] << 40 | (uint64_t)b32[17] << 48 | (uint64_t)b32[16] << 56; + r->d[2] = (uint64_t)b32[15] | (uint64_t)b32[14] << 8 | (uint64_t)b32[13] << 16 | (uint64_t)b32[12] << 24 | (uint64_t)b32[11] << 32 | (uint64_t)b32[10] << 40 | (uint64_t)b32[9] << 48 | (uint64_t)b32[8] << 56; + r->d[3] = (uint64_t)b32[7] | (uint64_t)b32[6] << 8 | (uint64_t)b32[5] << 16 | (uint64_t)b32[4] << 24 | (uint64_t)b32[3] << 32 | (uint64_t)b32[2] << 40 | (uint64_t)b32[1] << 48 | (uint64_t)b32[0] << 56; + int over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); + if (overflow) { + *overflow = over; + } +} + +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_t* a) { + bin[0] = a->d[3] >> 56; bin[1] = a->d[3] >> 48; bin[2] = a->d[3] >> 40; bin[3] = a->d[3] >> 32; bin[4] = a->d[3] >> 24; bin[5] = a->d[3] >> 16; bin[6] = a->d[3] >> 8; bin[7] = a->d[3]; + bin[8] = a->d[2] >> 56; bin[9] = a->d[2] >> 48; bin[10] = a->d[2] >> 40; bin[11] = a->d[2] >> 32; bin[12] = a->d[2] >> 24; bin[13] = a->d[2] >> 16; bin[14] = a->d[2] >> 8; bin[15] = a->d[2]; + bin[16] = a->d[1] >> 56; bin[17] = a->d[1] >> 48; bin[18] = a->d[1] >> 40; bin[19] = a->d[1] >> 32; bin[20] = a->d[1] >> 24; bin[21] = a->d[1] >> 16; bin[22] = a->d[1] >> 8; bin[23] = a->d[1]; + bin[24] = a->d[0] >> 56; bin[25] = a->d[0] >> 48; bin[26] = a->d[0] >> 40; bin[27] = a->d[0] >> 32; bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0]; +} + +SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar_t *a) { + return (a->d[0] | a->d[1] | a->d[2] | a->d[3]) == 0; +} + +static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) { + uint64_t nonzero = 0xFFFFFFFFFFFFFFFFULL * (secp256k1_scalar_is_zero(a) == 0); + uint128_t t = (uint128_t)(~a->d[0]) + SECP256K1_N_0 + 1; + r->d[0] = t & nonzero; t >>= 64; + t += (uint128_t)(~a->d[1]) + SECP256K1_N_1; + r->d[1] = t & nonzero; t >>= 64; + t += (uint128_t)(~a->d[2]) + SECP256K1_N_2; + r->d[2] = t & nonzero; t >>= 64; + t += (uint128_t)(~a->d[3]) + SECP256K1_N_3; + r->d[3] = t & nonzero; +} + +SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar_t *a) { + return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3]) == 0; +} + +static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { + int yes = 0; + int no = 0; + no |= (a->d[3] < SECP256K1_N_H_3); + yes |= (a->d[3] > SECP256K1_N_H_3) & ~no; + no |= (a->d[2] < SECP256K1_N_H_2) & ~yes; /* No need for a > check. */ + no |= (a->d[1] < SECP256K1_N_H_1) & ~yes; + yes |= (a->d[1] > SECP256K1_N_H_1) & ~no; + yes |= (a->d[0] > SECP256K1_N_H_0) & ~no; + return yes; +} + +/* Inspired by the macros in OpenSSL's crypto/bn/asm/x86_64-gcc.c. */ + +/** Add a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ +#define muladd(a,b) { \ + uint64_t tl, th; \ + { \ + uint128_t t = (uint128_t)a * b; \ + th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \ + tl = t; \ + } \ + c0 += tl; /* overflow is handled on the next line */ \ + th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFFFFFFFFFF */ \ + c1 += th; /* overflow is handled on the next line */ \ + c2 += (c1 < th) ? 1 : 0; /* never overflows by contract (verified in the next line) */ \ + VERIFY_CHECK((c1 >= th) || (c2 != 0)); \ +} + +/** Add a*b to the number defined by (c0,c1). c1 must never overflow. */ +#define muladd_fast(a,b) { \ + uint64_t tl, th; \ + { \ + uint128_t t = (uint128_t)a * b; \ + th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \ + tl = t; \ + } \ + c0 += tl; /* overflow is handled on the next line */ \ + th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFFFFFFFFFF */ \ + c1 += th; /* never overflows by contract (verified in the next line) */ \ + VERIFY_CHECK(c1 >= th); \ +} + +/** Add 2*a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ +#define muladd2(a,b) { \ + uint64_t tl, th; \ + { \ + uint128_t t = (uint128_t)a * b; \ + th = t >> 64; /* at most 0xFFFFFFFFFFFFFFFE */ \ + tl = t; \ + } \ + uint64_t th2 = th + th; /* at most 0xFFFFFFFFFFFFFFFE (in case th was 0x7FFFFFFFFFFFFFFF) */ \ + c2 += (th2 < th) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ + VERIFY_CHECK((th2 >= th) || (c2 != 0)); \ + uint64_t tl2 = tl + tl; /* at most 0xFFFFFFFFFFFFFFFE (in case the lowest 63 bits of tl were 0x7FFFFFFFFFFFFFFF) */ \ + th2 += (tl2 < tl) ? 1 : 0; /* at most 0xFFFFFFFFFFFFFFFF */ \ + c0 += tl2; /* overflow is handled on the next line */ \ + th2 += (c0 < tl2) ? 1 : 0; /* second overflow is handled on the next line */ \ + c2 += (c0 < tl2) & (th2 == 0); /* never overflows by contract (verified the next line) */ \ + VERIFY_CHECK((c0 >= tl2) || (th2 != 0) || (c2 != 0)); \ + c1 += th2; /* overflow is handled on the next line */ \ + c2 += (c1 < th2) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ + VERIFY_CHECK((c1 >= th2) || (c2 != 0)); \ +} + +/** Add a to the number defined by (c0,c1,c2). c2 must never overflow. */ +#define sumadd(a) { \ + c0 += (a); /* overflow is handled on the next line */ \ + unsigned int over = (c0 < (a)) ? 1 : 0; \ + c1 += over; /* overflow is handled on the next line */ \ + c2 += (c1 < over) ? 1 : 0; /* never overflows by contract */ \ +} + +/** Add a to the number defined by (c0,c1). c1 must never overflow, c2 must be zero. */ +#define sumadd_fast(a) { \ + c0 += (a); /* overflow is handled on the next line */ \ + c1 += (c0 < (a)) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ + VERIFY_CHECK((c1 != 0) | (c0 >= (a))); \ + VERIFY_CHECK(c2 == 0); \ +} + +/** Extract the lowest 64 bits of (c0,c1,c2) into n, and left shift the number 64 bits. */ +#define extract(n) { \ + (n) = c0; \ + c0 = c1; \ + c1 = c2; \ + c2 = 0; \ +} + +/** Extract the lowest 64 bits of (c0,c1,c2) into n, and left shift the number 64 bits. c2 is required to be zero. */ +#define extract_fast(n) { \ + (n) = c0; \ + c0 = c1; \ + c1 = 0; \ + VERIFY_CHECK(c2 == 0); \ +} + +static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l) { + uint64_t n0 = l[4], n1 = l[5], n2 = l[6], n3 = l[7]; + + /* 160 bit accumulator. */ + uint64_t c0, c1; + uint32_t c2; + + /* Reduce 512 bits into 385. */ + /* m[0..6] = l[0..3] + n[0..3] * SECP256K1_N_C. */ + c0 = l[0]; c1 = 0; c2 = 0; + muladd_fast(n0, SECP256K1_N_C_0); + uint64_t m0; extract_fast(m0); + sumadd_fast(l[1]); + muladd(n1, SECP256K1_N_C_0); + muladd(n0, SECP256K1_N_C_1); + uint64_t m1; extract(m1); + sumadd(l[2]); + muladd(n2, SECP256K1_N_C_0); + muladd(n1, SECP256K1_N_C_1); + sumadd(n0); + uint64_t m2; extract(m2); + sumadd(l[3]); + muladd(n3, SECP256K1_N_C_0); + muladd(n2, SECP256K1_N_C_1); + sumadd(n1); + uint64_t m3; extract(m3); + muladd(n3, SECP256K1_N_C_1); + sumadd(n2); + uint64_t m4; extract(m4); + sumadd_fast(n3); + uint64_t m5; extract_fast(m5); + VERIFY_CHECK(c0 <= 1); + uint32_t m6 = c0; + + /* Reduce 385 bits into 258. */ + /* p[0..4] = m[0..3] + m[4..6] * SECP256K1_N_C. */ + c0 = m0; c1 = 0; c2 = 0; + muladd_fast(m4, SECP256K1_N_C_0); + uint64_t p0; extract_fast(p0); + sumadd_fast(m1); + muladd(m5, SECP256K1_N_C_0); + muladd(m4, SECP256K1_N_C_1); + uint64_t p1; extract(p1); + sumadd(m2); + muladd(m6, SECP256K1_N_C_0); + muladd(m5, SECP256K1_N_C_1); + sumadd(m4); + uint64_t p2; extract(p2); + sumadd_fast(m3); + muladd_fast(m6, SECP256K1_N_C_1); + sumadd_fast(m5); + uint64_t p3; extract_fast(p3); + uint32_t p4 = c0 + m6; + VERIFY_CHECK(p4 <= 2); + + /* Reduce 258 bits into 256. */ + /* r[0..3] = p[0..3] + p[4] * SECP256K1_N_C. */ + uint128_t c = p0 + (uint128_t)SECP256K1_N_C_0 * p4; + r->d[0] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; + c += p1 + (uint128_t)SECP256K1_N_C_1 * p4; + r->d[1] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; + c += p2 + (uint128_t)p4; + r->d[2] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; + c += p3; + r->d[3] = c & 0xFFFFFFFFFFFFFFFFULL; c >>= 64; + + /* Final reduction of r. */ + secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r)); +} + +static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { + /* 160 bit accumulator. */ + uint64_t c0 = 0, c1 = 0; + uint32_t c2 = 0; + + /* l[0..7] = a[0..3] * b[0..3]. */ + muladd_fast(a->d[0], b->d[0]); + extract_fast(l[0]); + muladd(a->d[0], b->d[1]); + muladd(a->d[1], b->d[0]); + extract(l[1]); + muladd(a->d[0], b->d[2]); + muladd(a->d[1], b->d[1]); + muladd(a->d[2], b->d[0]); + extract(l[2]); + muladd(a->d[0], b->d[3]); + muladd(a->d[1], b->d[2]); + muladd(a->d[2], b->d[1]); + muladd(a->d[3], b->d[0]); + extract(l[3]); + muladd(a->d[1], b->d[3]); + muladd(a->d[2], b->d[2]); + muladd(a->d[3], b->d[1]); + extract(l[4]); + muladd(a->d[2], b->d[3]); + muladd(a->d[3], b->d[2]); + extract(l[5]); + muladd_fast(a->d[3], b->d[3]); + extract_fast(l[6]); + VERIFY_CHECK(c1 <= 0); + l[7] = c0; +} + +static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar_t *a) { + /* 160 bit accumulator. */ + uint64_t c0 = 0, c1 = 0; + uint32_t c2 = 0; + + /* l[0..7] = a[0..3] * b[0..3]. */ + muladd_fast(a->d[0], a->d[0]); + extract_fast(l[0]); + muladd2(a->d[0], a->d[1]); + extract(l[1]); + muladd2(a->d[0], a->d[2]); + muladd(a->d[1], a->d[1]); + extract(l[2]); + muladd2(a->d[0], a->d[3]); + muladd2(a->d[1], a->d[2]); + extract(l[3]); + muladd2(a->d[1], a->d[3]); + muladd(a->d[2], a->d[2]); + extract(l[4]); + muladd2(a->d[2], a->d[3]); + extract(l[5]); + muladd_fast(a->d[3], a->d[3]); + extract_fast(l[6]); + VERIFY_CHECK(c1 == 0); + l[7] = c0; +} + +#undef sumadd +#undef sumadd_fast +#undef muladd +#undef muladd_fast +#undef muladd2 +#undef extract +#undef extract_fast + +static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { + uint64_t l[8]; + secp256k1_scalar_mul_512(l, a, b); + secp256k1_scalar_reduce_512(r, l); +} + +static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) { + uint64_t l[8]; + secp256k1_scalar_sqr_512(l, a); + secp256k1_scalar_reduce_512(r, l); +} + +static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) { + r1->d[0] = a->d[0]; + r1->d[1] = a->d[1]; + r1->d[2] = 0; + r1->d[3] = 0; + r2->d[0] = a->d[2]; + r2->d[1] = a->d[3]; + r2->d[2] = 0; + r2->d[3] = 0; +} + +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { + return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3])) == 0; +} + +SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift) { + VERIFY_CHECK(shift >= 256); + uint64_t l[8]; + secp256k1_scalar_mul_512(l, a, b); + unsigned int shiftlimbs = shift >> 6; + unsigned int shiftlow = shift & 0x3F; + unsigned int shifthigh = 64 - shiftlow; + r->d[0] = shift < 512 ? (l[0 + shiftlimbs] >> shiftlow | (shift < 448 && shiftlow ? (l[1 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[1] = shift < 448 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 384 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[2] = shift < 384 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[3] = shift < 320 ? (l[3 + shiftlimbs] >> shiftlow) : 0; + if ((l[(shift - 1) >> 6] >> ((shift - 1) & 0x3f)) & 1) { + secp256k1_scalar_add_bit(r, 0); + } +} + +#endif diff --git a/src/secp256k1/src/scalar_8x32.h b/src/secp256k1/src/scalar_8x32.h new file mode 100644 index 0000000000..f70328cfc9 --- /dev/null +++ b/src/secp256k1/src/scalar_8x32.h @@ -0,0 +1,17 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_SCALAR_REPR_ +#define _SECP256K1_SCALAR_REPR_ + +#include <stdint.h> + +/** A scalar modulo the group order of the secp256k1 curve. */ +typedef struct { + uint32_t d[8]; +} secp256k1_scalar_t; + +#endif diff --git a/src/secp256k1/src/scalar_8x32_impl.h b/src/secp256k1/src/scalar_8x32_impl.h new file mode 100644 index 0000000000..915cbcddbe --- /dev/null +++ b/src/secp256k1/src/scalar_8x32_impl.h @@ -0,0 +1,668 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_SCALAR_REPR_IMPL_H_ +#define _SECP256K1_SCALAR_REPR_IMPL_H_ + +/* Limbs of the secp256k1 order. */ +#define SECP256K1_N_0 ((uint32_t)0xD0364141UL) +#define SECP256K1_N_1 ((uint32_t)0xBFD25E8CUL) +#define SECP256K1_N_2 ((uint32_t)0xAF48A03BUL) +#define SECP256K1_N_3 ((uint32_t)0xBAAEDCE6UL) +#define SECP256K1_N_4 ((uint32_t)0xFFFFFFFEUL) +#define SECP256K1_N_5 ((uint32_t)0xFFFFFFFFUL) +#define SECP256K1_N_6 ((uint32_t)0xFFFFFFFFUL) +#define SECP256K1_N_7 ((uint32_t)0xFFFFFFFFUL) + +/* Limbs of 2^256 minus the secp256k1 order. */ +#define SECP256K1_N_C_0 (~SECP256K1_N_0 + 1) +#define SECP256K1_N_C_1 (~SECP256K1_N_1) +#define SECP256K1_N_C_2 (~SECP256K1_N_2) +#define SECP256K1_N_C_3 (~SECP256K1_N_3) +#define SECP256K1_N_C_4 (1) + +/* Limbs of half the secp256k1 order. */ +#define SECP256K1_N_H_0 ((uint32_t)0x681B20A0UL) +#define SECP256K1_N_H_1 ((uint32_t)0xDFE92F46UL) +#define SECP256K1_N_H_2 ((uint32_t)0x57A4501DUL) +#define SECP256K1_N_H_3 ((uint32_t)0x5D576E73UL) +#define SECP256K1_N_H_4 ((uint32_t)0xFFFFFFFFUL) +#define SECP256K1_N_H_5 ((uint32_t)0xFFFFFFFFUL) +#define SECP256K1_N_H_6 ((uint32_t)0xFFFFFFFFUL) +#define SECP256K1_N_H_7 ((uint32_t)0x7FFFFFFFUL) + +SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar_t *r) { + r->d[0] = 0; + r->d[1] = 0; + r->d[2] = 0; + r->d[3] = 0; + r->d[4] = 0; + r->d[5] = 0; + r->d[6] = 0; + r->d[7] = 0; +} + +SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, unsigned int v) { + r->d[0] = v; + r->d[1] = 0; + r->d[2] = 0; + r->d[3] = 0; + r->d[4] = 0; + r->d[5] = 0; + r->d[6] = 0; + r->d[7] = 0; +} + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) { + VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5); + return (a->d[offset >> 5] >> (offset & 0x1F)) & ((1 << count) - 1); +} + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) { + VERIFY_CHECK(count < 32); + VERIFY_CHECK(offset + count <= 256); + if ((offset + count - 1) >> 5 == offset >> 5) { + return secp256k1_scalar_get_bits(a, offset, count); + } else { + VERIFY_CHECK((offset >> 5) + 1 < 8); + return ((a->d[offset >> 5] >> (offset & 0x1F)) | (a->d[(offset >> 5) + 1] << (32 - (offset & 0x1F)))) & ((((uint32_t)1) << count) - 1); + } +} + +SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar_t *a) { + int yes = 0; + int no = 0; + no |= (a->d[7] < SECP256K1_N_7); /* No need for a > check. */ + no |= (a->d[6] < SECP256K1_N_6); /* No need for a > check. */ + no |= (a->d[5] < SECP256K1_N_5); /* No need for a > check. */ + no |= (a->d[4] < SECP256K1_N_4); + yes |= (a->d[4] > SECP256K1_N_4) & ~no; + no |= (a->d[3] < SECP256K1_N_3) & ~yes; + yes |= (a->d[3] > SECP256K1_N_3) & ~no; + no |= (a->d[2] < SECP256K1_N_2) & ~yes; + yes |= (a->d[2] > SECP256K1_N_2) & ~no; + no |= (a->d[1] < SECP256K1_N_1) & ~yes; + yes |= (a->d[1] > SECP256K1_N_1) & ~no; + yes |= (a->d[0] >= SECP256K1_N_0) & ~no; + return yes; +} + +SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, uint32_t overflow) { + VERIFY_CHECK(overflow <= 1); + uint64_t t = (uint64_t)r->d[0] + overflow * SECP256K1_N_C_0; + r->d[0] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[1] + overflow * SECP256K1_N_C_1; + r->d[1] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[2] + overflow * SECP256K1_N_C_2; + r->d[2] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[3] + overflow * SECP256K1_N_C_3; + r->d[3] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[4] + overflow * SECP256K1_N_C_4; + r->d[4] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[5]; + r->d[5] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[6]; + r->d[6] = t & 0xFFFFFFFFUL; t >>= 32; + t += (uint64_t)r->d[7]; + r->d[7] = t & 0xFFFFFFFFUL; + return overflow; +} + +static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { + uint64_t t = (uint64_t)a->d[0] + b->d[0]; + r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[1] + b->d[1]; + r->d[1] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[2] + b->d[2]; + r->d[2] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[3] + b->d[3]; + r->d[3] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[4] + b->d[4]; + r->d[4] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[5] + b->d[5]; + r->d[5] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[6] + b->d[6]; + r->d[6] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)a->d[7] + b->d[7]; + r->d[7] = t & 0xFFFFFFFFULL; t >>= 32; + int overflow = t + secp256k1_scalar_check_overflow(r); + VERIFY_CHECK(overflow == 0 || overflow == 1); + secp256k1_scalar_reduce(r, overflow); + return overflow; +} + +static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { + VERIFY_CHECK(bit < 256); + uint64_t t = (uint64_t)r->d[0] + (((uint32_t)((bit >> 5) == 0)) << (bit & 0x1F)); + r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[1] + (((uint32_t)((bit >> 5) == 1)) << (bit & 0x1F)); + r->d[1] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[2] + (((uint32_t)((bit >> 5) == 2)) << (bit & 0x1F)); + r->d[2] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[3] + (((uint32_t)((bit >> 5) == 3)) << (bit & 0x1F)); + r->d[3] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[4] + (((uint32_t)((bit >> 5) == 4)) << (bit & 0x1F)); + r->d[4] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[5] + (((uint32_t)((bit >> 5) == 5)) << (bit & 0x1F)); + r->d[5] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[6] + (((uint32_t)((bit >> 5) == 6)) << (bit & 0x1F)); + r->d[6] = t & 0xFFFFFFFFULL; t >>= 32; + t += (uint64_t)r->d[7] + (((uint32_t)((bit >> 5) == 7)) << (bit & 0x1F)); + r->d[7] = t & 0xFFFFFFFFULL; +#ifdef VERIFY + VERIFY_CHECK((t >> 32) == 0); + VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); +#endif +} + +static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *b32, int *overflow) { + r->d[0] = (uint32_t)b32[31] | (uint32_t)b32[30] << 8 | (uint32_t)b32[29] << 16 | (uint32_t)b32[28] << 24; + r->d[1] = (uint32_t)b32[27] | (uint32_t)b32[26] << 8 | (uint32_t)b32[25] << 16 | (uint32_t)b32[24] << 24; + r->d[2] = (uint32_t)b32[23] | (uint32_t)b32[22] << 8 | (uint32_t)b32[21] << 16 | (uint32_t)b32[20] << 24; + r->d[3] = (uint32_t)b32[19] | (uint32_t)b32[18] << 8 | (uint32_t)b32[17] << 16 | (uint32_t)b32[16] << 24; + r->d[4] = (uint32_t)b32[15] | (uint32_t)b32[14] << 8 | (uint32_t)b32[13] << 16 | (uint32_t)b32[12] << 24; + r->d[5] = (uint32_t)b32[11] | (uint32_t)b32[10] << 8 | (uint32_t)b32[9] << 16 | (uint32_t)b32[8] << 24; + r->d[6] = (uint32_t)b32[7] | (uint32_t)b32[6] << 8 | (uint32_t)b32[5] << 16 | (uint32_t)b32[4] << 24; + r->d[7] = (uint32_t)b32[3] | (uint32_t)b32[2] << 8 | (uint32_t)b32[1] << 16 | (uint32_t)b32[0] << 24; + int over = secp256k1_scalar_reduce(r, secp256k1_scalar_check_overflow(r)); + if (overflow) { + *overflow = over; + } +} + +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_t* a) { + bin[0] = a->d[7] >> 24; bin[1] = a->d[7] >> 16; bin[2] = a->d[7] >> 8; bin[3] = a->d[7]; + bin[4] = a->d[6] >> 24; bin[5] = a->d[6] >> 16; bin[6] = a->d[6] >> 8; bin[7] = a->d[6]; + bin[8] = a->d[5] >> 24; bin[9] = a->d[5] >> 16; bin[10] = a->d[5] >> 8; bin[11] = a->d[5]; + bin[12] = a->d[4] >> 24; bin[13] = a->d[4] >> 16; bin[14] = a->d[4] >> 8; bin[15] = a->d[4]; + bin[16] = a->d[3] >> 24; bin[17] = a->d[3] >> 16; bin[18] = a->d[3] >> 8; bin[19] = a->d[3]; + bin[20] = a->d[2] >> 24; bin[21] = a->d[2] >> 16; bin[22] = a->d[2] >> 8; bin[23] = a->d[2]; + bin[24] = a->d[1] >> 24; bin[25] = a->d[1] >> 16; bin[26] = a->d[1] >> 8; bin[27] = a->d[1]; + bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0]; +} + +SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar_t *a) { + return (a->d[0] | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0; +} + +static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) { + uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(a) == 0); + uint64_t t = (uint64_t)(~a->d[0]) + SECP256K1_N_0 + 1; + r->d[0] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[1]) + SECP256K1_N_1; + r->d[1] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[2]) + SECP256K1_N_2; + r->d[2] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[3]) + SECP256K1_N_3; + r->d[3] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[4]) + SECP256K1_N_4; + r->d[4] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[5]) + SECP256K1_N_5; + r->d[5] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[6]) + SECP256K1_N_6; + r->d[6] = t & nonzero; t >>= 32; + t += (uint64_t)(~a->d[7]) + SECP256K1_N_7; + r->d[7] = t & nonzero; +} + +SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar_t *a) { + return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0; +} + +static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { + int yes = 0; + int no = 0; + no |= (a->d[7] < SECP256K1_N_H_7); + yes |= (a->d[7] > SECP256K1_N_H_7) & ~no; + no |= (a->d[6] < SECP256K1_N_H_6) & ~yes; /* No need for a > check. */ + no |= (a->d[5] < SECP256K1_N_H_5) & ~yes; /* No need for a > check. */ + no |= (a->d[4] < SECP256K1_N_H_4) & ~yes; /* No need for a > check. */ + no |= (a->d[3] < SECP256K1_N_H_3) & ~yes; + yes |= (a->d[3] > SECP256K1_N_H_3) & ~no; + no |= (a->d[2] < SECP256K1_N_H_2) & ~yes; + yes |= (a->d[2] > SECP256K1_N_H_2) & ~no; + no |= (a->d[1] < SECP256K1_N_H_1) & ~yes; + yes |= (a->d[1] > SECP256K1_N_H_1) & ~no; + yes |= (a->d[0] > SECP256K1_N_H_0) & ~no; + return yes; +} + +/* Inspired by the macros in OpenSSL's crypto/bn/asm/x86_64-gcc.c. */ + +/** Add a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ +#define muladd(a,b) { \ + uint32_t tl, th; \ + { \ + uint64_t t = (uint64_t)a * b; \ + th = t >> 32; /* at most 0xFFFFFFFE */ \ + tl = t; \ + } \ + c0 += tl; /* overflow is handled on the next line */ \ + th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \ + c1 += th; /* overflow is handled on the next line */ \ + c2 += (c1 < th) ? 1 : 0; /* never overflows by contract (verified in the next line) */ \ + VERIFY_CHECK((c1 >= th) || (c2 != 0)); \ +} + +/** Add a*b to the number defined by (c0,c1). c1 must never overflow. */ +#define muladd_fast(a,b) { \ + uint32_t tl, th; \ + { \ + uint64_t t = (uint64_t)a * b; \ + th = t >> 32; /* at most 0xFFFFFFFE */ \ + tl = t; \ + } \ + c0 += tl; /* overflow is handled on the next line */ \ + th += (c0 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \ + c1 += th; /* never overflows by contract (verified in the next line) */ \ + VERIFY_CHECK(c1 >= th); \ +} + +/** Add 2*a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ +#define muladd2(a,b) { \ + uint32_t tl, th; \ + { \ + uint64_t t = (uint64_t)a * b; \ + th = t >> 32; /* at most 0xFFFFFFFE */ \ + tl = t; \ + } \ + uint32_t th2 = th + th; /* at most 0xFFFFFFFE (in case th was 0x7FFFFFFF) */ \ + c2 += (th2 < th) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ + VERIFY_CHECK((th2 >= th) || (c2 != 0)); \ + uint32_t tl2 = tl + tl; /* at most 0xFFFFFFFE (in case the lowest 63 bits of tl were 0x7FFFFFFF) */ \ + th2 += (tl2 < tl) ? 1 : 0; /* at most 0xFFFFFFFF */ \ + c0 += tl2; /* overflow is handled on the next line */ \ + th2 += (c0 < tl2) ? 1 : 0; /* second overflow is handled on the next line */ \ + c2 += (c0 < tl2) & (th2 == 0); /* never overflows by contract (verified the next line) */ \ + VERIFY_CHECK((c0 >= tl2) || (th2 != 0) || (c2 != 0)); \ + c1 += th2; /* overflow is handled on the next line */ \ + c2 += (c1 < th2) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ + VERIFY_CHECK((c1 >= th2) || (c2 != 0)); \ +} + +/** Add a to the number defined by (c0,c1,c2). c2 must never overflow. */ +#define sumadd(a) { \ + c0 += (a); /* overflow is handled on the next line */ \ + unsigned int over = (c0 < (a)) ? 1 : 0; \ + c1 += over; /* overflow is handled on the next line */ \ + c2 += (c1 < over) ? 1 : 0; /* never overflows by contract */ \ +} + +/** Add a to the number defined by (c0,c1). c1 must never overflow, c2 must be zero. */ +#define sumadd_fast(a) { \ + c0 += (a); /* overflow is handled on the next line */ \ + c1 += (c0 < (a)) ? 1 : 0; /* never overflows by contract (verified the next line) */ \ + VERIFY_CHECK((c1 != 0) | (c0 >= (a))); \ + VERIFY_CHECK(c2 == 0); \ +} + +/** Extract the lowest 32 bits of (c0,c1,c2) into n, and left shift the number 32 bits. */ +#define extract(n) { \ + (n) = c0; \ + c0 = c1; \ + c1 = c2; \ + c2 = 0; \ +} + +/** Extract the lowest 32 bits of (c0,c1,c2) into n, and left shift the number 32 bits. c2 is required to be zero. */ +#define extract_fast(n) { \ + (n) = c0; \ + c0 = c1; \ + c1 = 0; \ + VERIFY_CHECK(c2 == 0); \ +} + +static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint32_t *l) { + uint32_t n0 = l[8], n1 = l[9], n2 = l[10], n3 = l[11], n4 = l[12], n5 = l[13], n6 = l[14], n7 = l[15]; + + /* 96 bit accumulator. */ + uint32_t c0, c1, c2; + + /* Reduce 512 bits into 385. */ + /* m[0..12] = l[0..7] + n[0..7] * SECP256K1_N_C. */ + c0 = l[0]; c1 = 0; c2 = 0; + muladd_fast(n0, SECP256K1_N_C_0); + uint32_t m0; extract_fast(m0); + sumadd_fast(l[1]); + muladd(n1, SECP256K1_N_C_0); + muladd(n0, SECP256K1_N_C_1); + uint32_t m1; extract(m1); + sumadd(l[2]); + muladd(n2, SECP256K1_N_C_0); + muladd(n1, SECP256K1_N_C_1); + muladd(n0, SECP256K1_N_C_2); + uint32_t m2; extract(m2); + sumadd(l[3]); + muladd(n3, SECP256K1_N_C_0); + muladd(n2, SECP256K1_N_C_1); + muladd(n1, SECP256K1_N_C_2); + muladd(n0, SECP256K1_N_C_3); + uint32_t m3; extract(m3); + sumadd(l[4]); + muladd(n4, SECP256K1_N_C_0); + muladd(n3, SECP256K1_N_C_1); + muladd(n2, SECP256K1_N_C_2); + muladd(n1, SECP256K1_N_C_3); + sumadd(n0); + uint32_t m4; extract(m4); + sumadd(l[5]); + muladd(n5, SECP256K1_N_C_0); + muladd(n4, SECP256K1_N_C_1); + muladd(n3, SECP256K1_N_C_2); + muladd(n2, SECP256K1_N_C_3); + sumadd(n1); + uint32_t m5; extract(m5); + sumadd(l[6]); + muladd(n6, SECP256K1_N_C_0); + muladd(n5, SECP256K1_N_C_1); + muladd(n4, SECP256K1_N_C_2); + muladd(n3, SECP256K1_N_C_3); + sumadd(n2); + uint32_t m6; extract(m6); + sumadd(l[7]); + muladd(n7, SECP256K1_N_C_0); + muladd(n6, SECP256K1_N_C_1); + muladd(n5, SECP256K1_N_C_2); + muladd(n4, SECP256K1_N_C_3); + sumadd(n3); + uint32_t m7; extract(m7); + muladd(n7, SECP256K1_N_C_1); + muladd(n6, SECP256K1_N_C_2); + muladd(n5, SECP256K1_N_C_3); + sumadd(n4); + uint32_t m8; extract(m8); + muladd(n7, SECP256K1_N_C_2); + muladd(n6, SECP256K1_N_C_3); + sumadd(n5); + uint32_t m9; extract(m9); + muladd(n7, SECP256K1_N_C_3); + sumadd(n6); + uint32_t m10; extract(m10); + sumadd_fast(n7); + uint32_t m11; extract_fast(m11); + VERIFY_CHECK(c0 <= 1); + uint32_t m12 = c0; + + /* Reduce 385 bits into 258. */ + /* p[0..8] = m[0..7] + m[8..12] * SECP256K1_N_C. */ + c0 = m0; c1 = 0; c2 = 0; + muladd_fast(m8, SECP256K1_N_C_0); + uint32_t p0; extract_fast(p0); + sumadd_fast(m1); + muladd(m9, SECP256K1_N_C_0); + muladd(m8, SECP256K1_N_C_1); + uint32_t p1; extract(p1); + sumadd(m2); + muladd(m10, SECP256K1_N_C_0); + muladd(m9, SECP256K1_N_C_1); + muladd(m8, SECP256K1_N_C_2); + uint32_t p2; extract(p2); + sumadd(m3); + muladd(m11, SECP256K1_N_C_0); + muladd(m10, SECP256K1_N_C_1); + muladd(m9, SECP256K1_N_C_2); + muladd(m8, SECP256K1_N_C_3); + uint32_t p3; extract(p3); + sumadd(m4); + muladd(m12, SECP256K1_N_C_0); + muladd(m11, SECP256K1_N_C_1); + muladd(m10, SECP256K1_N_C_2); + muladd(m9, SECP256K1_N_C_3); + sumadd(m8); + uint32_t p4; extract(p4); + sumadd(m5); + muladd(m12, SECP256K1_N_C_1); + muladd(m11, SECP256K1_N_C_2); + muladd(m10, SECP256K1_N_C_3); + sumadd(m9); + uint32_t p5; extract(p5); + sumadd(m6); + muladd(m12, SECP256K1_N_C_2); + muladd(m11, SECP256K1_N_C_3); + sumadd(m10); + uint32_t p6; extract(p6); + sumadd_fast(m7); + muladd_fast(m12, SECP256K1_N_C_3); + sumadd_fast(m11); + uint32_t p7; extract_fast(p7); + uint32_t p8 = c0 + m12; + VERIFY_CHECK(p8 <= 2); + + /* Reduce 258 bits into 256. */ + /* r[0..7] = p[0..7] + p[8] * SECP256K1_N_C. */ + uint64_t c = p0 + (uint64_t)SECP256K1_N_C_0 * p8; + r->d[0] = c & 0xFFFFFFFFUL; c >>= 32; + c += p1 + (uint64_t)SECP256K1_N_C_1 * p8; + r->d[1] = c & 0xFFFFFFFFUL; c >>= 32; + c += p2 + (uint64_t)SECP256K1_N_C_2 * p8; + r->d[2] = c & 0xFFFFFFFFUL; c >>= 32; + c += p3 + (uint64_t)SECP256K1_N_C_3 * p8; + r->d[3] = c & 0xFFFFFFFFUL; c >>= 32; + c += p4 + (uint64_t)p8; + r->d[4] = c & 0xFFFFFFFFUL; c >>= 32; + c += p5; + r->d[5] = c & 0xFFFFFFFFUL; c >>= 32; + c += p6; + r->d[6] = c & 0xFFFFFFFFUL; c >>= 32; + c += p7; + r->d[7] = c & 0xFFFFFFFFUL; c >>= 32; + + /* Final reduction of r. */ + secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r)); +} + +static void secp256k1_scalar_mul_512(uint32_t l[16], const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { + /* 96 bit accumulator. */ + uint32_t c0 = 0, c1 = 0, c2 = 0; + + /* l[0..15] = a[0..7] * b[0..7]. */ + muladd_fast(a->d[0], b->d[0]); + extract_fast(l[0]); + muladd(a->d[0], b->d[1]); + muladd(a->d[1], b->d[0]); + extract(l[1]); + muladd(a->d[0], b->d[2]); + muladd(a->d[1], b->d[1]); + muladd(a->d[2], b->d[0]); + extract(l[2]); + muladd(a->d[0], b->d[3]); + muladd(a->d[1], b->d[2]); + muladd(a->d[2], b->d[1]); + muladd(a->d[3], b->d[0]); + extract(l[3]); + muladd(a->d[0], b->d[4]); + muladd(a->d[1], b->d[3]); + muladd(a->d[2], b->d[2]); + muladd(a->d[3], b->d[1]); + muladd(a->d[4], b->d[0]); + extract(l[4]); + muladd(a->d[0], b->d[5]); + muladd(a->d[1], b->d[4]); + muladd(a->d[2], b->d[3]); + muladd(a->d[3], b->d[2]); + muladd(a->d[4], b->d[1]); + muladd(a->d[5], b->d[0]); + extract(l[5]); + muladd(a->d[0], b->d[6]); + muladd(a->d[1], b->d[5]); + muladd(a->d[2], b->d[4]); + muladd(a->d[3], b->d[3]); + muladd(a->d[4], b->d[2]); + muladd(a->d[5], b->d[1]); + muladd(a->d[6], b->d[0]); + extract(l[6]); + muladd(a->d[0], b->d[7]); + muladd(a->d[1], b->d[6]); + muladd(a->d[2], b->d[5]); + muladd(a->d[3], b->d[4]); + muladd(a->d[4], b->d[3]); + muladd(a->d[5], b->d[2]); + muladd(a->d[6], b->d[1]); + muladd(a->d[7], b->d[0]); + extract(l[7]); + muladd(a->d[1], b->d[7]); + muladd(a->d[2], b->d[6]); + muladd(a->d[3], b->d[5]); + muladd(a->d[4], b->d[4]); + muladd(a->d[5], b->d[3]); + muladd(a->d[6], b->d[2]); + muladd(a->d[7], b->d[1]); + extract(l[8]); + muladd(a->d[2], b->d[7]); + muladd(a->d[3], b->d[6]); + muladd(a->d[4], b->d[5]); + muladd(a->d[5], b->d[4]); + muladd(a->d[6], b->d[3]); + muladd(a->d[7], b->d[2]); + extract(l[9]); + muladd(a->d[3], b->d[7]); + muladd(a->d[4], b->d[6]); + muladd(a->d[5], b->d[5]); + muladd(a->d[6], b->d[4]); + muladd(a->d[7], b->d[3]); + extract(l[10]); + muladd(a->d[4], b->d[7]); + muladd(a->d[5], b->d[6]); + muladd(a->d[6], b->d[5]); + muladd(a->d[7], b->d[4]); + extract(l[11]); + muladd(a->d[5], b->d[7]); + muladd(a->d[6], b->d[6]); + muladd(a->d[7], b->d[5]); + extract(l[12]); + muladd(a->d[6], b->d[7]); + muladd(a->d[7], b->d[6]); + extract(l[13]); + muladd_fast(a->d[7], b->d[7]); + extract_fast(l[14]); + VERIFY_CHECK(c1 == 0); + l[15] = c0; +} + +static void secp256k1_scalar_sqr_512(uint32_t l[16], const secp256k1_scalar_t *a) { + /* 96 bit accumulator. */ + uint32_t c0 = 0, c1 = 0, c2 = 0; + + /* l[0..15] = a[0..7]^2. */ + muladd_fast(a->d[0], a->d[0]); + extract_fast(l[0]); + muladd2(a->d[0], a->d[1]); + extract(l[1]); + muladd2(a->d[0], a->d[2]); + muladd(a->d[1], a->d[1]); + extract(l[2]); + muladd2(a->d[0], a->d[3]); + muladd2(a->d[1], a->d[2]); + extract(l[3]); + muladd2(a->d[0], a->d[4]); + muladd2(a->d[1], a->d[3]); + muladd(a->d[2], a->d[2]); + extract(l[4]); + muladd2(a->d[0], a->d[5]); + muladd2(a->d[1], a->d[4]); + muladd2(a->d[2], a->d[3]); + extract(l[5]); + muladd2(a->d[0], a->d[6]); + muladd2(a->d[1], a->d[5]); + muladd2(a->d[2], a->d[4]); + muladd(a->d[3], a->d[3]); + extract(l[6]); + muladd2(a->d[0], a->d[7]); + muladd2(a->d[1], a->d[6]); + muladd2(a->d[2], a->d[5]); + muladd2(a->d[3], a->d[4]); + extract(l[7]); + muladd2(a->d[1], a->d[7]); + muladd2(a->d[2], a->d[6]); + muladd2(a->d[3], a->d[5]); + muladd(a->d[4], a->d[4]); + extract(l[8]); + muladd2(a->d[2], a->d[7]); + muladd2(a->d[3], a->d[6]); + muladd2(a->d[4], a->d[5]); + extract(l[9]); + muladd2(a->d[3], a->d[7]); + muladd2(a->d[4], a->d[6]); + muladd(a->d[5], a->d[5]); + extract(l[10]); + muladd2(a->d[4], a->d[7]); + muladd2(a->d[5], a->d[6]); + extract(l[11]); + muladd2(a->d[5], a->d[7]); + muladd(a->d[6], a->d[6]); + extract(l[12]); + muladd2(a->d[6], a->d[7]); + extract(l[13]); + muladd_fast(a->d[7], a->d[7]); + extract_fast(l[14]); + VERIFY_CHECK(c1 == 0); + l[15] = c0; +} + +#undef sumadd +#undef sumadd_fast +#undef muladd +#undef muladd_fast +#undef muladd2 +#undef extract +#undef extract_fast + +static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { + uint32_t l[16]; + secp256k1_scalar_mul_512(l, a, b); + secp256k1_scalar_reduce_512(r, l); +} + +static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) { + uint32_t l[16]; + secp256k1_scalar_sqr_512(l, a); + secp256k1_scalar_reduce_512(r, l); +} + +static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) { + r1->d[0] = a->d[0]; + r1->d[1] = a->d[1]; + r1->d[2] = a->d[2]; + r1->d[3] = a->d[3]; + r1->d[4] = 0; + r1->d[5] = 0; + r1->d[6] = 0; + r1->d[7] = 0; + r2->d[0] = a->d[4]; + r2->d[1] = a->d[5]; + r2->d[2] = a->d[6]; + r2->d[3] = a->d[7]; + r2->d[4] = 0; + r2->d[5] = 0; + r2->d[6] = 0; + r2->d[7] = 0; +} + +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { + return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3]) | (a->d[4] ^ b->d[4]) | (a->d[5] ^ b->d[5]) | (a->d[6] ^ b->d[6]) | (a->d[7] ^ b->d[7])) == 0; +} + +SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift) { + VERIFY_CHECK(shift >= 256); + uint32_t l[16]; + secp256k1_scalar_mul_512(l, a, b); + unsigned int shiftlimbs = shift >> 5; + unsigned int shiftlow = shift & 0x1F; + unsigned int shifthigh = 32 - shiftlow; + r->d[0] = shift < 512 ? (l[0 + shiftlimbs] >> shiftlow | (shift < 480 && shiftlow ? (l[1 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[1] = shift < 480 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 448 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[2] = shift < 448 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 416 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[3] = shift < 416 ? (l[3 + shiftlimbs] >> shiftlow | (shift < 384 && shiftlow ? (l[4 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[4] = shift < 384 ? (l[4 + shiftlimbs] >> shiftlow | (shift < 352 && shiftlow ? (l[5 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[5] = shift < 352 ? (l[5 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[6 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[6] = shift < 320 ? (l[6 + shiftlimbs] >> shiftlow | (shift < 288 && shiftlow ? (l[7 + shiftlimbs] << shifthigh) : 0)) : 0; + r->d[7] = shift < 288 ? (l[7 + shiftlimbs] >> shiftlow) : 0; + if ((l[(shift - 1) >> 5] >> ((shift - 1) & 0x1f)) & 1) { + secp256k1_scalar_add_bit(r, 0); + } +} + +#endif diff --git a/src/secp256k1/src/scalar_impl.h b/src/secp256k1/src/scalar_impl.h new file mode 100644 index 0000000000..4408cce2d8 --- /dev/null +++ b/src/secp256k1/src/scalar_impl.h @@ -0,0 +1,336 @@ +/********************************************************************** + * Copyright (c) 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_SCALAR_IMPL_H_ +#define _SECP256K1_SCALAR_IMPL_H_ + +#include <string.h> + +#include "group.h" +#include "scalar.h" + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#if defined(USE_SCALAR_4X64) +#include "scalar_4x64_impl.h" +#elif defined(USE_SCALAR_8X32) +#include "scalar_8x32_impl.h" +#else +#error "Please select scalar implementation" +#endif + +typedef struct { +#ifndef USE_NUM_NONE + secp256k1_num_t order; +#endif +#ifdef USE_ENDOMORPHISM + secp256k1_scalar_t minus_lambda, minus_b1, minus_b2, g1, g2; +#endif +} secp256k1_scalar_consts_t; + +static const secp256k1_scalar_consts_t *secp256k1_scalar_consts = NULL; + +static void secp256k1_scalar_start(void) { + if (secp256k1_scalar_consts != NULL) + return; + + /* Allocate. */ + secp256k1_scalar_consts_t *ret = (secp256k1_scalar_consts_t*)checked_malloc(sizeof(secp256k1_scalar_consts_t)); + +#ifndef USE_NUM_NONE + static const unsigned char secp256k1_scalar_consts_order[] = { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, + 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, + 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 + }; + secp256k1_num_set_bin(&ret->order, secp256k1_scalar_consts_order, sizeof(secp256k1_scalar_consts_order)); +#endif +#ifdef USE_ENDOMORPHISM + /** + * Lambda is a scalar which has the property for secp256k1 that point multiplication by + * it is efficiently computable (see secp256k1_gej_mul_lambda). */ + static const unsigned char secp256k1_scalar_consts_lambda[32] = { + 0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0, + 0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a, + 0x12,0x2e,0x22,0xea,0x20,0x81,0x66,0x78, + 0xdf,0x02,0x96,0x7c,0x1b,0x23,0xbd,0x72 + }; + /** + * "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm + * (algorithm 3.74) to find k1 and k2 given k, such that k1 + k2 * lambda == k mod n, and k1 + * and k2 have a small size. + * It relies on constants a1, b1, a2, b2. These constants for the value of lambda above are: + * + * - a1 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} + * - b1 = -{0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3} + * - a2 = {0x01,0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8} + * - b2 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15} + * + * The algorithm then computes c1 = round(b1 * k / n) and c2 = round(b2 * k / n), and gives + * k1 = k - (c1*a1 + c2*a2) and k2 = -(c1*b1 + c2*b2). Instead, we use modular arithmetic, and + * compute k1 as k - k2 * lambda, avoiding the need for constants a1 and a2. + * + * g1, g2 are precomputed constants used to replace division with a rounded multiplication + * when decomposing the scalar for an endomorphism-based point multiplication. + * + * The possibility of using precomputed estimates is mentioned in "Guide to Elliptic Curve + * Cryptography" (Hankerson, Menezes, Vanstone) in section 3.5. + * + * The derivation is described in the paper "Efficient Software Implementation of Public-Key + * Cryptography on Sensor Networks Using the MSP430X Microcontroller" (Gouvea, Oliveira, Lopez), + * Section 4.3 (here we use a somewhat higher-precision estimate): + * d = a1*b2 - b1*a2 + * g1 = round((2^272)*b2/d) + * g2 = round((2^272)*b1/d) + * + * (Note that 'd' is also equal to the curve order here because [a1,b1] and [a2,b2] are found + * as outputs of the Extended Euclidean Algorithm on inputs 'order' and 'lambda'). + */ + static const unsigned char secp256k1_scalar_consts_minus_b1[32] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28, + 0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3 + }; + static const unsigned char secp256k1_scalar_consts_b2[32] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd, + 0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15 + }; + static const unsigned char secp256k1_scalar_consts_g1[32] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x86, + 0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c, + 0x90,0xe4,0x92,0x84,0xeb,0x15,0x3d,0xab + }; + static const unsigned char secp256k1_scalar_consts_g2[32] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x43, + 0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54, + 0x7f,0xa9,0x0a,0xbf,0xe4,0xc4,0x22,0x12 + }; + + secp256k1_scalar_set_b32(&ret->minus_lambda, secp256k1_scalar_consts_lambda, NULL); + secp256k1_scalar_negate(&ret->minus_lambda, &ret->minus_lambda); + secp256k1_scalar_set_b32(&ret->minus_b1, secp256k1_scalar_consts_minus_b1, NULL); + secp256k1_scalar_set_b32(&ret->minus_b2, secp256k1_scalar_consts_b2, NULL); + secp256k1_scalar_negate(&ret->minus_b2, &ret->minus_b2); + secp256k1_scalar_set_b32(&ret->g1, secp256k1_scalar_consts_g1, NULL); + secp256k1_scalar_set_b32(&ret->g2, secp256k1_scalar_consts_g2, NULL); +#endif + + /* Set the global pointer. */ + secp256k1_scalar_consts = ret; +} + +static void secp256k1_scalar_stop(void) { + if (secp256k1_scalar_consts == NULL) + return; + + secp256k1_scalar_consts_t *c = (secp256k1_scalar_consts_t*)secp256k1_scalar_consts; + secp256k1_scalar_consts = NULL; + free(c); +} + +#ifndef USE_NUM_NONE +static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a) { + unsigned char c[32]; + secp256k1_scalar_get_b32(c, a); + secp256k1_num_set_bin(r, c, 32); +} + +static void secp256k1_scalar_order_get_num(secp256k1_num_t *r) { + *r = secp256k1_scalar_consts->order; +} +#endif + +static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scalar_t *x) { + /* First compute x ^ (2^N - 1) for some values of N. */ + secp256k1_scalar_t x2, x3, x4, x6, x7, x8, x15, x30, x60, x120, x127; + + secp256k1_scalar_sqr(&x2, x); + secp256k1_scalar_mul(&x2, &x2, x); + + secp256k1_scalar_sqr(&x3, &x2); + secp256k1_scalar_mul(&x3, &x3, x); + + secp256k1_scalar_sqr(&x4, &x3); + secp256k1_scalar_mul(&x4, &x4, x); + + secp256k1_scalar_sqr(&x6, &x4); + secp256k1_scalar_sqr(&x6, &x6); + secp256k1_scalar_mul(&x6, &x6, &x2); + + secp256k1_scalar_sqr(&x7, &x6); + secp256k1_scalar_mul(&x7, &x7, x); + + secp256k1_scalar_sqr(&x8, &x7); + secp256k1_scalar_mul(&x8, &x8, x); + + secp256k1_scalar_sqr(&x15, &x8); + for (int i=0; i<6; i++) + secp256k1_scalar_sqr(&x15, &x15); + secp256k1_scalar_mul(&x15, &x15, &x7); + + secp256k1_scalar_sqr(&x30, &x15); + for (int i=0; i<14; i++) + secp256k1_scalar_sqr(&x30, &x30); + secp256k1_scalar_mul(&x30, &x30, &x15); + + secp256k1_scalar_sqr(&x60, &x30); + for (int i=0; i<29; i++) + secp256k1_scalar_sqr(&x60, &x60); + secp256k1_scalar_mul(&x60, &x60, &x30); + + secp256k1_scalar_sqr(&x120, &x60); + for (int i=0; i<59; i++) + secp256k1_scalar_sqr(&x120, &x120); + secp256k1_scalar_mul(&x120, &x120, &x60); + + secp256k1_scalar_sqr(&x127, &x120); + for (int 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). */ + secp256k1_scalar_t *t = &x127; + for (int i=0; i<2; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<4; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x3); /* 111 */ + for (int i=0; i<2; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<2; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<2; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<4; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x3); /* 111 */ + for (int i=0; i<3; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x2); /* 11 */ + for (int i=0; i<4; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x3); /* 111 */ + for (int i=0; i<5; i++) /* 00 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x3); /* 111 */ + for (int i=0; i<4; i++) /* 00 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x2); /* 11 */ + for (int i=0; i<2; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<2; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<5; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x4); /* 1111 */ + for (int i=0; i<2; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<3; i++) /* 00 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<4; i++) /* 000 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<2; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<10; i++) /* 0000000 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x3); /* 111 */ + for (int i=0; i<4; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x3); /* 111 */ + for (int i=0; i<9; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x8); /* 11111111 */ + for (int i=0; i<2; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<3; i++) /* 00 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<3; i++) /* 00 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<5; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x4); /* 1111 */ + for (int i=0; i<2; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<5; i++) /* 000 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x2); /* 11 */ + for (int i=0; i<4; i++) /* 00 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x2); /* 11 */ + for (int i=0; i<2; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<8; i++) /* 000000 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x2); /* 11 */ + for (int i=0; i<3; i++) /* 0 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, &x2); /* 11 */ + for (int i=0; i<3; i++) /* 00 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<6; i++) /* 00000 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(t, t, x); /* 1 */ + for (int i=0; i<8; i++) /* 00 */ + secp256k1_scalar_sqr(t, t); + secp256k1_scalar_mul(r, t, &x6); /* 111111 */ +} + +static void secp256k1_scalar_inverse_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *x) { +#if defined(USE_SCALAR_INV_BUILTIN) + secp256k1_scalar_inverse(r, x); +#elif defined(USE_SCALAR_INV_NUM) + unsigned char b[32]; + secp256k1_scalar_get_b32(b, x); + secp256k1_num_t n; + secp256k1_num_set_bin(&n, b, 32); + secp256k1_num_mod_inverse(&n, &n, &secp256k1_scalar_consts->order); + secp256k1_num_get_bin(b, 32, &n); + secp256k1_scalar_set_b32(r, b, NULL); +#else +#error "Please select scalar inverse implementation" +#endif +} + +#ifdef USE_ENDOMORPHISM +static void secp256k1_scalar_split_lambda_var(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) { + VERIFY_CHECK(r1 != a); + VERIFY_CHECK(r2 != a); + secp256k1_scalar_t c1, c2; + secp256k1_scalar_mul_shift_var(&c1, a, &secp256k1_scalar_consts->g1, 272); + secp256k1_scalar_mul_shift_var(&c2, a, &secp256k1_scalar_consts->g2, 272); + secp256k1_scalar_mul(&c1, &c1, &secp256k1_scalar_consts->minus_b1); + secp256k1_scalar_mul(&c2, &c2, &secp256k1_scalar_consts->minus_b2); + secp256k1_scalar_add(r2, &c1, &c2); + secp256k1_scalar_mul(r1, r2, &secp256k1_scalar_consts->minus_lambda); + secp256k1_scalar_add(r1, r1, a); +} +#endif + +#endif diff --git a/src/secp256k1/src/secp256k1.c b/src/secp256k1/src/secp256k1.c new file mode 100644 index 0000000000..0328db88fc --- /dev/null +++ b/src/secp256k1/src/secp256k1.c @@ -0,0 +1,310 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#define SECP256K1_BUILD (1) + +#include "include/secp256k1.h" + +#include "util.h" +#include "num_impl.h" +#include "field_impl.h" +#include "scalar_impl.h" +#include "group_impl.h" +#include "ecmult_impl.h" +#include "ecmult_gen_impl.h" +#include "ecdsa_impl.h" +#include "eckey_impl.h" + +void secp256k1_start(unsigned int flags) { + secp256k1_fe_start(); + secp256k1_ge_start(); + secp256k1_scalar_start(); + secp256k1_ecdsa_start(); + if (flags & SECP256K1_START_SIGN) { + secp256k1_ecmult_gen_start(); + } + if (flags & SECP256K1_START_VERIFY) { + secp256k1_ecmult_start(); + } +} + +void secp256k1_stop(void) { + secp256k1_ecmult_stop(); + secp256k1_ecmult_gen_stop(); + secp256k1_ecdsa_stop(); + secp256k1_scalar_stop(); + secp256k1_ge_stop(); + secp256k1_fe_stop(); +} + +int secp256k1_ecdsa_verify(const unsigned char *msg32, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) { + DEBUG_CHECK(secp256k1_ecmult_consts != NULL); + DEBUG_CHECK(msg32 != NULL); + DEBUG_CHECK(sig != NULL); + DEBUG_CHECK(pubkey != NULL); + + int ret = -3; + secp256k1_scalar_t m; + secp256k1_ecdsa_sig_t s; + secp256k1_ge_t q; + secp256k1_scalar_set_b32(&m, msg32, NULL); + + if (!secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen)) { + ret = -1; + goto end; + } + if (!secp256k1_ecdsa_sig_parse(&s, sig, siglen)) { + ret = -2; + goto end; + } + if (!secp256k1_ecdsa_sig_verify(&s, &q, &m)) { + ret = 0; + goto end; + } + ret = 1; +end: + return ret; +} + +int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, const unsigned char *nonce) { + DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL); + DEBUG_CHECK(msg32 != NULL); + DEBUG_CHECK(signature != NULL); + DEBUG_CHECK(signaturelen != NULL); + DEBUG_CHECK(seckey != NULL); + DEBUG_CHECK(nonce != NULL); + + secp256k1_scalar_t sec, non, msg; + secp256k1_scalar_set_b32(&sec, seckey, NULL); + int overflow = 0; + secp256k1_scalar_set_b32(&non, nonce, &overflow); + secp256k1_scalar_set_b32(&msg, msg32, NULL); + int ret = !secp256k1_scalar_is_zero(&non) && !overflow; + secp256k1_ecdsa_sig_t sig; + if (ret) { + ret = secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, NULL); + } + if (ret) { + secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig); + } + secp256k1_scalar_clear(&msg); + secp256k1_scalar_clear(&non); + secp256k1_scalar_clear(&sec); + return ret; +} + +int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, const unsigned char *nonce, int *recid) { + DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL); + DEBUG_CHECK(msg32 != NULL); + DEBUG_CHECK(sig64 != NULL); + DEBUG_CHECK(seckey != NULL); + DEBUG_CHECK(nonce != NULL); + + secp256k1_scalar_t sec, non, msg; + secp256k1_scalar_set_b32(&sec, seckey, NULL); + int overflow = 0; + secp256k1_scalar_set_b32(&non, nonce, &overflow); + secp256k1_scalar_set_b32(&msg, msg32, NULL); + int ret = !secp256k1_scalar_is_zero(&non) && !overflow; + secp256k1_ecdsa_sig_t sig; + if (ret) { + ret = secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid); + } + if (ret) { + secp256k1_scalar_get_b32(sig64, &sig.r); + secp256k1_scalar_get_b32(sig64 + 32, &sig.s); + } + secp256k1_scalar_clear(&msg); + secp256k1_scalar_clear(&non); + secp256k1_scalar_clear(&sec); + return ret; +} + +int secp256k1_ecdsa_recover_compact(const unsigned char *msg32, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) { + DEBUG_CHECK(secp256k1_ecmult_consts != NULL); + DEBUG_CHECK(msg32 != NULL); + DEBUG_CHECK(sig64 != NULL); + DEBUG_CHECK(pubkey != NULL); + DEBUG_CHECK(pubkeylen != NULL); + DEBUG_CHECK(recid >= 0 && recid <= 3); + + int ret = 0; + secp256k1_scalar_t m; + secp256k1_ecdsa_sig_t sig; + int overflow = 0; + secp256k1_scalar_set_b32(&sig.r, sig64, &overflow); + if (overflow) { + return 0; + } + secp256k1_scalar_set_b32(&sig.s, sig64 + 32, &overflow); + if (overflow) { + return 0; + } + secp256k1_scalar_set_b32(&m, msg32, NULL); + + secp256k1_ge_t q; + if (secp256k1_ecdsa_sig_recover(&sig, &q, &m, recid)) { + ret = secp256k1_eckey_pubkey_serialize(&q, pubkey, pubkeylen, compressed); + } + return ret; +} + +int secp256k1_ec_seckey_verify(const unsigned char *seckey) { + DEBUG_CHECK(seckey != NULL); + + secp256k1_scalar_t sec; + int overflow; + secp256k1_scalar_set_b32(&sec, seckey, &overflow); + int ret = !secp256k1_scalar_is_zero(&sec) && !overflow; + secp256k1_scalar_clear(&sec); + return ret; +} + +int secp256k1_ec_pubkey_verify(const unsigned char *pubkey, int pubkeylen) { + DEBUG_CHECK(pubkey != NULL); + + secp256k1_ge_t q; + return secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen); +} + +int secp256k1_ec_pubkey_create(unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed) { + DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL); + DEBUG_CHECK(pubkey != NULL); + DEBUG_CHECK(pubkeylen != NULL); + DEBUG_CHECK(seckey != NULL); + + secp256k1_scalar_t sec; + secp256k1_scalar_set_b32(&sec, seckey, NULL); + secp256k1_gej_t pj; + secp256k1_ecmult_gen(&pj, &sec); + secp256k1_scalar_clear(&sec); + secp256k1_ge_t p; + secp256k1_ge_set_gej(&p, &pj); + return secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, compressed); +} + +int secp256k1_ec_pubkey_decompress(unsigned char *pubkey, int *pubkeylen) { + DEBUG_CHECK(pubkey != NULL); + DEBUG_CHECK(pubkeylen != NULL); + + secp256k1_ge_t p; + if (!secp256k1_eckey_pubkey_parse(&p, pubkey, *pubkeylen)) + return 0; + return secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, 0); +} + +int secp256k1_ec_privkey_tweak_add(unsigned char *seckey, const unsigned char *tweak) { + DEBUG_CHECK(seckey != NULL); + DEBUG_CHECK(tweak != NULL); + + secp256k1_scalar_t term; + int overflow = 0; + secp256k1_scalar_set_b32(&term, tweak, &overflow); + secp256k1_scalar_t sec; + secp256k1_scalar_set_b32(&sec, seckey, NULL); + + int ret = secp256k1_eckey_privkey_tweak_add(&sec, &term) && !overflow; + if (ret) { + secp256k1_scalar_get_b32(seckey, &sec); + } + + secp256k1_scalar_clear(&sec); + secp256k1_scalar_clear(&term); + return ret; +} + +int secp256k1_ec_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { + DEBUG_CHECK(secp256k1_ecmult_consts != NULL); + DEBUG_CHECK(pubkey != NULL); + DEBUG_CHECK(tweak != NULL); + + secp256k1_scalar_t term; + int overflow = 0; + secp256k1_scalar_set_b32(&term, tweak, &overflow); + if (overflow) { + return 0; + } + secp256k1_ge_t p; + int ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); + if (ret) { + ret = secp256k1_eckey_pubkey_tweak_add(&p, &term); + } + if (ret) { + int oldlen = pubkeylen; + ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); + VERIFY_CHECK(pubkeylen == oldlen); + } + + return ret; +} + +int secp256k1_ec_privkey_tweak_mul(unsigned char *seckey, const unsigned char *tweak) { + DEBUG_CHECK(seckey != NULL); + DEBUG_CHECK(tweak != NULL); + + secp256k1_scalar_t factor; + int overflow = 0; + secp256k1_scalar_set_b32(&factor, tweak, &overflow); + secp256k1_scalar_t sec; + secp256k1_scalar_set_b32(&sec, seckey, NULL); + int ret = secp256k1_eckey_privkey_tweak_mul(&sec, &factor) && !overflow; + if (ret) { + secp256k1_scalar_get_b32(seckey, &sec); + } + + secp256k1_scalar_clear(&sec); + secp256k1_scalar_clear(&factor); + return ret; +} + +int secp256k1_ec_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { + DEBUG_CHECK(secp256k1_ecmult_consts != NULL); + DEBUG_CHECK(pubkey != NULL); + DEBUG_CHECK(tweak != NULL); + + secp256k1_scalar_t factor; + int overflow = 0; + secp256k1_scalar_set_b32(&factor, tweak, &overflow); + if (overflow) { + return 0; + } + secp256k1_ge_t p; + int ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); + if (ret) { + ret = secp256k1_eckey_pubkey_tweak_mul(&p, &factor); + } + if (ret) { + int oldlen = pubkeylen; + ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); + VERIFY_CHECK(pubkeylen == oldlen); + } + + return ret; +} + +int secp256k1_ec_privkey_export(const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed) { + DEBUG_CHECK(seckey != NULL); + DEBUG_CHECK(privkey != NULL); + DEBUG_CHECK(privkeylen != NULL); + + secp256k1_scalar_t key; + secp256k1_scalar_set_b32(&key, seckey, NULL); + int ret = secp256k1_eckey_privkey_serialize(privkey, privkeylen, &key, compressed); + secp256k1_scalar_clear(&key); + return ret; +} + +int secp256k1_ec_privkey_import(unsigned char *seckey, const unsigned char *privkey, int privkeylen) { + DEBUG_CHECK(seckey != NULL); + DEBUG_CHECK(privkey != NULL); + + secp256k1_scalar_t key; + int ret = secp256k1_eckey_privkey_parse(&key, privkey, privkeylen); + if (ret) + secp256k1_scalar_get_b32(seckey, &key); + secp256k1_scalar_clear(&key); + return ret; +} diff --git a/src/secp256k1/src/testrand.h b/src/secp256k1/src/testrand.h new file mode 100644 index 0000000000..018b65cd53 --- /dev/null +++ b/src/secp256k1/src/testrand.h @@ -0,0 +1,26 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_TESTRAND_H_ +#define _SECP256K1_TESTRAND_H_ + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +/** Seed the pseudorandom number generator. */ +SECP256K1_INLINE static void secp256k1_rand_seed(uint64_t v); + +/** Generate a pseudorandom 32-bit number. */ +static uint32_t secp256k1_rand32(void); + +/** Generate a pseudorandom 32-byte array. */ +static void secp256k1_rand256(unsigned char *b32); + +/** Generate a pseudorandom 32-byte array with long sequences of zero and one bits. */ +static void secp256k1_rand256_test(unsigned char *b32); + +#endif diff --git a/src/secp256k1/src/testrand_impl.h b/src/secp256k1/src/testrand_impl.h new file mode 100644 index 0000000000..677c4b9a0e --- /dev/null +++ b/src/secp256k1/src/testrand_impl.h @@ -0,0 +1,60 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_TESTRAND_IMPL_H_ +#define _SECP256K1_TESTRAND_IMPL_H_ + +#include <stdint.h> +#include <string.h> + +#include "testrand.h" + +static uint32_t secp256k1_Rz = 11, secp256k1_Rw = 11; + +SECP256K1_INLINE static void secp256k1_rand_seed(uint64_t v) { + secp256k1_Rz = v >> 32; + secp256k1_Rw = v; + + if (secp256k1_Rz == 0 || secp256k1_Rz == 0x9068ffffU) { + secp256k1_Rz = 111; + } + if (secp256k1_Rw == 0 || secp256k1_Rw == 0x464fffffU) { + secp256k1_Rw = 111; + } +} + +SECP256K1_INLINE static uint32_t secp256k1_rand32(void) { + secp256k1_Rz = 36969 * (secp256k1_Rz & 0xFFFF) + (secp256k1_Rz >> 16); + secp256k1_Rw = 18000 * (secp256k1_Rw & 0xFFFF) + (secp256k1_Rw >> 16); + return (secp256k1_Rw << 16) + (secp256k1_Rw >> 16) + secp256k1_Rz; +} + +static void secp256k1_rand256(unsigned char *b32) { + for (int i=0; i<8; i++) { + uint32_t r = secp256k1_rand32(); + b32[i*4 + 0] = (r >> 0) & 0xFF; + b32[i*4 + 1] = (r >> 8) & 0xFF; + b32[i*4 + 2] = (r >> 16) & 0xFF; + b32[i*4 + 3] = (r >> 24) & 0xFF; + } +} + +static void secp256k1_rand256_test(unsigned char *b32) { + int bits=0; + memset(b32, 0, 32); + while (bits < 256) { + uint32_t ent = secp256k1_rand32(); + int now = 1 + ((ent % 64)*((ent >> 6) % 32)+16)/31; + uint32_t val = 1 & (ent >> 11); + while (now > 0 && bits < 256) { + b32[bits / 8] |= val << (bits % 8); + now--; + bits++; + } + } +} + +#endif diff --git a/src/secp256k1/src/tests.c b/src/secp256k1/src/tests.c new file mode 100644 index 0000000000..7ebb19ff99 --- /dev/null +++ b/src/secp256k1/src/tests.c @@ -0,0 +1,1455 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> + +#include <time.h> + +#include "secp256k1.c" +#include "testrand_impl.h" + +#ifdef ENABLE_OPENSSL_TESTS +#include "openssl/bn.h" +#include "openssl/ec.h" +#include "openssl/ecdsa.h" +#include "openssl/obj_mac.h" +#endif + +static int count = 64; + +void random_field_element_test(secp256k1_fe_t *fe) { + do { + unsigned char b32[32]; + secp256k1_rand256_test(b32); + if (secp256k1_fe_set_b32(fe, b32)) { + break; + } + } while(1); +} + +void random_field_element_magnitude(secp256k1_fe_t *fe) { + secp256k1_fe_normalize(fe); + int n = secp256k1_rand32() % 4; + for (int i = 0; i < n; i++) { + secp256k1_fe_negate(fe, fe, 1 + 2*i); + secp256k1_fe_negate(fe, fe, 2 + 2*i); + } +} + +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)) + break; + } while(1); +} + +void random_group_element_jacobian_test(secp256k1_gej_t *gej, const secp256k1_ge_t *ge) { + do { + random_field_element_test(&gej->z); + if (!secp256k1_fe_is_zero(&gej->z)) { + break; + } + } while(1); + secp256k1_fe_t z2; secp256k1_fe_sqr(&z2, &gej->z); + secp256k1_fe_t z3; secp256k1_fe_mul(&z3, &z2, &gej->z); + secp256k1_fe_mul(&gej->x, &ge->x, &z2); + secp256k1_fe_mul(&gej->y, &ge->y, &z3); + gej->infinity = ge->infinity; +} + +void random_scalar_order_test(secp256k1_scalar_t *num) { + do { + unsigned char b32[32]; + secp256k1_rand256_test(b32); + int overflow = 0; + secp256k1_scalar_set_b32(num, b32, &overflow); + if (overflow || secp256k1_scalar_is_zero(num)) + continue; + break; + } while(1); +} + +void random_scalar_order(secp256k1_scalar_t *num) { + do { + unsigned char b32[32]; + secp256k1_rand256(b32); + int overflow = 0; + secp256k1_scalar_set_b32(num, b32, &overflow); + if (overflow || secp256k1_scalar_is_zero(num)) + continue; + break; + } while(1); +} + +/***** NUM TESTS *****/ + +#ifndef USE_NUM_NONE +void random_num_negate(secp256k1_num_t *num) { + if (secp256k1_rand32() & 1) + secp256k1_num_negate(num); +} + +void random_num_order_test(secp256k1_num_t *num) { + secp256k1_scalar_t sc; + random_scalar_order_test(&sc); + secp256k1_scalar_get_num(num, &sc); +} + +void random_num_order(secp256k1_num_t *num) { + secp256k1_scalar_t sc; + random_scalar_order(&sc); + secp256k1_scalar_get_num(num, &sc); +} + +void test_num_negate(void) { + secp256k1_num_t n1; + secp256k1_num_t n2; + random_num_order_test(&n1); /* n1 = R */ + random_num_negate(&n1); + secp256k1_num_copy(&n2, &n1); /* n2 = R */ + secp256k1_num_sub(&n1, &n2, &n1); /* n1 = n2-n1 = 0 */ + CHECK(secp256k1_num_is_zero(&n1)); + secp256k1_num_copy(&n1, &n2); /* n1 = R */ + secp256k1_num_negate(&n1); /* n1 = -R */ + CHECK(!secp256k1_num_is_zero(&n1)); + secp256k1_num_add(&n1, &n2, &n1); /* n1 = n2+n1 = 0 */ + CHECK(secp256k1_num_is_zero(&n1)); + secp256k1_num_copy(&n1, &n2); /* n1 = R */ + secp256k1_num_negate(&n1); /* n1 = -R */ + CHECK(secp256k1_num_is_neg(&n1) != secp256k1_num_is_neg(&n2)); + secp256k1_num_negate(&n1); /* n1 = R */ + CHECK(secp256k1_num_eq(&n1, &n2)); +} + +void test_num_add_sub(void) { + int r = secp256k1_rand32(); + secp256k1_num_t n1; + secp256k1_num_t n2; + random_num_order_test(&n1); /* n1 = R1 */ + if (r & 1) { + random_num_negate(&n1); + } + random_num_order_test(&n2); /* n2 = R2 */ + if (r & 2) { + random_num_negate(&n2); + } + secp256k1_num_t n1p2, n2p1, n1m2, n2m1; + secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = R1 + R2 */ + secp256k1_num_add(&n2p1, &n2, &n1); /* n2p1 = R2 + R1 */ + secp256k1_num_sub(&n1m2, &n1, &n2); /* n1m2 = R1 - R2 */ + secp256k1_num_sub(&n2m1, &n2, &n1); /* n2m1 = R2 - R1 */ + CHECK(secp256k1_num_eq(&n1p2, &n2p1)); + CHECK(!secp256k1_num_eq(&n1p2, &n1m2)); + secp256k1_num_negate(&n2m1); /* n2m1 = -R2 + R1 */ + CHECK(secp256k1_num_eq(&n2m1, &n1m2)); + CHECK(!secp256k1_num_eq(&n2m1, &n1)); + secp256k1_num_add(&n2m1, &n2m1, &n2); /* n2m1 = -R2 + R1 + R2 = R1 */ + CHECK(secp256k1_num_eq(&n2m1, &n1)); + CHECK(!secp256k1_num_eq(&n2p1, &n1)); + secp256k1_num_sub(&n2p1, &n2p1, &n2); /* n2p1 = R2 + R1 - R2 = R1 */ + CHECK(secp256k1_num_eq(&n2p1, &n1)); +} + +void run_num_smalltests(void) { + for (int i=0; i<100*count; i++) { + test_num_negate(); + test_num_add_sub(); + } +} +#endif + +/***** SCALAR TESTS *****/ + +void scalar_test(void) { + unsigned char c[32]; + + /* Set 's' to a random scalar, with value 'snum'. */ + secp256k1_scalar_t s; + random_scalar_order_test(&s); + + /* Set 's1' to a random scalar, with value 's1num'. */ + secp256k1_scalar_t s1; + random_scalar_order_test(&s1); + + /* Set 's2' to a random scalar, with value 'snum2', and byte array representation 'c'. */ + secp256k1_scalar_t s2; + random_scalar_order_test(&s2); + secp256k1_scalar_get_b32(c, &s2); + +#ifndef USE_NUM_NONE + secp256k1_num_t snum, s1num, s2num; + secp256k1_scalar_get_num(&snum, &s); + secp256k1_scalar_get_num(&s1num, &s1); + secp256k1_scalar_get_num(&s2num, &s2); + + secp256k1_num_t order; + secp256k1_scalar_order_get_num(&order); + secp256k1_num_t half_order = order; + secp256k1_num_shift(&half_order, 1); +#endif + + { + /* Test that fetching groups of 4 bits from a scalar and recursing n(i)=16*n(i-1)+p(i) reconstructs it. */ + secp256k1_scalar_t n; + secp256k1_scalar_set_int(&n, 0); + for (int i = 0; i < 256; i += 4) { + secp256k1_scalar_t t; + secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits(&s, 256 - 4 - i, 4)); + for (int j = 0; j < 4; j++) { + secp256k1_scalar_add(&n, &n, &n); + } + secp256k1_scalar_add(&n, &n, &t); + } + CHECK(secp256k1_scalar_eq(&n, &s)); + } + + { + /* Test that fetching groups of randomly-sized bits from a scalar and recursing n(i)=b*n(i-1)+p(i) reconstructs it. */ + secp256k1_scalar_t n; + secp256k1_scalar_set_int(&n, 0); + int i = 0; + while (i < 256) { + int now = (secp256k1_rand32() % 15) + 1; + if (now + i > 256) { + now = 256 - i; + } + secp256k1_scalar_t t; + secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits_var(&s, 256 - now - i, now)); + for (int j = 0; j < now; j++) { + secp256k1_scalar_add(&n, &n, &n); + } + secp256k1_scalar_add(&n, &n, &t); + i += now; + } + CHECK(secp256k1_scalar_eq(&n, &s)); + } + +#ifndef USE_NUM_NONE + { + /* Test that adding the scalars together is equal to adding their numbers together modulo the order. */ + secp256k1_num_t rnum; + secp256k1_num_add(&rnum, &snum, &s2num); + secp256k1_num_mod(&rnum, &order); + secp256k1_scalar_t r; + secp256k1_scalar_add(&r, &s, &s2); + secp256k1_num_t r2num; + secp256k1_scalar_get_num(&r2num, &r); + CHECK(secp256k1_num_eq(&rnum, &r2num)); + } + + { + /* Test that multipying the scalars is equal to multiplying their numbers modulo the order. */ + secp256k1_num_t rnum; + secp256k1_num_mul(&rnum, &snum, &s2num); + secp256k1_num_mod(&rnum, &order); + secp256k1_scalar_t r; + secp256k1_scalar_mul(&r, &s, &s2); + secp256k1_num_t r2num; + secp256k1_scalar_get_num(&r2num, &r); + CHECK(secp256k1_num_eq(&rnum, &r2num)); + /* The result can only be zero if at least one of the factors was zero. */ + CHECK(secp256k1_scalar_is_zero(&r) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_zero(&s2))); + /* The results can only be equal to one of the factors if that factor was zero, or the other factor was one. */ + CHECK(secp256k1_num_eq(&rnum, &snum) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_one(&s2))); + CHECK(secp256k1_num_eq(&rnum, &s2num) == (secp256k1_scalar_is_zero(&s2) || secp256k1_scalar_is_one(&s))); + } + + { + /* Check that comparison with zero matches comparison with zero on the number. */ + CHECK(secp256k1_num_is_zero(&snum) == secp256k1_scalar_is_zero(&s)); + /* Check that comparison with the half order is equal to testing for high scalar. */ + CHECK(secp256k1_scalar_is_high(&s) == (secp256k1_num_cmp(&snum, &half_order) > 0)); + secp256k1_scalar_t neg; + secp256k1_scalar_negate(&neg, &s); + secp256k1_num_t negnum; + secp256k1_num_sub(&negnum, &order, &snum); + secp256k1_num_mod(&negnum, &order); + /* Check that comparison with the half order is equal to testing for high scalar after negation. */ + CHECK(secp256k1_scalar_is_high(&neg) == (secp256k1_num_cmp(&negnum, &half_order) > 0)); + /* Negating should change the high property, unless the value was already zero. */ + CHECK((secp256k1_scalar_is_high(&s) == secp256k1_scalar_is_high(&neg)) == secp256k1_scalar_is_zero(&s)); + secp256k1_num_t negnum2; + secp256k1_scalar_get_num(&negnum2, &neg); + /* Negating a scalar should be equal to (order - n) mod order on the number. */ + CHECK(secp256k1_num_eq(&negnum, &negnum2)); + secp256k1_scalar_add(&neg, &neg, &s); + /* Adding a number to its negation should result in zero. */ + CHECK(secp256k1_scalar_is_zero(&neg)); + secp256k1_scalar_negate(&neg, &neg); + /* Negating zero should still result in zero. */ + CHECK(secp256k1_scalar_is_zero(&neg)); + } + + { + /* Test secp256k1_scalar_mul_shift_var. */ + secp256k1_scalar_t r; + unsigned int shift = 256 + (secp256k1_rand32() % 257); + secp256k1_scalar_mul_shift_var(&r, &s1, &s2, shift); + secp256k1_num_t rnum; + secp256k1_num_mul(&rnum, &s1num, &s2num); + secp256k1_num_shift(&rnum, shift - 1); + secp256k1_num_t one; + unsigned char cone[1] = {0x01}; + secp256k1_num_set_bin(&one, cone, 1); + secp256k1_num_add(&rnum, &rnum, &one); + secp256k1_num_shift(&rnum, 1); + secp256k1_num_t rnum2; + secp256k1_scalar_get_num(&rnum2, &r); + CHECK(secp256k1_num_eq(&rnum, &rnum2)); + } +#endif + + { + /* Test that scalar inverses are equal to the inverse of their number modulo the order. */ + if (!secp256k1_scalar_is_zero(&s)) { + secp256k1_scalar_t inv; + secp256k1_scalar_inverse(&inv, &s); +#ifndef USE_NUM_NONE + secp256k1_num_t invnum; + secp256k1_num_mod_inverse(&invnum, &snum, &order); + secp256k1_num_t invnum2; + secp256k1_scalar_get_num(&invnum2, &inv); + CHECK(secp256k1_num_eq(&invnum, &invnum2)); +#endif + secp256k1_scalar_mul(&inv, &inv, &s); + /* Multiplying a scalar with its inverse must result in one. */ + CHECK(secp256k1_scalar_is_one(&inv)); + secp256k1_scalar_inverse(&inv, &inv); + /* Inverting one must result in one. */ + CHECK(secp256k1_scalar_is_one(&inv)); + } + } + + { + /* Test commutativity of add. */ + secp256k1_scalar_t r1, r2; + secp256k1_scalar_add(&r1, &s1, &s2); + secp256k1_scalar_add(&r2, &s2, &s1); + CHECK(secp256k1_scalar_eq(&r1, &r2)); + } + + { + /* Test add_bit. */ + int bit = secp256k1_rand32() % 256; + secp256k1_scalar_t b; + secp256k1_scalar_set_int(&b, 1); + CHECK(secp256k1_scalar_is_one(&b)); + for (int i = 0; i < bit; i++) { + secp256k1_scalar_add(&b, &b, &b); + } + secp256k1_scalar_t r1 = s1, r2 = s1; + if (!secp256k1_scalar_add(&r1, &r1, &b)) { + /* No overflow happened. */ + secp256k1_scalar_add_bit(&r2, bit); + CHECK(secp256k1_scalar_eq(&r1, &r2)); + } + } + + { + /* Test commutativity of mul. */ + secp256k1_scalar_t r1, r2; + secp256k1_scalar_mul(&r1, &s1, &s2); + secp256k1_scalar_mul(&r2, &s2, &s1); + CHECK(secp256k1_scalar_eq(&r1, &r2)); + } + + { + /* Test associativity of add. */ + secp256k1_scalar_t r1, r2; + secp256k1_scalar_add(&r1, &s1, &s2); + secp256k1_scalar_add(&r1, &r1, &s); + secp256k1_scalar_add(&r2, &s2, &s); + secp256k1_scalar_add(&r2, &s1, &r2); + CHECK(secp256k1_scalar_eq(&r1, &r2)); + } + + { + /* Test associativity of mul. */ + secp256k1_scalar_t r1, r2; + secp256k1_scalar_mul(&r1, &s1, &s2); + secp256k1_scalar_mul(&r1, &r1, &s); + secp256k1_scalar_mul(&r2, &s2, &s); + secp256k1_scalar_mul(&r2, &s1, &r2); + CHECK(secp256k1_scalar_eq(&r1, &r2)); + } + + { + /* Test distributitivity of mul over add. */ + secp256k1_scalar_t r1, r2, t; + secp256k1_scalar_add(&r1, &s1, &s2); + secp256k1_scalar_mul(&r1, &r1, &s); + secp256k1_scalar_mul(&r2, &s1, &s); + secp256k1_scalar_mul(&t, &s2, &s); + secp256k1_scalar_add(&r2, &r2, &t); + CHECK(secp256k1_scalar_eq(&r1, &r2)); + } + + { + /* Test square. */ + secp256k1_scalar_t r1, r2; + secp256k1_scalar_sqr(&r1, &s1); + secp256k1_scalar_mul(&r2, &s1, &s1); + CHECK(secp256k1_scalar_eq(&r1, &r2)); + } + + { + /* Test multiplicative identity. */ + secp256k1_scalar_t r1, v1; + secp256k1_scalar_set_int(&v1,1); + secp256k1_scalar_mul(&r1, &s1, &v1); + CHECK(secp256k1_scalar_eq(&r1, &s1)); + } + + { + /* Test additive identity. */ + secp256k1_scalar_t r1, v0; + secp256k1_scalar_set_int(&v0,0); + secp256k1_scalar_add(&r1, &s1, &v0); + CHECK(secp256k1_scalar_eq(&r1, &s1)); + } + + { + /* Test zero product property. */ + secp256k1_scalar_t r1, v0; + secp256k1_scalar_set_int(&v0,0); + secp256k1_scalar_mul(&r1, &s1, &v0); + CHECK(secp256k1_scalar_eq(&r1, &v0)); + } + +} + +void run_scalar_tests(void) { + for (int i = 0; i < 128 * count; i++) { + scalar_test(); + } + + { + /* (-1)+1 should be zero. */ + secp256k1_scalar_t s, o; + secp256k1_scalar_set_int(&s, 1); + CHECK(secp256k1_scalar_is_one(&s)); + secp256k1_scalar_negate(&o, &s); + secp256k1_scalar_add(&o, &o, &s); + CHECK(secp256k1_scalar_is_zero(&o)); + secp256k1_scalar_negate(&o, &o); + CHECK(secp256k1_scalar_is_zero(&o)); + } + +#ifndef USE_NUM_NONE + { + /* A scalar with value of the curve order should be 0. */ + secp256k1_num_t order; + secp256k1_scalar_order_get_num(&order); + unsigned char bin[32]; + secp256k1_num_get_bin(bin, 32, &order); + secp256k1_scalar_t zero; + int overflow = 0; + secp256k1_scalar_set_b32(&zero, bin, &overflow); + CHECK(overflow == 1); + CHECK(secp256k1_scalar_is_zero(&zero)); + } +#endif +} + +/***** FIELD TESTS *****/ + +void random_fe(secp256k1_fe_t *x) { + unsigned char bin[32]; + do { + secp256k1_rand256(bin); + if (secp256k1_fe_set_b32(x, bin)) { + return; + } + } while(1); +} + +void random_fe_non_zero(secp256k1_fe_t *nz) { + int tries = 10; + while (--tries >= 0) { + random_fe(nz); + secp256k1_fe_normalize(nz); + if (!secp256k1_fe_is_zero(nz)) + break; + } + /* Infinitesimal probability of spurious failure here */ + CHECK(tries >= 0); +} + +void random_fe_non_square(secp256k1_fe_t *ns) { + random_fe_non_zero(ns); + secp256k1_fe_t r; + if (secp256k1_fe_sqrt_var(&r, ns)) { + secp256k1_fe_negate(ns, ns, 1); + } +} + +int check_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { + secp256k1_fe_t an = *a; secp256k1_fe_normalize(&an); + secp256k1_fe_t bn = *b; secp256k1_fe_normalize_var(&bn); + return secp256k1_fe_equal(&an, &bn); +} + +int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) { + secp256k1_fe_t x; secp256k1_fe_mul(&x, a, ai); + secp256k1_fe_t one; secp256k1_fe_set_int(&one, 1); + return check_fe_equal(&x, &one); +} + +void run_field_misc(void) { + const unsigned char f32_5[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, + }; + secp256k1_fe_t x; + secp256k1_fe_t y; + secp256k1_fe_t z; + secp256k1_fe_t q; + secp256k1_fe_t fe5; + CHECK(secp256k1_fe_set_b32(&fe5, f32_5)); + for (int i=0; i<5*count; i++) { + random_fe(&x); + random_fe_non_zero(&y); + /* Test the fe equality and comparison operations. */ + CHECK(secp256k1_fe_cmp_var(&x, &x) == 0); + CHECK(secp256k1_fe_equal(&x, &x)); + z = x; + secp256k1_fe_add(&z,&y); + secp256k1_fe_normalize(&z); + /* Test the conditional move. */ + secp256k1_fe_cmov(&z, &x, 0); + CHECK(secp256k1_fe_equal(&x, &z) == 0); + CHECK(secp256k1_fe_cmp_var(&x, &z) != 0); + secp256k1_fe_cmov(&y, &x, 1); + CHECK(secp256k1_fe_equal(&x, &y)); + /* Test that mul_int, mul, and add agree. */ + secp256k1_fe_add(&y, &x); + secp256k1_fe_add(&y, &x); + z = x; + secp256k1_fe_mul_int(&z, 3); + CHECK(check_fe_equal(&y, &z)); + secp256k1_fe_add(&y, &x); + secp256k1_fe_add(&z, &x); + CHECK(check_fe_equal(&z, &y)); + z = x; + secp256k1_fe_mul_int(&z, 5); + secp256k1_fe_mul(&q, &x, &fe5); + CHECK(check_fe_equal(&z, &q)); + secp256k1_fe_negate(&x, &x, 1); + secp256k1_fe_add(&z, &x); + secp256k1_fe_add(&q, &x); + CHECK(check_fe_equal(&y, &z)); + CHECK(check_fe_equal(&q, &y)); + } +} + +void run_field_inv(void) { + secp256k1_fe_t x, xi, xii; + for (int i=0; i<10*count; i++) { + random_fe_non_zero(&x); + secp256k1_fe_inv(&xi, &x); + CHECK(check_fe_inverse(&x, &xi)); + secp256k1_fe_inv(&xii, &xi); + CHECK(check_fe_equal(&x, &xii)); + } +} + +void run_field_inv_var(void) { + secp256k1_fe_t x, xi, xii; + for (int i=0; i<10*count; i++) { + random_fe_non_zero(&x); + secp256k1_fe_inv_var(&xi, &x); + CHECK(check_fe_inverse(&x, &xi)); + secp256k1_fe_inv_var(&xii, &xi); + CHECK(check_fe_equal(&x, &xii)); + } +} + +void run_field_inv_all_var(void) { + secp256k1_fe_t x[16], xi[16], xii[16]; + /* Check it's safe to call for 0 elements */ + secp256k1_fe_inv_all_var(0, xi, x); + for (int i=0; i<count; i++) { + size_t len = (secp256k1_rand32() & 15) + 1; + for (size_t j=0; j<len; j++) + random_fe_non_zero(&x[j]); + secp256k1_fe_inv_all_var(len, xi, x); + for (size_t j=0; j<len; j++) + CHECK(check_fe_inverse(&x[j], &xi[j])); + secp256k1_fe_inv_all_var(len, xii, xi); + for (size_t j=0; j<len; j++) + CHECK(check_fe_equal(&x[j], &xii[j])); + } +} + +void run_sqr(void) { + secp256k1_fe_t x, s; + + { + secp256k1_fe_set_int(&x, 1); + secp256k1_fe_negate(&x, &x, 1); + + for (int i=1; i<=512; ++i) { + secp256k1_fe_mul_int(&x, 2); + secp256k1_fe_normalize(&x); + secp256k1_fe_sqr(&s, &x); + } + } +} + +void test_sqrt(const secp256k1_fe_t *a, const secp256k1_fe_t *k) { + secp256k1_fe_t r1, r2; + int v = secp256k1_fe_sqrt_var(&r1, a); + CHECK((v == 0) == (k == NULL)); + + if (k != NULL) { + /* Check that the returned root is +/- the given known answer */ + secp256k1_fe_negate(&r2, &r1, 1); + secp256k1_fe_add(&r1, k); secp256k1_fe_add(&r2, k); + secp256k1_fe_normalize(&r1); secp256k1_fe_normalize(&r2); + CHECK(secp256k1_fe_is_zero(&r1) || secp256k1_fe_is_zero(&r2)); + } +} + +void run_sqrt(void) { + secp256k1_fe_t ns, x, s, t; + + /* Check sqrt(0) is 0 */ + secp256k1_fe_set_int(&x, 0); + secp256k1_fe_sqr(&s, &x); + test_sqrt(&s, &x); + + /* Check sqrt of small squares (and their negatives) */ + for (int i=1; i<=100; i++) { + secp256k1_fe_set_int(&x, i); + secp256k1_fe_sqr(&s, &x); + test_sqrt(&s, &x); + secp256k1_fe_negate(&t, &s, 1); + test_sqrt(&t, NULL); + } + + /* Consistency checks for large random values */ + for (int i=0; i<10; i++) { + random_fe_non_square(&ns); + for (int j=0; j<count; j++) { + random_fe(&x); + secp256k1_fe_sqr(&s, &x); + test_sqrt(&s, &x); + secp256k1_fe_negate(&t, &s, 1); + test_sqrt(&t, NULL); + secp256k1_fe_mul(&t, &s, &ns); + test_sqrt(&t, NULL); + } + } +} + +/***** GROUP TESTS *****/ + +int ge_equals_ge(const secp256k1_ge_t *a, const secp256k1_ge_t *b) { + if (a->infinity && b->infinity) + return 1; + return check_fe_equal(&a->x, &b->x) && check_fe_equal(&a->y, &b->y); +} + +void ge_equals_gej(const secp256k1_ge_t *a, const secp256k1_gej_t *b) { + secp256k1_ge_t bb; + secp256k1_gej_t bj = *b; + secp256k1_ge_set_gej_var(&bb, &bj); + CHECK(ge_equals_ge(a, &bb)); +} + +void gej_equals_gej(const secp256k1_gej_t *a, const secp256k1_gej_t *b) { + secp256k1_ge_t aa, bb; + secp256k1_gej_t aj = *a, bj = *b; + secp256k1_ge_set_gej_var(&aa, &aj); + secp256k1_ge_set_gej_var(&bb, &bj); + CHECK(ge_equals_ge(&aa, &bb)); +} + +void test_ge(void) { + char ca[135]; + char cb[68]; + int rlen; + secp256k1_ge_t a, b, i, n; + random_group_element_test(&a); + random_group_element_test(&b); + rlen = sizeof(ca); + secp256k1_ge_get_hex(ca,&rlen,&a); + CHECK(rlen > 4 && rlen <= (int)sizeof(ca)); + rlen = sizeof(cb); + secp256k1_ge_get_hex(cb,&rlen,&b); /* Intentionally undersized buffer. */ + n = a; + secp256k1_fe_normalize(&a.y); + secp256k1_fe_negate(&n.y, &a.y, 1); + secp256k1_ge_set_infinity(&i); + random_field_element_magnitude(&a.x); + random_field_element_magnitude(&a.y); + random_field_element_magnitude(&b.x); + random_field_element_magnitude(&b.y); + random_field_element_magnitude(&n.x); + random_field_element_magnitude(&n.y); + + secp256k1_gej_t aj, bj, ij, nj; + random_group_element_jacobian_test(&aj, &a); + random_group_element_jacobian_test(&bj, &b); + secp256k1_gej_set_infinity(&ij); + random_group_element_jacobian_test(&nj, &n); + random_field_element_magnitude(&aj.x); + random_field_element_magnitude(&aj.y); + random_field_element_magnitude(&aj.z); + random_field_element_magnitude(&bj.x); + random_field_element_magnitude(&bj.y); + random_field_element_magnitude(&bj.z); + random_field_element_magnitude(&nj.x); + random_field_element_magnitude(&nj.y); + random_field_element_magnitude(&nj.z); + + /* gej + gej adds */ + secp256k1_gej_t aaj; secp256k1_gej_add_var(&aaj, &aj, &aj); + secp256k1_gej_t abj; secp256k1_gej_add_var(&abj, &aj, &bj); + secp256k1_gej_t aij; secp256k1_gej_add_var(&aij, &aj, &ij); + secp256k1_gej_t anj; secp256k1_gej_add_var(&anj, &aj, &nj); + secp256k1_gej_t iaj; secp256k1_gej_add_var(&iaj, &ij, &aj); + secp256k1_gej_t iij; secp256k1_gej_add_var(&iij, &ij, &ij); + + /* gej + ge adds */ + secp256k1_gej_t aa; secp256k1_gej_add_ge_var(&aa, &aj, &a); + secp256k1_gej_t ab; secp256k1_gej_add_ge_var(&ab, &aj, &b); + secp256k1_gej_t ai; secp256k1_gej_add_ge_var(&ai, &aj, &i); + secp256k1_gej_t an; secp256k1_gej_add_ge_var(&an, &aj, &n); + secp256k1_gej_t ia; secp256k1_gej_add_ge_var(&ia, &ij, &a); + secp256k1_gej_t ii; secp256k1_gej_add_ge_var(&ii, &ij, &i); + + /* const gej + ge adds */ + secp256k1_gej_t aac; secp256k1_gej_add_ge(&aac, &aj, &a); + secp256k1_gej_t abc; secp256k1_gej_add_ge(&abc, &aj, &b); + secp256k1_gej_t anc; secp256k1_gej_add_ge(&anc, &aj, &n); + secp256k1_gej_t iac; secp256k1_gej_add_ge(&iac, &ij, &a); + + CHECK(secp256k1_gej_is_infinity(&an)); + CHECK(secp256k1_gej_is_infinity(&anj)); + CHECK(secp256k1_gej_is_infinity(&anc)); + gej_equals_gej(&aa, &aaj); + gej_equals_gej(&aa, &aac); + gej_equals_gej(&ab, &abj); + gej_equals_gej(&ab, &abc); + gej_equals_gej(&an, &anj); + gej_equals_gej(&an, &anc); + gej_equals_gej(&ia, &iaj); + gej_equals_gej(&ai, &aij); + gej_equals_gej(&ii, &iij); + ge_equals_gej(&a, &ai); + ge_equals_gej(&a, &ai); + ge_equals_gej(&a, &iaj); + ge_equals_gej(&a, &iaj); + ge_equals_gej(&a, &iac); +} + +void run_ge(void) { + for (int i = 0; i < 2000*count; i++) { + test_ge(); + } +} + +/***** ECMULT TESTS *****/ + +void run_ecmult_chain(void) { + /* random starting point A (on the curve) */ + secp256k1_fe_t ax; VERIFY_CHECK(secp256k1_fe_set_hex(&ax, "8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004", 64)); + secp256k1_fe_t ay; VERIFY_CHECK(secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64)); + secp256k1_gej_t a; secp256k1_gej_set_xy(&a, &ax, &ay); + /* two random initial factors xn and gn */ + static const unsigned char xni[32] = { + 0x84, 0xcc, 0x54, 0x52, 0xf7, 0xfd, 0xe1, 0xed, + 0xb4, 0xd3, 0x8a, 0x8c, 0xe9, 0xb1, 0xb8, 0x4c, + 0xce, 0xf3, 0x1f, 0x14, 0x6e, 0x56, 0x9b, 0xe9, + 0x70, 0x5d, 0x35, 0x7a, 0x42, 0x98, 0x54, 0x07 + }; + secp256k1_scalar_t xn; + secp256k1_scalar_set_b32(&xn, xni, NULL); + static const unsigned char gni[32] = { + 0xa1, 0xe5, 0x8d, 0x22, 0x55, 0x3d, 0xcd, 0x42, + 0xb2, 0x39, 0x80, 0x62, 0x5d, 0x4c, 0x57, 0xa9, + 0x6e, 0x93, 0x23, 0xd4, 0x2b, 0x31, 0x52, 0xe5, + 0xca, 0x2c, 0x39, 0x90, 0xed, 0xc7, 0xc9, 0xde + }; + secp256k1_scalar_t gn; + secp256k1_scalar_set_b32(&gn, gni, NULL); + /* two small multipliers to be applied to xn and gn in every iteration: */ + static const unsigned char xfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x13,0x37}; + secp256k1_scalar_t xf; + secp256k1_scalar_set_b32(&xf, xfi, NULL); + static const unsigned char gfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x71,0x13}; + secp256k1_scalar_t gf; + secp256k1_scalar_set_b32(&gf, gfi, NULL); + /* accumulators with the resulting coefficients to A and G */ + secp256k1_scalar_t ae; + secp256k1_scalar_set_int(&ae, 1); + secp256k1_scalar_t ge; + secp256k1_scalar_set_int(&ge, 0); + /* the point being computed */ + secp256k1_gej_t x = a; + for (int i=0; i<200*count; i++) { + /* in each iteration, compute X = xn*X + gn*G; */ + secp256k1_ecmult(&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); + secp256k1_scalar_mul(&ge, &ge, &xn); + secp256k1_scalar_add(&ge, &ge, &gn); + /* modify xn and gn */ + secp256k1_scalar_mul(&xn, &xn, &xf); + secp256k1_scalar_mul(&gn, &gn, &gf); + + /* verify */ + if (i == 19999) { + char res[132]; int resl = 132; + secp256k1_gej_get_hex(res, &resl, &x); + CHECK(strcmp(res, "(D6E96687F9B10D092A6F35439D86CEBEA4535D0D409F53586440BD74B933E830,B95CBCA2C77DA786539BE8FD53354D2D3B4F566AE658045407ED6015EE1B2A88)") == 0); + } + } + /* redo the computation, but directly with the resulting ae and ge coefficients: */ + secp256k1_gej_t x2; secp256k1_ecmult(&x2, &a, &ae, &ge); + char res[132]; int resl = 132; + char res2[132]; int resl2 = 132; + secp256k1_gej_get_hex(res, &resl, &x); + secp256k1_gej_get_hex(res2, &resl2, &x2); + CHECK(strcmp(res, res2) == 0); + CHECK(strlen(res) == 131); +} + +void test_point_times_order(const secp256k1_gej_t *point) { + unsigned char pub[65]; + /* X * (point + G) + (order-X) * (pointer + G) = 0 */ + secp256k1_scalar_t x; + random_scalar_order_test(&x); + secp256k1_scalar_t nx; + secp256k1_scalar_negate(&nx, &x); + secp256k1_gej_t res1, res2; + 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_gej_add_var(&res1, &res1, &res2); + CHECK(secp256k1_gej_is_infinity(&res1)); + CHECK(secp256k1_gej_is_valid_var(&res1) == 0); + secp256k1_ge_t res3; + secp256k1_ge_set_gej(&res3, &res1); + CHECK(secp256k1_ge_is_infinity(&res3)); + CHECK(secp256k1_ge_is_valid_var(&res3) == 0); + int psize = 65; + CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 0) == 0); + psize = 65; + CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 1) == 0); +} + +void run_point_times_order(void) { + secp256k1_fe_t x; VERIFY_CHECK(secp256k1_fe_set_hex(&x, "02", 2)); + for (int i=0; i<500; i++) { + secp256k1_ge_t p; + if (secp256k1_ge_set_xo_var(&p, &x, 1)) { + CHECK(secp256k1_ge_is_valid_var(&p)); + secp256k1_gej_t j; + secp256k1_gej_set_ge(&j, &p); + CHECK(secp256k1_gej_is_valid_var(&j)); + test_point_times_order(&j); + } + secp256k1_fe_sqr(&x, &x); + } + char c[65]; + int cl = 1; + c[1] = 123; + secp256k1_fe_get_hex(c, &cl, &x); /* Check that fe_get_hex handles a too short input. */ + CHECK(c[1] == 123); + cl = 65; + secp256k1_fe_get_hex(c, &cl, &x); + CHECK(strcmp(c, "7603CB59B0EF6C63FE6084792A0C378CDB3233A80F8A9A09A877DEAD31B38C45") == 0); +} + +void test_wnaf(const secp256k1_scalar_t *number, int w) { + secp256k1_scalar_t x, two, t; + secp256k1_scalar_set_int(&x, 0); + secp256k1_scalar_set_int(&two, 2); + int wnaf[256]; + int bits = secp256k1_ecmult_wnaf(wnaf, number, w); + CHECK(bits <= 256); + int zeroes = -1; + for (int i=bits-1; i>=0; i--) { + secp256k1_scalar_mul(&x, &x, &two); + int v = wnaf[i]; + if (v) { + CHECK(zeroes == -1 || zeroes >= w-1); /* check that distance between non-zero elements is at least w-1 */ + zeroes=0; + CHECK((v & 1) == 1); /* check non-zero elements are odd */ + CHECK(v <= (1 << (w-1)) - 1); /* check range below */ + CHECK(v >= -(1 << (w-1)) - 1); /* check range above */ + } else { + CHECK(zeroes != -1); /* check that no unnecessary zero padding exists */ + zeroes++; + } + if (v >= 0) { + secp256k1_scalar_set_int(&t, v); + } else { + secp256k1_scalar_set_int(&t, -v); + secp256k1_scalar_negate(&t, &t); + } + secp256k1_scalar_add(&x, &x, &t); + } + CHECK(secp256k1_scalar_eq(&x, number)); /* check that wnaf represents number */ +} + +void run_wnaf(void) { + secp256k1_scalar_t n; + for (int i=0; i<count; i++) { + random_scalar_order(&n); + if (i % 1) + secp256k1_scalar_negate(&n, &n); + test_wnaf(&n, 4+(i%10)); + } +} + +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)); +} + +void test_ecdsa_sign_verify(void) { + int recid; + int getrec; + secp256k1_scalar_t msg, key; + random_scalar_order_test(&msg); + random_scalar_order_test(&key); + secp256k1_gej_t pubj; secp256k1_ecmult_gen(&pubj, &key); + secp256k1_ge_t pub; secp256k1_ge_set_gej(&pub, &pubj); + secp256k1_ecdsa_sig_t sig; + 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)); + secp256k1_scalar_t one; + secp256k1_scalar_set_int(&one, 1); + secp256k1_scalar_add(&msg, &msg, &one); + CHECK(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg)); +} + +void run_ecdsa_sign_verify(void) { + for (int i=0; i<10*count; i++) { + test_ecdsa_sign_verify(); + } +} + +void test_ecdsa_end_to_end(void) { + unsigned char privkey[32]; + unsigned char message[32]; + + /* Generate a random key and message. */ + { + secp256k1_scalar_t msg, key; + random_scalar_order_test(&msg); + random_scalar_order_test(&key); + secp256k1_scalar_get_b32(privkey, &key); + secp256k1_scalar_get_b32(message, &msg); + } + + /* Construct and verify corresponding public key. */ + CHECK(secp256k1_ec_seckey_verify(privkey) == 1); + unsigned char pubkey[65]; int pubkeylen = 65; + CHECK(secp256k1_ec_pubkey_create(pubkey, &pubkeylen, privkey, (secp256k1_rand32() & 3) != 0) == 1); + if (secp256k1_rand32() & 1) { + CHECK(secp256k1_ec_pubkey_decompress(pubkey, &pubkeylen)); + } + CHECK(secp256k1_ec_pubkey_verify(pubkey, pubkeylen)); + + /* Verify private key import and export. */ + unsigned char seckey[300]; int seckeylen = 300; + CHECK(secp256k1_ec_privkey_export(privkey, seckey, &seckeylen, secp256k1_rand32() % 2) == 1); + unsigned char privkey2[32]; + CHECK(secp256k1_ec_privkey_import(privkey2, seckey, seckeylen) == 1); + CHECK(memcmp(privkey, privkey2, 32) == 0); + + /* Optionally tweak the keys using addition. */ + if (secp256k1_rand32() % 3 == 0) { + unsigned char rnd[32]; + secp256k1_rand256_test(rnd); + int ret1 = secp256k1_ec_privkey_tweak_add(privkey, rnd); + int ret2 = secp256k1_ec_pubkey_tweak_add(pubkey, pubkeylen, rnd); + CHECK(ret1 == ret2); + if (ret1 == 0) return; + unsigned char pubkey2[65]; int pubkeylen2 = 65; + CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); + CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); + } + + /* Optionally tweak the keys using multiplication. */ + if (secp256k1_rand32() % 3 == 0) { + unsigned char rnd[32]; + secp256k1_rand256_test(rnd); + int ret1 = secp256k1_ec_privkey_tweak_mul(privkey, rnd); + int ret2 = secp256k1_ec_pubkey_tweak_mul(pubkey, pubkeylen, rnd); + CHECK(ret1 == ret2); + if (ret1 == 0) return; + unsigned char pubkey2[65]; int pubkeylen2 = 65; + CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); + CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); + } + + /* Sign. */ + unsigned char signature[72]; int signaturelen = 72; + while(1) { + unsigned char rnd[32]; + secp256k1_rand256_test(rnd); + if (secp256k1_ecdsa_sign(message, signature, &signaturelen, privkey, rnd) == 1) { + break; + } + } + /* Verify. */ + CHECK(secp256k1_ecdsa_verify(message, signature, signaturelen, 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); + + /* Compact sign. */ + unsigned char csignature[64]; int recid = 0; + while(1) { + unsigned char rnd[32]; + secp256k1_rand256_test(rnd); + if (secp256k1_ecdsa_sign_compact(message, csignature, privkey, rnd, &recid) == 1) { + break; + } + } + /* Recover. */ + unsigned char recpubkey[65]; int recpubkeylen = 0; + CHECK(secp256k1_ecdsa_recover_compact(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 || + memcmp(pubkey, recpubkey, pubkeylen) != 0); + CHECK(recpubkeylen == pubkeylen); + +} + +void test_random_pubkeys(void) { + unsigned char in[65]; + /* Generate some randomly sized pubkeys. */ + uint32_t r = secp256k1_rand32(); + int len = (r & 3) == 0 ? 65 : 33; + r>>=2; + if ((r & 3) == 0) len = (r & 252) >> 3; + r>>=8; + if (len == 65) { + in[0] = (r & 2) ? 4 : (r & 1? 6 : 7); + } else { + in[0] = (r & 1) ? 2 : 3; + } + r>>=2; + 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]); + secp256k1_ge_t elem; + secp256k1_ge_t elem2; + if (secp256k1_eckey_pubkey_parse(&elem, in, len)) { + unsigned char out[65]; + unsigned char firstb; + int res; + int size = len; + firstb = in[0]; + /* If the pubkey can be parsed, it should round-trip... */ + CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, len == 33)); + 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]); + size = 65; + CHECK(secp256k1_eckey_pubkey_serialize(&elem, in, &size, 0)); + CHECK(size == 65); + CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size)); + CHECK(ge_equals_ge(&elem,&elem2)); + /* Check that the X9.62 hybrid type is checked. */ + 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 (res) { + CHECK(ge_equals_ge(&elem,&elem2)); + CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, 0)); + CHECK(memcmp(&in[1], &out[1], 64) == 0); + } + } +} + +void run_random_pubkeys(void) { + for (int i=0; i<10*count; i++) { + test_random_pubkeys(); + } +} + +void run_ecdsa_end_to_end(void) { + for (int i=0; i<64*count; i++) { + test_ecdsa_end_to_end(); + } +} + +/* Tests several edge cases. */ +void test_ecdsa_edge_cases(void) { + const unsigned char msg32[32] = { + 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', + 'a', ' ', 'v', 'e', 'r', 'y', ' ', 's', + 'e', 'c', 'r', 'e', 't', ' ', 'm', 'e', + 's', 's', 'a', 'g', 'e', '.', '.', '.' + }; + const unsigned char sig64[64] = { + /* Generated by signing the above message with nonce 'This is the nonce we will use...' + * and secret key 0 (which is not valid), resulting in recid 0. */ + 0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8, + 0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96, + 0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63, + 0x17, 0x9A, 0x7D, 0xD1, 0x7B, 0xD2, 0x35, 0x32, + 0x4B, 0x1B, 0x7D, 0xF3, 0x4C, 0xE1, 0xF6, 0x8E, + 0x69, 0x4F, 0xF6, 0xF1, 0x1A, 0xC7, 0x51, 0xDD, + 0x7D, 0xD7, 0x3E, 0x38, 0x7E, 0xE4, 0xFC, 0x86, + 0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57 + }; + unsigned char pubkey[65]; + int pubkeylen = 65; + 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)); + + /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */ + const unsigned char sigb64[64] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + }; + unsigned char pubkeyb[33]; + int pubkeyblen = 33; + for (int recid = 0; recid < 4; recid++) { + /* (4,4) encoded in DER. */ + unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04}; + unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01}; + unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00}; + unsigned char sigbderalt1[39] = { + 0x30, 0x25, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, + }; + unsigned char sigbderalt2[39] = { + 0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + }; + unsigned char sigbderalt3[40] = { + 0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, + }; + unsigned char sigbderalt4[40] = { + 0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + }; + /* (order + r,4) encoded in DER. */ + unsigned char sigbderlong[40] = { + 0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, + 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, + 0x8C, 0xD0, 0x36, 0x41, 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); + for (int recid2 = 0; recid2 < 4; recid2++) { + unsigned char pubkey2b[33]; + int pubkey2blen = 33; + CHECK(secp256k1_ecdsa_recover_compact(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); + } + /* 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); + /* 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); + sigbderalt3[4] = 1; + CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == -2); + sigbderalt4[7] = 1; + CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == -2); + /* Damage signature. */ + sigbder[7]++; + CHECK(secp256k1_ecdsa_verify(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); + for(int i = 0; i<8; i++) { + unsigned char orig = sigbder[i]; + /*Try every single-byte change.*/ + for (int c=0; c<256; c++) { + if (c == orig ) continue; + sigbder[i] = c; + CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == + (i==4 || i==7) ? 0 : -2 ); + } + sigbder[i] = orig; + } + } + + /* Test the case where ECDSA recomputes a point that is infinity. */ + { + secp256k1_ecdsa_sig_t sig; + secp256k1_scalar_set_int(&sig.s, 1); + secp256k1_scalar_negate(&sig.s, &sig.s); + secp256k1_scalar_inverse(&sig.s, &sig.s); + secp256k1_scalar_set_int(&sig.r, 1); + secp256k1_gej_t keyj; + secp256k1_ecmult_gen(&keyj, &sig.r); + secp256k1_ge_t key; + secp256k1_ge_set_gej(&key, &keyj); + secp256k1_scalar_t msg = sig.s; + CHECK(secp256k1_ecdsa_sig_verify(&sig, &key, &msg) == 0); + } + + /* Test r/s equal to zero */ + { + /* (1,1) encoded in DER. */ + unsigned char sigcder[8] = {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01}; + unsigned char sigc64[64] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }; + 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); + 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); + 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); + } + + /*Signature where s would be zero.*/ + { + const unsigned char nonce[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }; + const unsigned char key[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }; + unsigned char msg[32] = { + 0x86, 0x41, 0x99, 0x81, 0x06, 0x23, 0x44, 0x53, + 0xaa, 0x5f, 0x9d, 0x6a, 0x31, 0x78, 0xf4, 0xf7, + 0xb8, 0x12, 0xe0, 0x0b, 0x81, 0x7a, 0x77, 0x62, + 0x65, 0xdf, 0xdd, 0x31, 0xb9, 0x3e, 0x29, 0xa9, + }; + unsigned char sig[72]; + int siglen = 72; + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce) == 0); + msg[31] = 0xaa; + siglen = 72; + CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce) == 1); + } + + /* Privkey export where pubkey is the point at infinity. */ + { + unsigned char privkey[300]; + unsigned char seckey[32] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, + 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41, + }; + int outlen = 300; + CHECK(!secp256k1_ec_privkey_export(seckey, privkey, &outlen, 0)); + CHECK(!secp256k1_ec_privkey_export(seckey, privkey, &outlen, 1)); + } +} + +void run_ecdsa_edge_cases(void) { + test_ecdsa_edge_cases(); +} + +#ifdef ENABLE_OPENSSL_TESTS +EC_KEY *get_openssl_key(const secp256k1_scalar_t *key) { + unsigned char privkey[300]; + int privkeylen; + int compr = secp256k1_rand32() & 1; + const unsigned char* pbegin = privkey; + EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1); + CHECK(secp256k1_eckey_privkey_serialize(privkey, &privkeylen, key, compr)); + CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen)); + CHECK(EC_KEY_check_key(ec_key)); + return ec_key; +} + +void test_ecdsa_openssl(void) { + secp256k1_scalar_t key, msg; + unsigned char message[32]; + secp256k1_rand256_test(message); + secp256k1_scalar_set_b32(&msg, message, NULL); + random_scalar_order_test(&key); + secp256k1_gej_t qj; + secp256k1_ecmult_gen(&qj, &key); + secp256k1_ge_t q; + secp256k1_ge_set_gej(&q, &qj); + EC_KEY *ec_key = get_openssl_key(&key); + CHECK(ec_key); + unsigned char signature[80]; + unsigned int sigsize = 80; + CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key)); + secp256k1_ecdsa_sig_t sig; + CHECK(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize)); + CHECK(secp256k1_ecdsa_sig_verify(&sig, &q, &msg)); + secp256k1_scalar_t one; + secp256k1_scalar_set_int(&one, 1); + secp256k1_scalar_t msg2; + secp256k1_scalar_add(&msg2, &msg, &one); + CHECK(!secp256k1_ecdsa_sig_verify(&sig, &q, &msg2)); + + random_sign(&sig, &key, &msg, NULL); + int secp_sigsize = 80; + CHECK(secp256k1_ecdsa_sig_serialize(signature, &secp_sigsize, &sig)); + CHECK(ECDSA_verify(0, message, sizeof(message), signature, secp_sigsize, ec_key) == 1); + + EC_KEY_free(ec_key); +} + +void run_ecdsa_openssl(void) { + for (int i=0; i<10*count; i++) { + test_ecdsa_openssl(); + } +} +#endif + +int main(int argc, char **argv) { + /* find iteration count */ + if (argc > 1) { + count = strtol(argv[1], NULL, 0); + } + + /* find random seed */ + uint64_t seed; + if (argc > 2) { + seed = strtoull(argv[2], NULL, 0); + } else { + FILE *frand = fopen("/dev/urandom", "r"); + if (!frand || !fread(&seed, sizeof(seed), 1, frand)) { + seed = time(NULL) * 1337; + } + fclose(frand); + } + secp256k1_rand_seed(seed); + + printf("test count = %i\n", count); + printf("random seed = %llu\n", (unsigned long long)seed); + + /* initialize */ + secp256k1_start(SECP256K1_START_SIGN | SECP256K1_START_VERIFY); + + /* initializing a second time shouldn't cause any harm or memory leaks. */ + secp256k1_start(SECP256K1_START_SIGN | SECP256K1_START_VERIFY); + + /* Likewise, re-running the internal init functions should be harmless. */ + secp256k1_fe_start(); + secp256k1_ge_start(); + secp256k1_scalar_start(); + secp256k1_ecdsa_start(); + +#ifndef USE_NUM_NONE + /* num tests */ + run_num_smalltests(); +#endif + + /* scalar tests */ + run_scalar_tests(); + + /* field tests */ + run_field_inv(); + run_field_inv_var(); + run_field_inv_all_var(); + run_field_misc(); + run_sqr(); + run_sqrt(); + + /* group tests */ + run_ge(); + + /* ecmult tests */ + run_wnaf(); + run_point_times_order(); + run_ecmult_chain(); + + /* ecdsa tests */ + run_random_pubkeys(); + run_ecdsa_sign_verify(); + run_ecdsa_end_to_end(); + run_ecdsa_edge_cases(); +#ifdef ENABLE_OPENSSL_TESTS + run_ecdsa_openssl(); +#endif + + printf("random run = %llu\n", (unsigned long long)secp256k1_rand32() + ((unsigned long long)secp256k1_rand32() << 32)); + + /* shutdown */ + secp256k1_stop(); + + /* shutting down twice shouldn't cause any double frees. */ + secp256k1_stop(); + + /* Same for the internal shutdown functions. */ + secp256k1_fe_stop(); + secp256k1_ge_stop(); + secp256k1_scalar_stop(); + secp256k1_ecdsa_stop(); + return 0; +} diff --git a/src/secp256k1/src/util.h b/src/secp256k1/src/util.h new file mode 100644 index 0000000000..c3a8f3a42b --- /dev/null +++ b/src/secp256k1/src/util.h @@ -0,0 +1,87 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_UTIL_H_ +#define _SECP256K1_UTIL_H_ + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include <stdlib.h> +#include <stdint.h> +#include <stdio.h> + +#ifdef DETERMINISTIC +#define TEST_FAILURE(msg) do { \ + fprintf(stderr, "%s\n", msg); \ + abort(); \ +} while(0); +#else +#define TEST_FAILURE(msg) do { \ + fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \ + abort(); \ +} while(0) +#endif + +#ifndef HAVE_BUILTIN_EXPECT +#define EXPECT(x,c) __builtin_expect((x),(c)) +#else +#define EXPECT(x,c) (x) +#endif + +#ifdef DETERMINISTIC +#define CHECK(cond) do { \ + if (EXPECT(!(cond), 0)) { \ + TEST_FAILURE("test condition failed"); \ + } \ +} while(0) +#else +#define CHECK(cond) do { \ + if (EXPECT(!(cond), 0)) { \ + TEST_FAILURE("test condition failed: " #cond); \ + } \ +} while(0) +#endif + +/* Like assert(), but safe to use on expressions with side effects. */ +#ifndef NDEBUG +#define DEBUG_CHECK CHECK +#else +#define DEBUG_CHECK(cond) do { (void)(cond); } while(0) +#endif + +/* Like DEBUG_CHECK(), but when VERIFY is defined instead of NDEBUG not defined. */ +#ifdef VERIFY +#define VERIFY_CHECK CHECK +#else +#define VERIFY_CHECK(cond) do { (void)(cond); } while(0) +#endif + +static inline void *checked_malloc(size_t size) { + void *ret = malloc(size); + CHECK(ret != NULL); + return ret; +} + +/* Macro for restrict, when available and not in a VERIFY build. */ +#if defined(SECP256K1_BUILD) && defined(VERIFY) +# define SECP256K1_RESTRICT +#else +# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) +# if SECP256K1_GNUC_PREREQ(3,0) +# define SECP256K1_RESTRICT __restrict__ +# elif (defined(_MSC_VER) && _MSC_VER >= 1400) +# define SECP256K1_RESTRICT __restrict +# else +# define SECP256K1_RESTRICT +# endif +# else +# define SECP256K1_RESTRICT restrict +# endif +#endif + +#endif diff --git a/src/serialize.h b/src/serialize.h index 57f5fd069b..e4a4039c71 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -1,13 +1,11 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_SERIALIZE_H #define BITCOIN_SERIALIZE_H -#include "allocators.h" - #include <algorithm> #include <assert.h> #include <ios> @@ -20,32 +18,32 @@ #include <utility> #include <vector> -#include <boost/tuple/tuple.hpp> -#include <boost/type_traits/is_fundamental.hpp> - -class CAutoFile; -class CDataStream; class CScript; static const unsigned int MAX_SIZE = 0x02000000; -// Used to bypass the rule against non-const reference to temporary -// where it makes sense with wrappers such as CFlatData or CTxDB +/** + * Used to bypass the rule against non-const reference to temporary + * where it makes sense with wrappers such as CFlatData or CTxDB + */ template<typename T> inline T& REF(const T& val) { return const_cast<T&>(val); } -// Used to acquire a non-const pointer "this" to generate bodies -// of const serialization operations from a template +/** + * Used to acquire a non-const pointer "this" to generate bodies + * of const serialization operations from a template + */ template<typename T> inline T* NCONST_PTR(const T* val) { return const_cast<T*>(val); } -/** Get begin pointer of vector (non-const version). +/** + * Get begin pointer of vector (non-const version). * @note These functions avoid the undefined case of indexing into an empty * vector, as well as that of indexing after the end of the vector. */ @@ -89,10 +87,12 @@ enum #define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action)) -/* Implement three methods for serializable objects. These are actually wrappers over +/** + * Implement three methods for serializable objects. These are actually wrappers over * "SerializationOp" template, which implements the body of each class' serialization * code. Adding "ADD_SERIALIZE_METHODS" in the body of the class causes these wrappers to be - * added as members. */ + * added as members. + */ #define ADD_SERIALIZE_METHODS \ size_t GetSerializeSize(int nType, int nVersion) const { \ CSizeComputer s(nType, nVersion); \ @@ -110,9 +110,9 @@ enum -// -// Basic types -// +/* + * Basic Types + */ #define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj)) #define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj)) @@ -167,13 +167,13 @@ template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0 -// -// Compact size -// size < 253 -- 1 byte -// size <= USHRT_MAX -- 3 bytes (253 + 2 bytes) -// size <= UINT_MAX -- 5 bytes (254 + 4 bytes) -// size > UINT_MAX -- 9 bytes (255 + 8 bytes) -// +/** + * Compact Size + * size < 253 -- 1 byte + * size <= USHRT_MAX -- 3 bytes (253 + 2 bytes) + * size <= UINT_MAX -- 5 bytes (254 + 4 bytes) + * size > UINT_MAX -- 9 bytes (255 + 8 bytes) + */ inline unsigned int GetSizeOfCompactSize(uint64_t nSize) { if (nSize < 253) return sizeof(unsigned char); @@ -245,7 +245,7 @@ uint64_t ReadCompactSize(Stream& is) uint64_t xSize; READDATA(is, xSize); nSizeRet = xSize; - if (nSizeRet < 0x100000000LLu) + if (nSizeRet < 0x100000000ULL) throw std::ios_base::failure("non-canonical ReadCompactSize()"); } if (nSizeRet > (uint64_t)MAX_SIZE) @@ -253,27 +253,29 @@ uint64_t ReadCompactSize(Stream& is) return nSizeRet; } -// Variable-length integers: bytes are a MSB base-128 encoding of the number. -// The high bit in each byte signifies whether another digit follows. To make -// the encoding is one-to-one, one is subtracted from all but the last digit. -// Thus, the byte sequence a[] with length len, where all but the last byte -// has bit 128 set, encodes the number: -// -// (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1)) -// -// Properties: -// * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes) -// * Every integer has exactly one encoding -// * Encoding does not depend on size of original integer type -// * No redundancy: every (infinite) byte sequence corresponds to a list -// of encoded integers. -// -// 0: [0x00] 256: [0x81 0x00] -// 1: [0x01] 16383: [0xFE 0x7F] -// 127: [0x7F] 16384: [0xFF 0x00] -// 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F] -// 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F] -// 2^32: [0x8E 0xFE 0xFE 0xFF 0x00] +/** + * Variable-length integers: bytes are a MSB base-128 encoding of the number. + * The high bit in each byte signifies whether another digit follows. To make + * sure the encoding is one-to-one, one is subtracted from all but the last digit. + * Thus, the byte sequence a[] with length len, where all but the last byte + * has bit 128 set, encodes the number: + * + * (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1)) + * + * Properties: + * * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes) + * * Every integer has exactly one encoding + * * Encoding does not depend on size of original integer type + * * No redundancy: every (infinite) byte sequence corresponds to a list + * of encoded integers. + * + * 0: [0x00] 256: [0x81 0x00] + * 1: [0x01] 16383: [0xFE 0x7F] + * 127: [0x7F] 16384: [0xFF 0x00] + * 128: [0x80 0x00] 16511: [0x80 0xFF 0x7F] + * 255: [0x80 0x7F] 65535: [0x82 0xFD 0x7F] + * 2^32: [0x8E 0xFE 0xFE 0xFF 0x00] + */ template<typename I> inline unsigned int GetSizeOfVarInt(I n) @@ -324,7 +326,8 @@ I ReadVarInt(Stream& is) #define VARINT(obj) REF(WrapVarInt(REF(obj))) #define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj))) -/** Wrapper for serializing arrays and POD. +/** + * Wrapper for serializing arrays and POD. */ class CFlatData { @@ -422,52 +425,55 @@ public: template<typename I> CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); } -// -// Forward declarations -// +/** + * Forward declarations + */ -// string +/** + * string + */ template<typename C> unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int=0); template<typename Stream, typename C> void Serialize(Stream& os, const std::basic_string<C>& str, int, int=0); template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0); -// vector -template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&); -template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&); +/** + * vector + * vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob. + */ +template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&); +template<typename T, typename A, typename V> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&); template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion); -template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&); -template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&); +template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&); +template<typename Stream, typename T, typename A, typename V> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&); template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion); -template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&); -template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&); +template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&); +template<typename Stream, typename T, typename A, typename V> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&); template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion); -// others derived from vector +/** + * others derived from vector + */ extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion); template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion); template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion); -// pair +/** + * pair + */ template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion); template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion); template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion); -// 3 tuple -template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion); -template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion); -template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion); - -// 4 tuple -template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion); -template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion); -template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion); - -// map +/** + * map + */ template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion); template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion); template<typename Stream, typename K, typename T, typename Pred, typename A> void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion); -// set +/** + * set + */ template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion); template<typename Stream, typename K, typename Pred, typename A> void Serialize(Stream& os, const std::set<K, Pred, A>& m, int nType, int nVersion); template<typename Stream, typename K, typename Pred, typename A> void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion); @@ -476,12 +482,12 @@ template<typename Stream, typename K, typename Pred, typename A> void Unserializ -// -// If none of the specialized versions above matched, default to calling member function. -// "int nType" is changed to "long nType" to keep from getting an ambiguous overload error. -// The compiler will only cast int to long if none of the other templates matched. -// Thanks to Boost serialization for this idea. -// +/** + * If none of the specialized versions above matched, default to calling member function. + * "int nType" is changed to "long nType" to keep from getting an ambiguous overload error. + * The compiler will only cast int to long if none of the other templates matched. + * Thanks to Boost serialization for this idea. + */ template<typename T> inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion) { @@ -504,9 +510,9 @@ inline void Unserialize(Stream& is, T& a, long nType, int nVersion) -// -// string -// +/** + * string + */ template<typename C> unsigned int GetSerializeSize(const std::basic_string<C>& str, int, int) { @@ -532,17 +538,17 @@ void Unserialize(Stream& is, std::basic_string<C>& str, int, int) -// -// vector -// +/** + * vector + */ template<typename T, typename A> -unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&) +unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&) { return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T)); } -template<typename T, typename A> -unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&) +template<typename T, typename A, typename V> +unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const V&) { unsigned int nSize = GetSizeOfCompactSize(v.size()); for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi) @@ -553,20 +559,20 @@ unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nV template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion) { - return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental<T>()); + return GetSerializeSize_impl(v, nType, nVersion, T()); } template<typename Stream, typename T, typename A> -void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&) +void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const unsigned char&) { WriteCompactSize(os, v.size()); if (!v.empty()) os.write((char*)&v[0], v.size() * sizeof(T)); } -template<typename Stream, typename T, typename A> -void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&) +template<typename Stream, typename T, typename A, typename V> +void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const V&) { WriteCompactSize(os, v.size()); for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi) @@ -576,12 +582,12 @@ void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVers template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion) { - Serialize_impl(os, v, nType, nVersion, boost::is_fundamental<T>()); + Serialize_impl(os, v, nType, nVersion, T()); } template<typename Stream, typename T, typename A> -void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&) +void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const unsigned char&) { // Limit size per read so bogus size value won't cause out of memory v.clear(); @@ -596,8 +602,8 @@ void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, } } -template<typename Stream, typename T, typename A> -void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&) +template<typename Stream, typename T, typename A, typename V> +void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const V&) { v.clear(); unsigned int nSize = ReadCompactSize(is); @@ -617,14 +623,14 @@ void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion) { - Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental<T>()); + Unserialize_impl(is, v, nType, nVersion, T()); } -// -// others derived from vector -// +/** + * others derived from vector + */ inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion) { return GetSerializeSize((const std::vector<unsigned char>&)v, nType, nVersion); @@ -644,9 +650,9 @@ void Unserialize(Stream& is, CScript& v, int nType, int nVersion) -// -// pair -// +/** + * pair + */ template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion) { @@ -669,74 +675,9 @@ void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion) -// -// 3 tuple -// -template<typename T0, typename T1, typename T2> -unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion) -{ - unsigned int nSize = 0; - nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion); - nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion); - nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion); - return nSize; -} - -template<typename Stream, typename T0, typename T1, typename T2> -void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion) -{ - Serialize(os, boost::get<0>(item), nType, nVersion); - Serialize(os, boost::get<1>(item), nType, nVersion); - Serialize(os, boost::get<2>(item), nType, nVersion); -} - -template<typename Stream, typename T0, typename T1, typename T2> -void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion) -{ - Unserialize(is, boost::get<0>(item), nType, nVersion); - Unserialize(is, boost::get<1>(item), nType, nVersion); - Unserialize(is, boost::get<2>(item), nType, nVersion); -} - - - -// -// 4 tuple -// -template<typename T0, typename T1, typename T2, typename T3> -unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion) -{ - unsigned int nSize = 0; - nSize += GetSerializeSize(boost::get<0>(item), nType, nVersion); - nSize += GetSerializeSize(boost::get<1>(item), nType, nVersion); - nSize += GetSerializeSize(boost::get<2>(item), nType, nVersion); - nSize += GetSerializeSize(boost::get<3>(item), nType, nVersion); - return nSize; -} - -template<typename Stream, typename T0, typename T1, typename T2, typename T3> -void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion) -{ - Serialize(os, boost::get<0>(item), nType, nVersion); - Serialize(os, boost::get<1>(item), nType, nVersion); - Serialize(os, boost::get<2>(item), nType, nVersion); - Serialize(os, boost::get<3>(item), nType, nVersion); -} - -template<typename Stream, typename T0, typename T1, typename T2, typename T3> -void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion) -{ - Unserialize(is, boost::get<0>(item), nType, nVersion); - Unserialize(is, boost::get<1>(item), nType, nVersion); - Unserialize(is, boost::get<2>(item), nType, nVersion); - Unserialize(is, boost::get<3>(item), nType, nVersion); -} - - - -// -// map -// +/** + * map + */ template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion) { @@ -770,9 +711,9 @@ void Unserialize(Stream& is, std::map<K, T, Pred, A>& m, int nType, int nVersion -// -// set -// +/** + * set + */ template<typename K, typename Pred, typename A> unsigned int GetSerializeSize(const std::set<K, Pred, A>& m, int nType, int nVersion) { @@ -806,9 +747,9 @@ void Unserialize(Stream& is, std::set<K, Pred, A>& m, int nType, int nVersion) -// -// Support for ADD_SERIALIZE_METHODS and READWRITE macro -// +/** + * Support for ADD_SERIALIZE_METHODS and READWRITE macro + */ struct CSerActionSerialize { bool ForRead() const { return false; } @@ -838,8 +779,6 @@ inline void SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionU -typedef std::vector<char, zero_after_free_allocator<char> > CSerializeData; - class CSizeComputer { protected: @@ -869,515 +808,4 @@ public: } }; -/** Double ended buffer combining vector and stream-like interfaces. - * - * >> and << read and write unformatted data using the above serialization templates. - * Fills with data in linear time; some stringstream implementations take N^2 time. - */ -class CDataStream -{ -protected: - typedef CSerializeData vector_type; - vector_type vch; - unsigned int nReadPos; -public: - int nType; - int nVersion; - - typedef vector_type::allocator_type allocator_type; - typedef vector_type::size_type size_type; - typedef vector_type::difference_type difference_type; - typedef vector_type::reference reference; - typedef vector_type::const_reference const_reference; - typedef vector_type::value_type value_type; - typedef vector_type::iterator iterator; - typedef vector_type::const_iterator const_iterator; - typedef vector_type::reverse_iterator reverse_iterator; - - explicit CDataStream(int nTypeIn, int nVersionIn) - { - Init(nTypeIn, nVersionIn); - } - - CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) - { - Init(nTypeIn, nVersionIn); - } - -#if !defined(_MSC_VER) || _MSC_VER >= 1300 - CDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) - { - Init(nTypeIn, nVersionIn); - } -#endif - - CDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) - { - Init(nTypeIn, nVersionIn); - } - - CDataStream(const std::vector<char>& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) - { - Init(nTypeIn, nVersionIn); - } - - CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn, int nVersionIn) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) - { - Init(nTypeIn, nVersionIn); - } - - void Init(int nTypeIn, int nVersionIn) - { - nReadPos = 0; - nType = nTypeIn; - nVersion = nVersionIn; - } - - CDataStream& operator+=(const CDataStream& b) - { - vch.insert(vch.end(), b.begin(), b.end()); - return *this; - } - - friend CDataStream operator+(const CDataStream& a, const CDataStream& b) - { - CDataStream ret = a; - ret += b; - return (ret); - } - - std::string str() const - { - return (std::string(begin(), end())); - } - - - // - // Vector subset - // - const_iterator begin() const { return vch.begin() + nReadPos; } - iterator begin() { return vch.begin() + nReadPos; } - const_iterator end() const { return vch.end(); } - iterator end() { return vch.end(); } - size_type size() const { return vch.size() - nReadPos; } - bool empty() const { return vch.size() == nReadPos; } - void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); } - void reserve(size_type n) { vch.reserve(n + nReadPos); } - const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; } - reference operator[](size_type pos) { return vch[pos + nReadPos]; } - void clear() { vch.clear(); nReadPos = 0; } - iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); } - void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); } - - void insert(iterator it, std::vector<char>::const_iterator first, std::vector<char>::const_iterator last) - { - assert(last - first >= 0); - if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) - { - // special case for inserting at the front when there's room - nReadPos -= (last - first); - memcpy(&vch[nReadPos], &first[0], last - first); - } - else - vch.insert(it, first, last); - } - -#if !defined(_MSC_VER) || _MSC_VER >= 1300 - void insert(iterator it, const char* first, const char* last) - { - assert(last - first >= 0); - if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) - { - // special case for inserting at the front when there's room - nReadPos -= (last - first); - memcpy(&vch[nReadPos], &first[0], last - first); - } - else - vch.insert(it, first, last); - } -#endif - - iterator erase(iterator it) - { - if (it == vch.begin() + nReadPos) - { - // special case for erasing from the front - if (++nReadPos >= vch.size()) - { - // whenever we reach the end, we take the opportunity to clear the buffer - nReadPos = 0; - return vch.erase(vch.begin(), vch.end()); - } - return vch.begin() + nReadPos; - } - else - return vch.erase(it); - } - - iterator erase(iterator first, iterator last) - { - if (first == vch.begin() + nReadPos) - { - // special case for erasing from the front - if (last == vch.end()) - { - nReadPos = 0; - return vch.erase(vch.begin(), vch.end()); - } - else - { - nReadPos = (last - vch.begin()); - return last; - } - } - else - return vch.erase(first, last); - } - - inline void Compact() - { - vch.erase(vch.begin(), vch.begin() + nReadPos); - nReadPos = 0; - } - - bool Rewind(size_type n) - { - // Rewind by n characters if the buffer hasn't been compacted yet - if (n > nReadPos) - return false; - nReadPos -= n; - return true; - } - - - // - // Stream subset - // - bool eof() const { return size() == 0; } - CDataStream* rdbuf() { return this; } - int in_avail() { return size(); } - - void SetType(int n) { nType = n; } - int GetType() { return nType; } - void SetVersion(int n) { nVersion = n; } - int GetVersion() { return nVersion; } - void ReadVersion() { *this >> nVersion; } - void WriteVersion() { *this << nVersion; } - - CDataStream& read(char* pch, size_t nSize) - { - // Read from the beginning of the buffer - unsigned int nReadPosNext = nReadPos + nSize; - if (nReadPosNext >= vch.size()) - { - if (nReadPosNext > vch.size()) - { - throw std::ios_base::failure("CDataStream::read() : end of data"); - } - memcpy(pch, &vch[nReadPos], nSize); - nReadPos = 0; - vch.clear(); - return (*this); - } - memcpy(pch, &vch[nReadPos], nSize); - nReadPos = nReadPosNext; - return (*this); - } - - CDataStream& ignore(int nSize) - { - // Ignore from the beginning of the buffer - assert(nSize >= 0); - unsigned int nReadPosNext = nReadPos + nSize; - if (nReadPosNext >= vch.size()) - { - if (nReadPosNext > vch.size()) - throw std::ios_base::failure("CDataStream::ignore() : end of data"); - nReadPos = 0; - vch.clear(); - return (*this); - } - nReadPos = nReadPosNext; - return (*this); - } - - CDataStream& write(const char* pch, size_t nSize) - { - // Write to the end of the buffer - vch.insert(vch.end(), pch, pch + nSize); - return (*this); - } - - template<typename Stream> - void Serialize(Stream& s, int nType, int nVersion) const - { - // Special case: stream << stream concatenates like stream += stream - if (!vch.empty()) - s.write((char*)&vch[0], vch.size() * sizeof(vch[0])); - } - - template<typename T> - unsigned int GetSerializeSize(const T& obj) - { - // Tells the size of the object if serialized to this stream - return ::GetSerializeSize(obj, nType, nVersion); - } - - template<typename T> - CDataStream& operator<<(const T& obj) - { - // Serialize to this stream - ::Serialize(*this, obj, nType, nVersion); - return (*this); - } - - template<typename T> - CDataStream& operator>>(T& obj) - { - // Unserialize from this stream - ::Unserialize(*this, obj, nType, nVersion); - return (*this); - } - - void GetAndClear(CSerializeData &data) { - data.insert(data.end(), begin(), end()); - clear(); - } -}; - - - - - - - - - - -/** RAII wrapper for FILE*. - * - * Will automatically close the file when it goes out of scope if not null. - * If you're returning the file pointer, return file.release(). - * If you need to close the file early, use file.fclose() instead of fclose(file). - */ -class CAutoFile -{ -protected: - FILE* file; -public: - int nType; - int nVersion; - - CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn) - { - file = filenew; - nType = nTypeIn; - nVersion = nVersionIn; - } - - ~CAutoFile() - { - fclose(); - } - - void fclose() - { - if (file != NULL && file != stdin && file != stdout && file != stderr) - ::fclose(file); - file = NULL; - } - - FILE* release() { FILE* ret = file; file = NULL; return ret; } - operator FILE*() { return file; } - FILE* operator->() { return file; } - FILE& operator*() { return *file; } - FILE** operator&() { return &file; } - FILE* operator=(FILE* pnew) { return file = pnew; } - bool operator!() { return (file == NULL); } - - - // - // Stream subset - // - void SetType(int n) { nType = n; } - int GetType() { return nType; } - void SetVersion(int n) { nVersion = n; } - int GetVersion() { return nVersion; } - void ReadVersion() { *this >> nVersion; } - void WriteVersion() { *this << nVersion; } - - CAutoFile& read(char* pch, size_t nSize) - { - if (!file) - throw std::ios_base::failure("CAutoFile::read : file handle is NULL"); - if (fread(pch, 1, nSize, file) != nSize) - throw std::ios_base::failure(feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed"); - return (*this); - } - - CAutoFile& write(const char* pch, size_t nSize) - { - if (!file) - throw std::ios_base::failure("CAutoFile::write : file handle is NULL"); - if (fwrite(pch, 1, nSize, file) != nSize) - throw std::ios_base::failure("CAutoFile::write : write failed"); - return (*this); - } - - template<typename T> - unsigned int GetSerializeSize(const T& obj) - { - // Tells the size of the object if serialized to this stream - return ::GetSerializeSize(obj, nType, nVersion); - } - - template<typename T> - CAutoFile& operator<<(const T& obj) - { - // Serialize to this stream - if (!file) - throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL"); - ::Serialize(*this, obj, nType, nVersion); - return (*this); - } - - template<typename T> - CAutoFile& operator>>(T& obj) - { - // Unserialize from this stream - if (!file) - throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL"); - ::Unserialize(*this, obj, nType, nVersion); - return (*this); - } -}; - -/** Wrapper around a FILE* that implements a ring buffer to - * deserialize from. It guarantees the ability to rewind - * a given number of bytes. */ -class CBufferedFile -{ -private: - FILE *src; // source file - uint64_t nSrcPos; // how many bytes have been read from source - uint64_t nReadPos; // how many bytes have been read from this - uint64_t nReadLimit; // up to which position we're allowed to read - uint64_t nRewind; // how many bytes we guarantee to rewind - std::vector<char> vchBuf; // the buffer - -protected: - // read data from the source to fill the buffer - bool Fill() { - unsigned int pos = nSrcPos % vchBuf.size(); - unsigned int readNow = vchBuf.size() - pos; - unsigned int nAvail = vchBuf.size() - (nSrcPos - nReadPos) - nRewind; - if (nAvail < readNow) - readNow = nAvail; - if (readNow == 0) - return false; - size_t read = fread((void*)&vchBuf[pos], 1, readNow, src); - if (read == 0) { - throw std::ios_base::failure(feof(src) ? "CBufferedFile::Fill : end of file" : "CBufferedFile::Fill : fread failed"); - } else { - nSrcPos += read; - return true; - } - } - -public: - int nType; - int nVersion; - - CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) : - src(fileIn), nSrcPos(0), nReadPos(0), nReadLimit((uint64_t)(-1)), nRewind(nRewindIn), vchBuf(nBufSize, 0), - nType(nTypeIn), nVersion(nVersionIn) { - } - - // check whether we're at the end of the source file - bool eof() const { - return nReadPos == nSrcPos && feof(src); - } - - // read a number of bytes - CBufferedFile& read(char *pch, size_t nSize) { - if (nSize + nReadPos > nReadLimit) - throw std::ios_base::failure("Read attempted past buffer limit"); - if (nSize + nRewind > vchBuf.size()) - throw std::ios_base::failure("Read larger than buffer size"); - while (nSize > 0) { - if (nReadPos == nSrcPos) - Fill(); - unsigned int pos = nReadPos % vchBuf.size(); - size_t nNow = nSize; - if (nNow + pos > vchBuf.size()) - nNow = vchBuf.size() - pos; - if (nNow + nReadPos > nSrcPos) - nNow = nSrcPos - nReadPos; - memcpy(pch, &vchBuf[pos], nNow); - nReadPos += nNow; - pch += nNow; - nSize -= nNow; - } - return (*this); - } - - // return the current reading position - uint64_t GetPos() { - return nReadPos; - } - - // rewind to a given reading position - bool SetPos(uint64_t nPos) { - nReadPos = nPos; - if (nReadPos + nRewind < nSrcPos) { - nReadPos = nSrcPos - nRewind; - return false; - } else if (nReadPos > nSrcPos) { - nReadPos = nSrcPos; - return false; - } else { - return true; - } - } - - bool Seek(uint64_t nPos) { - long nLongPos = nPos; - if (nPos != (uint64_t)nLongPos) - return false; - if (fseek(src, nLongPos, SEEK_SET)) - return false; - nLongPos = ftell(src); - nSrcPos = nLongPos; - nReadPos = nLongPos; - return true; - } - - // prevent reading beyond a certain position - // no argument removes the limit - bool SetLimit(uint64_t nPos = (uint64_t)(-1)) { - if (nPos < nReadPos) - return false; - nReadLimit = nPos; - return true; - } - - template<typename T> - CBufferedFile& operator>>(T& obj) { - // Unserialize from this stream - ::Unserialize(*this, obj, nType, nVersion); - return (*this); - } - - // search for a given byte in the stream, and remain positioned on it - void FindByte(char ch) { - while (true) { - if (nReadPos == nSrcPos) - Fill(); - if (vchBuf[nReadPos % vchBuf.size()] == ch) - break; - nReadPos++; - } - } -}; - #endif // BITCOIN_SERIALIZE_H diff --git a/src/streams.h b/src/streams.h new file mode 100644 index 0000000000..6bd6d2b920 --- /dev/null +++ b/src/streams.h @@ -0,0 +1,571 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-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_STREAMS_H +#define BITCOIN_STREAMS_H + +#include "allocators.h" +#include "serialize.h" + +#include <algorithm> +#include <assert.h> +#include <ios> +#include <limits> +#include <map> +#include <set> +#include <stdint.h> +#include <string> +#include <string.h> +#include <utility> +#include <vector> + +/** Double ended buffer combining vector and stream-like interfaces. + * + * >> and << read and write unformatted data using the above serialization templates. + * Fills with data in linear time; some stringstream implementations take N^2 time. + */ +class CDataStream +{ +protected: + typedef CSerializeData vector_type; + vector_type vch; + unsigned int nReadPos; +public: + int nType; + int nVersion; + + typedef vector_type::allocator_type allocator_type; + typedef vector_type::size_type size_type; + typedef vector_type::difference_type difference_type; + typedef vector_type::reference reference; + typedef vector_type::const_reference const_reference; + typedef vector_type::value_type value_type; + typedef vector_type::iterator iterator; + typedef vector_type::const_iterator const_iterator; + typedef vector_type::reverse_iterator reverse_iterator; + + explicit CDataStream(int nTypeIn, int nVersionIn) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + CDataStream(const char* pbegin, const char* pend, int nTypeIn, int nVersionIn) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } +#endif + + CDataStream(const vector_type& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const std::vector<char>& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const std::vector<unsigned char>& vchIn, int nTypeIn, int nVersionIn) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + void Init(int nTypeIn, int nVersionIn) + { + nReadPos = 0; + nType = nTypeIn; + nVersion = nVersionIn; + } + + CDataStream& operator+=(const CDataStream& b) + { + vch.insert(vch.end(), b.begin(), b.end()); + return *this; + } + + friend CDataStream operator+(const CDataStream& a, const CDataStream& b) + { + CDataStream ret = a; + ret += b; + return (ret); + } + + std::string str() const + { + return (std::string(begin(), end())); + } + + + // + // Vector subset + // + const_iterator begin() const { return vch.begin() + nReadPos; } + iterator begin() { return vch.begin() + nReadPos; } + const_iterator end() const { return vch.end(); } + iterator end() { return vch.end(); } + size_type size() const { return vch.size() - nReadPos; } + bool empty() const { return vch.size() == nReadPos; } + void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); } + void reserve(size_type n) { vch.reserve(n + nReadPos); } + const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; } + reference operator[](size_type pos) { return vch[pos + nReadPos]; } + void clear() { vch.clear(); nReadPos = 0; } + iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); } + void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); } + + void insert(iterator it, std::vector<char>::const_iterator first, std::vector<char>::const_iterator last) + { + assert(last - first >= 0); + if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + void insert(iterator it, const char* first, const char* last) + { + assert(last - first >= 0); + if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } +#endif + + iterator erase(iterator it) + { + if (it == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (++nReadPos >= vch.size()) + { + // whenever we reach the end, we take the opportunity to clear the buffer + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + return vch.begin() + nReadPos; + } + else + return vch.erase(it); + } + + iterator erase(iterator first, iterator last) + { + if (first == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (last == vch.end()) + { + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + else + { + nReadPos = (last - vch.begin()); + return last; + } + } + else + return vch.erase(first, last); + } + + inline void Compact() + { + vch.erase(vch.begin(), vch.begin() + nReadPos); + nReadPos = 0; + } + + bool Rewind(size_type n) + { + // Rewind by n characters if the buffer hasn't been compacted yet + if (n > nReadPos) + return false; + nReadPos -= n; + return true; + } + + + // + // Stream subset + // + bool eof() const { return size() == 0; } + CDataStream* rdbuf() { return this; } + int in_avail() { return size(); } + + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CDataStream& read(char* pch, size_t nSize) + { + // Read from the beginning of the buffer + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + { + throw std::ios_base::failure("CDataStream::read() : end of data"); + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = 0; + vch.clear(); + return (*this); + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& ignore(int nSize) + { + // Ignore from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + throw std::ios_base::failure("CDataStream::ignore() : end of data"); + nReadPos = 0; + vch.clear(); + return (*this); + } + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& write(const char* pch, size_t nSize) + { + // Write to the end of the buffer + vch.insert(vch.end(), pch, pch + nSize); + return (*this); + } + + template<typename Stream> + void Serialize(Stream& s, int nType, int nVersion) const + { + // Special case: stream << stream concatenates like stream += stream + if (!vch.empty()) + s.write((char*)&vch[0], vch.size() * sizeof(vch[0])); + } + + template<typename T> + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template<typename T> + CDataStream& operator<<(const T& obj) + { + // Serialize to this stream + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template<typename T> + CDataStream& operator>>(T& obj) + { + // Unserialize from this stream + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } + + void GetAndClear(CSerializeData &data) { + data.insert(data.end(), begin(), end()); + clear(); + } +}; + + + + + + + + + + +/** Non-refcounted RAII wrapper for FILE* + * + * Will automatically close the file when it goes out of scope if not null. + * If you're returning the file pointer, return file.release(). + * If you need to close the file early, use file.fclose() instead of fclose(file). + */ +class CAutoFile +{ +private: + // Disallow copies + CAutoFile(const CAutoFile&); + CAutoFile& operator=(const CAutoFile&); + + int nType; + int nVersion; + + FILE* file; + +public: + CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn) + { + file = filenew; + nType = nTypeIn; + nVersion = nVersionIn; + } + + ~CAutoFile() + { + fclose(); + } + + void fclose() + { + if (file) { + ::fclose(file); + file = NULL; + } + } + + /** Get wrapped FILE* with transfer of ownership. + * @note This will invalidate the CAutoFile object, and makes it the responsibility of the caller + * of this function to clean up the returned FILE*. + */ + FILE* release() { FILE* ret = file; file = NULL; return ret; } + + /** Get wrapped FILE* without transfer of ownership. + * @note Ownership of the FILE* will remain with this class. Use this only if the scope of the + * CAutoFile outlives use of the passed pointer. + */ + FILE* Get() const { return file; } + + /** Return true if the wrapped FILE* is NULL, false otherwise. + */ + bool IsNull() const { return (file == NULL); } + + // + // Stream subset + // + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CAutoFile& read(char* pch, size_t nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::read : file handle is NULL"); + if (fread(pch, 1, nSize, file) != nSize) + throw std::ios_base::failure(feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed"); + return (*this); + } + + CAutoFile& write(const char* pch, size_t nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::write : file handle is NULL"); + if (fwrite(pch, 1, nSize, file) != nSize) + throw std::ios_base::failure("CAutoFile::write : write failed"); + return (*this); + } + + template<typename T> + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template<typename T> + CAutoFile& operator<<(const T& obj) + { + // Serialize to this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL"); + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template<typename T> + CAutoFile& operator>>(T& obj) + { + // Unserialize from this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL"); + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } +}; + +/** Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to + * deserialize from. It guarantees the ability to rewind a given number of bytes. + * + * Will automatically close the file when it goes out of scope if not null. + * If you need to close the file early, use file.fclose() instead of fclose(file). + */ +class CBufferedFile +{ +private: + // Disallow copies + CBufferedFile(const CBufferedFile&); + CBufferedFile& operator=(const CBufferedFile&); + + int nType; + int nVersion; + + FILE *src; // source file + uint64_t nSrcPos; // how many bytes have been read from source + uint64_t nReadPos; // how many bytes have been read from this + uint64_t nReadLimit; // up to which position we're allowed to read + uint64_t nRewind; // how many bytes we guarantee to rewind + std::vector<char> vchBuf; // the buffer + +protected: + // read data from the source to fill the buffer + bool Fill() { + unsigned int pos = nSrcPos % vchBuf.size(); + unsigned int readNow = vchBuf.size() - pos; + unsigned int nAvail = vchBuf.size() - (nSrcPos - nReadPos) - nRewind; + if (nAvail < readNow) + readNow = nAvail; + if (readNow == 0) + return false; + size_t read = fread((void*)&vchBuf[pos], 1, readNow, src); + if (read == 0) { + throw std::ios_base::failure(feof(src) ? "CBufferedFile::Fill : end of file" : "CBufferedFile::Fill : fread failed"); + } else { + nSrcPos += read; + return true; + } + } + +public: + CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) : + nSrcPos(0), nReadPos(0), nReadLimit((uint64_t)(-1)), nRewind(nRewindIn), vchBuf(nBufSize, 0) + { + src = fileIn; + nType = nTypeIn; + nVersion = nVersionIn; + } + + ~CBufferedFile() + { + fclose(); + } + + void fclose() + { + if (src) { + ::fclose(src); + src = NULL; + } + } + + // check whether we're at the end of the source file + bool eof() const { + return nReadPos == nSrcPos && feof(src); + } + + // read a number of bytes + CBufferedFile& read(char *pch, size_t nSize) { + if (nSize + nReadPos > nReadLimit) + throw std::ios_base::failure("Read attempted past buffer limit"); + if (nSize + nRewind > vchBuf.size()) + throw std::ios_base::failure("Read larger than buffer size"); + while (nSize > 0) { + if (nReadPos == nSrcPos) + Fill(); + unsigned int pos = nReadPos % vchBuf.size(); + size_t nNow = nSize; + if (nNow + pos > vchBuf.size()) + nNow = vchBuf.size() - pos; + if (nNow + nReadPos > nSrcPos) + nNow = nSrcPos - nReadPos; + memcpy(pch, &vchBuf[pos], nNow); + nReadPos += nNow; + pch += nNow; + nSize -= nNow; + } + return (*this); + } + + // return the current reading position + uint64_t GetPos() { + return nReadPos; + } + + // rewind to a given reading position + bool SetPos(uint64_t nPos) { + nReadPos = nPos; + if (nReadPos + nRewind < nSrcPos) { + nReadPos = nSrcPos - nRewind; + return false; + } else if (nReadPos > nSrcPos) { + nReadPos = nSrcPos; + return false; + } else { + return true; + } + } + + bool Seek(uint64_t nPos) { + long nLongPos = nPos; + if (nPos != (uint64_t)nLongPos) + return false; + if (fseek(src, nLongPos, SEEK_SET)) + return false; + nLongPos = ftell(src); + nSrcPos = nLongPos; + nReadPos = nLongPos; + return true; + } + + // prevent reading beyond a certain position + // no argument removes the limit + bool SetLimit(uint64_t nPos = (uint64_t)(-1)) { + if (nPos < nReadPos) + return false; + nReadLimit = nPos; + return true; + } + + template<typename T> + CBufferedFile& operator>>(T& obj) { + // Unserialize from this stream + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } + + // search for a given byte in the stream, and remain positioned on it + void FindByte(char ch) { + while (true) { + if (nReadPos == nSrcPos) + Fill(); + if (vchBuf[nReadPos % vchBuf.size()] == ch) + break; + nReadPos++; + } + } +}; + +#endif // BITCOIN_STREAMS_H diff --git a/src/sync.cpp b/src/sync.cpp index ef35c9d646..e28caee8e7 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2011-2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2011-2012 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "sync.h" diff --git a/src/sync.h b/src/sync.h index cd0aa7b20e..7891e41560 100644 --- a/src/sync.h +++ b/src/sync.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-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_SYNC_H diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index 8f70f18c7c..4ea6a91d54 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index 7bec12b665..9407511ecb 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // @@ -106,51 +106,6 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) BOOST_CHECK(!CNode::IsBanned(addr)); } -static bool CheckNBits(unsigned int nbits1, int64_t time1, unsigned int nbits2, int64_t time2)\ -{ - if (time1 > time2) - return CheckNBits(nbits2, time2, nbits1, time1); - int64_t deltaTime = time2-time1; - - return CheckMinWork(nbits2, nbits1, deltaTime); -} - -BOOST_AUTO_TEST_CASE(DoS_checknbits) -{ - using namespace boost::assign; // for 'map_list_of()' - - // Timestamps,nBits from the bitcoin block chain. - // These are the block-chain checkpoint blocks - typedef std::map<int64_t, unsigned int> BlockData; - BlockData chainData = - map_list_of(1239852051,486604799)(1262749024,486594666) - (1279305360,469854461)(1280200847,469830746)(1281678674,469809688) - (1296207707,453179945)(1302624061,453036989)(1309640330,437004818) - (1313172719,436789733); - - // Make sure CheckNBits considers every combination of block-chain-lock-in-points - // "sane": - BOOST_FOREACH(const BlockData::value_type& i, chainData) - { - BOOST_FOREACH(const BlockData::value_type& j, chainData) - { - BOOST_CHECK(CheckNBits(i.second, i.first, j.second, j.first)); - } - } - - // Test a couple of insane combinations: - BlockData::value_type firstcheck = *(chainData.begin()); - BlockData::value_type lastcheck = *(chainData.rbegin()); - - // First checkpoint difficulty at or a while after the last checkpoint time should fail when - // compared to last checkpoint - BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*10, lastcheck.second, lastcheck.first)); - BOOST_CHECK(!CheckNBits(firstcheck.second, lastcheck.first+60*60*24*14, lastcheck.second, lastcheck.first)); - - // ... but OK if enough time passed for difficulty to adjust downward: - BOOST_CHECK(CheckNBits(firstcheck.second, lastcheck.first+60*60*24*365*4, lastcheck.second, lastcheck.first)); -} - CTransaction RandomOrphan() { std::map<uint256, COrphanTx>::iterator it; diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp index 4bee0f6b6e..bed63991e6 100644 --- a/src/test/accounting_tests.cpp +++ b/src/test/accounting_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "wallet.h" @@ -15,7 +15,7 @@ extern CWallet* pwalletMain; BOOST_AUTO_TEST_SUITE(accounting_tests) static void -GetResults(CWalletDB& walletdb, std::map<int64_t, CAccountingEntry>& results) +GetResults(CWalletDB& walletdb, std::map<CAmount, CAccountingEntry>& results) { std::list<CAccountingEntry> aes; @@ -34,7 +34,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) std::vector<CWalletTx*> vpwtx; CWalletTx wtx; CAccountingEntry ae; - std::map<int64_t, CAccountingEntry> results; + std::map<CAmount, CAccountingEntry> results; LOCK(pwalletMain->cs_wallet); diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index 4af87cf8ef..efc9211717 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // @@ -7,12 +7,13 @@ // #include "alert.h" +#include "clientversion.h" #include "data/alertTests.raw.h" #include "serialize.h" +#include "streams.h" #include "util.h" #include "utilstrencodings.h" -#include "version.h" #include <fstream> @@ -91,7 +92,7 @@ struct ReadAlerts alerts.push_back(alert); } } - catch (std::exception) { } + catch (const std::exception&) { } } ~ReadAlerts() { } @@ -153,9 +154,6 @@ BOOST_AUTO_TEST_CASE(AlertApplies) } -// This uses sh 'echo' to test the -alertnotify function, writing to a -// /tmp file. So skip it on Windows: -#ifndef WIN32 BOOST_AUTO_TEST_CASE(AlertNotify) { SetMockTime(11); @@ -170,15 +168,24 @@ BOOST_AUTO_TEST_CASE(AlertNotify) std::vector<std::string> r = read_lines(temp); BOOST_CHECK_EQUAL(r.size(), 4u); + +// Windows built-in echo semantics are different than posixy shells. Quotes and +// whitespace are printed literally. + +#ifndef WIN32 BOOST_CHECK_EQUAL(r[0], "Alert 1"); BOOST_CHECK_EQUAL(r[1], "Alert 2, cancels 1"); BOOST_CHECK_EQUAL(r[2], "Alert 2, cancels 1"); BOOST_CHECK_EQUAL(r[3], "Evil Alert; /bin/ls; echo "); // single-quotes should be removed - +#else + BOOST_CHECK_EQUAL(r[0], "'Alert 1' "); + BOOST_CHECK_EQUAL(r[1], "'Alert 2, cancels 1' "); + BOOST_CHECK_EQUAL(r[2], "'Alert 2, cancels 1' "); + BOOST_CHECK_EQUAL(r[3], "'Evil Alert; /bin/ls; echo ' "); +#endif boost::filesystem::remove(temp); SetMockTime(0); } -#endif BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index 69888da3df..991b4ac099 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "util.h" diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp index 68617abbdd..5d20a90ad0 100644 --- a/src/test/base32_tests.cpp +++ b/src/test/base32_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "utilstrencodings.h" diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index fe68e9e974..e7d0281881 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" @@ -12,6 +12,7 @@ #include "script/script.h" #include "uint256.h" #include "util.h" +#include "utilstrencodings.h" #include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> @@ -40,7 +41,7 @@ BOOST_AUTO_TEST_CASE(base58_EncodeBase58) std::vector<unsigned char> sourcedata = ParseHex(test[0].get_str()); std::string base58string = test[1].get_str(); BOOST_CHECK_MESSAGE( - EncodeBase58(&sourcedata[0], &sourcedata[sourcedata.size()]) == base58string, + EncodeBase58(begin_ptr(sourcedata), end_ptr(sourcedata)) == base58string, strTest); } } @@ -175,7 +176,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest); } } - SelectParams(CBaseChainParams::MAIN); + SelectParams(CBaseChainParams::UNITTEST); } // Goal: check that generated keys match test vectors @@ -243,7 +244,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) CTxDestination nodest = CNoDestination(); BOOST_CHECK(!dummyAddr.Set(nodest)); - SelectParams(CBaseChainParams::MAIN); + SelectParams(CBaseChainParams::UNITTEST); } // Goal: check that base58 parsing code is robust against a variety of corrupted data diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp index f2bf3326ad..9e6cb342cc 100644 --- a/src/test/base64_tests.cpp +++ b/src/test/base64_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "utilstrencodings.h" diff --git a/src/test/bctest.py b/src/test/bctest.py index 1839f4fef4..3a8d0ea51b 100644 --- a/src/test/bctest.py +++ b/src/test/bctest.py @@ -1,5 +1,5 @@ # Copyright 2014 BitPay, Inc. -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. import subprocess @@ -7,9 +7,11 @@ import os import json import sys -def bctest(testDir, testObj): - execargs = testObj['exec'] +def bctest(testDir, testObj, exeext): + execprog = testObj['exec'] + exeext + execargs = testObj['args'] + execrun = [execprog] + execargs stdinCfg = None inputData = None if "input" in testObj: @@ -22,12 +24,11 @@ def bctest(testDir, testObj): if "output_cmp" in testObj: outputFn = testObj['output_cmp'] outputData = open(testDir + "/" + outputFn).read() - - proc = subprocess.Popen(execargs, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + proc = subprocess.Popen(execrun, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True) try: outs = proc.communicate(input=inputData) except OSError: - print("OSError, Failed to execute " + execargs[0]) + print("OSError, Failed to execute " + execprog) sys.exit(1) if outputData and (outs[0] != outputData): @@ -41,13 +42,13 @@ def bctest(testDir, testObj): print("Return code mismatch for " + outputFn) sys.exit(1) -def bctester(testDir, input_basename): +def bctester(testDir, input_basename, buildenv): input_filename = testDir + "/" + input_basename raw_data = open(input_filename).read() input_data = json.loads(raw_data) for testObj in input_data: - bctest(testDir, testObj) + bctest(testDir, testObj, buildenv.exeext) sys.exit(0) diff --git a/src/test/bignum.h b/src/test/bignum.h index a75f5250fa..365b17a1c5 100644 --- a/src/test/bignum.h +++ b/src/test/bignum.h @@ -1,10 +1,10 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-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_BIGNUM_H -#define BITCOIN_BIGNUM_H +#ifndef BITCOIN_TEST_BIGNUM_H +#define BITCOIN_TEST_BIGNUM_H #include <algorithm> #include <limits> @@ -63,11 +63,11 @@ public: int getint() const { - unsigned long n = BN_get_word(this); + BN_ULONG n = BN_get_word(this); if (!BN_is_negative(this)) - return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n); + return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n); else - return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n); + return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n); } void setint64(int64_t sn) @@ -177,4 +177,4 @@ inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); } inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); } -#endif +#endif // BITCOIN_TEST_BIGNUM_H diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 9cf07fc38c..3d28e06ffc 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <boost/test/unit_test.hpp> diff --git a/src/test/bitcoin-util-test.py b/src/test/bitcoin-util-test.py index 40690c2fed..20afb16a9e 100755 --- a/src/test/bitcoin-util-test.py +++ b/src/test/bitcoin-util-test.py @@ -1,12 +1,13 @@ #!/usr/bin/python # Copyright 2014 BitPay, Inc. -# Distributed under the MIT/X11 software license, see the accompanying +# Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. import os import bctest +import buildenv if __name__ == '__main__': bctest.bctester(os.environ["srcdir"] + "/test/data", - "bitcoin-util-test.json") + "bitcoin-util-test.json",buildenv) diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 2cdafa4bdd..c32098efa0 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -1,19 +1,23 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "bloom.h" #include "base58.h" +#include "clientversion.h" #include "key.h" -#include "main.h" +#include "merkleblock.h" #include "serialize.h" +#include "streams.h" #include "uint256.h" #include "util.h" +#include "utilstrencodings.h" #include <vector> #include <boost/test/unit_test.hpp> +#include <boost/tuple/tuple.hpp> using namespace std; using namespace boost::tuples; diff --git a/src/test/buildenv.py.in b/src/test/buildenv.py.in new file mode 100644 index 0000000000..1618bdeb76 --- /dev/null +++ b/src/test/buildenv.py.in @@ -0,0 +1,2 @@ +#!/usr/bin/python +exeext="@EXEEXT@" diff --git a/src/test/canonical_tests.cpp b/src/test/canonical_tests.cpp deleted file mode 100644 index a17099de72..0000000000 --- a/src/test/canonical_tests.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -// -// Unit tests for canonical signatures -// - -#include "data/sig_noncanonical.json.h" -#include "data/sig_canonical.json.h" -#include "key.h" -#include "random.h" -#include "script/interpreter.h" -#include "util.h" -#include "utilstrencodings.h" - -#include <boost/foreach.hpp> -#include <boost/test/unit_test.hpp> -#include "json/json_spirit_writer_template.h" -#include <openssl/ecdsa.h> - -using namespace std; -using namespace json_spirit; - -// In script_tests.cpp -extern Array read_json(const std::string& jsondata); - -BOOST_AUTO_TEST_SUITE(canonical_tests) - -// OpenSSL-based test for canonical signature (without test for hashtype byte) -bool static IsCanonicalSignature_OpenSSL_inner(const std::vector<unsigned char>& vchSig) -{ - if (vchSig.size() == 0) - return false; - const unsigned char *input = &vchSig[0]; - ECDSA_SIG *psig = NULL; - d2i_ECDSA_SIG(&psig, &input, vchSig.size()); - if (psig == NULL) - return false; - unsigned char buf[256]; - unsigned char *pbuf = buf; - unsigned int nLen = i2d_ECDSA_SIG(psig, NULL); - if (nLen != vchSig.size()) { - ECDSA_SIG_free(psig); - return false; - } - nLen = i2d_ECDSA_SIG(psig, &pbuf); - ECDSA_SIG_free(psig); - return (memcmp(&vchSig[0], &buf[0], nLen) == 0); -} - -// OpenSSL-based test for canonical signature -bool static IsCanonicalSignature_OpenSSL(const std::vector<unsigned char> &vchSignature) { - if (vchSignature.size() < 1) - return false; - if (vchSignature.size() > 127) - return false; - if (vchSignature[vchSignature.size() - 1] & 0x7C) - return false; - - std::vector<unsigned char> vchSig(vchSignature); - vchSig.pop_back(); - if (!IsCanonicalSignature_OpenSSL_inner(vchSig)) - return false; - return true; -} - -BOOST_AUTO_TEST_CASE(script_canon) -{ - Array tests = read_json(std::string(json_tests::sig_canonical, json_tests::sig_canonical + sizeof(json_tests::sig_canonical))); - - BOOST_FOREACH(Value &tv, tests) { - string test = tv.get_str(); - if (IsHex(test)) { - std::vector<unsigned char> sig = ParseHex(test); - BOOST_CHECK_MESSAGE(IsCanonicalSignature(sig, SCRIPT_VERIFY_STRICTENC), test); - BOOST_CHECK_MESSAGE(IsCanonicalSignature_OpenSSL(sig), test); - } - } -} - -BOOST_AUTO_TEST_CASE(script_noncanon) -{ - Array tests = read_json(std::string(json_tests::sig_noncanonical, json_tests::sig_noncanonical + sizeof(json_tests::sig_noncanonical))); - - BOOST_FOREACH(Value &tv, tests) { - string test = tv.get_str(); - if (IsHex(test)) { - std::vector<unsigned char> sig = ParseHex(test); - BOOST_CHECK_MESSAGE(!IsCanonicalSignature(sig, SCRIPT_VERIFY_STRICTENC), test); - BOOST_CHECK_MESSAGE(!IsCanonicalSignature_OpenSSL(sig), test); - } - } -} - -BOOST_AUTO_TEST_CASE(script_signstrict) -{ - for (int i=0; i<100; i++) { - CKey key; - key.MakeNewKey(i & 1); - std::vector<unsigned char> sig; - uint256 hash = GetRandHash(); - - BOOST_CHECK(key.Sign(hash, sig)); // Generate a random signature. - BOOST_CHECK(key.GetPubKey().Verify(hash, sig)); // Check it. - sig.push_back(0x01); // Append a sighash type. - - BOOST_CHECK(IsCanonicalSignature(sig, SCRIPT_VERIFY_STRICTENC | SCRIPT_VERIFY_LOW_S)); - BOOST_CHECK(IsCanonicalSignature_OpenSSL(sig)); - } -} - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp index fdea12846a..a4121caa8b 100644 --- a/src/test/checkblock_tests.cpp +++ b/src/test/checkblock_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2013-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // @@ -8,6 +8,7 @@ +#include "clientversion.h" #include "main.h" #include "utiltime.h" @@ -35,8 +36,8 @@ bool read_block(const std::string& filename, CBlock& block) fseek(fp, 8, SEEK_SET); // skip msgheader/size - CAutoFile filein = CAutoFile(fp, SER_DISK, CLIENT_VERSION); - if (!filein) return false; + CAutoFile filein(fp, SER_DISK, CLIENT_VERSION); + if (filein.IsNull()) return false; filein >> block; diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp new file mode 100644 index 0000000000..3ecd301bc7 --- /dev/null +++ b/src/test/coins_tests.cpp @@ -0,0 +1,178 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "coins.h" +#include "random.h" +#include "uint256.h" + +#include <vector> +#include <map> + +#include <boost/test/unit_test.hpp> + +namespace +{ +class CCoinsViewTest : public CCoinsView +{ + uint256 hashBestBlock_; + std::map<uint256, CCoins> map_; + +public: + bool GetCoins(const uint256& txid, CCoins& coins) const + { + std::map<uint256, CCoins>::const_iterator it = map_.find(txid); + if (it == map_.end()) { + return false; + } + coins = it->second; + if (coins.IsPruned() && insecure_rand() % 2 == 0) { + // Randomly return false in case of an empty entry. + return false; + } + return true; + } + + bool HaveCoins(const uint256& txid) const + { + CCoins coins; + return GetCoins(txid, coins); + } + + uint256 GetBestBlock() const { return hashBestBlock_; } + + bool BatchWrite(CCoinsMap& mapCoins, const uint256& hashBlock) + { + for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end(); ) { + map_[it->first] = it->second.coins; + if (it->second.coins.IsPruned() && insecure_rand() % 3 == 0) { + // Randomly delete empty entries on write. + map_.erase(it->first); + } + mapCoins.erase(it++); + } + mapCoins.clear(); + hashBestBlock_ = hashBlock; + return true; + } + + bool GetStats(CCoinsStats& stats) const { return false; } +}; +} + +BOOST_AUTO_TEST_SUITE(coins_tests) + +static const unsigned int NUM_SIMULATION_ITERATIONS = 40000; + +// This is a large randomized insert/remove simulation test on a variable-size +// stack of caches on top of CCoinsViewTest. +// +// It will randomly create/update/delete CCoins entries to a tip of caches, with +// txids picked from a limited list of random 256-bit hashes. Occasionally, a +// new tip is added to the stack of caches, or the tip is flushed and removed. +// +// During the process, booleans are kept to make sure that the randomized +// operation hits all branches. +BOOST_AUTO_TEST_CASE(coins_cache_simulation_test) +{ + // Various coverage trackers. + bool removed_all_caches = false; + bool reached_4_caches = false; + bool added_an_entry = false; + bool removed_an_entry = false; + bool updated_an_entry = false; + bool found_an_entry = false; + bool missed_an_entry = false; + + // A simple map to track what we expect the cache stack to represent. + std::map<uint256, CCoins> result; + + // 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. + + // Use a limited set of random transaction ids, so we do test overwriting entries. + std::vector<uint256> txids; + txids.resize(NUM_SIMULATION_ITERATIONS / 8); + for (unsigned int i = 0; i < txids.size(); i++) { + txids[i] = GetRandHash(); + } + + for (unsigned int i = 0; i < NUM_SIMULATION_ITERATIONS; i++) { + // Do a random modification. + { + uint256 txid = txids[insecure_rand() % txids.size()]; // txid we're going to modify in this iteration. + CCoins& coins = result[txid]; + CCoinsModifier entry = stack.back()->ModifyCoins(txid); + BOOST_CHECK(coins == *entry); + if (insecure_rand() % 5 == 0 || coins.IsPruned()) { + if (coins.IsPruned()) { + added_an_entry = true; + } else { + updated_an_entry = true; + } + coins.nVersion = insecure_rand(); + coins.vout.resize(1); + coins.vout[0].nValue = insecure_rand(); + *entry = coins; + } else { + coins.Clear(); + entry->Clear(); + removed_an_entry = true; + } + } + + // Once every 1000 iterations and at the end, verify the full cache. + if (insecure_rand() % 1000 == 1 || i == NUM_SIMULATION_ITERATIONS - 1) { + for (std::map<uint256, CCoins>::iterator it = result.begin(); it != result.end(); it++) { + const CCoins* coins = stack.back()->AccessCoins(it->first); + if (coins) { + BOOST_CHECK(*coins == it->second); + found_an_entry = true; + } else { + BOOST_CHECK(it->second.IsPruned()); + missed_an_entry = true; + } + } + } + + if (insecure_rand() % 100 == 0) { + // Every 100 iterations, change the cache stack. + if (stack.size() > 0 && insecure_rand() % 2 == 0) { + stack.back()->Flush(); + delete stack.back(); + stack.pop_back(); + } + if (stack.size() == 0 || (stack.size() < 4 && insecure_rand() % 2)) { + CCoinsView* tip = &base; + if (stack.size() > 0) { + tip = stack.back(); + } else { + removed_all_caches = true; + } + stack.push_back(new CCoinsViewCache(tip)); + if (stack.size() == 4) { + reached_4_caches = true; + } + } + } + } + + // Clean up the stack. + while (stack.size() > 0) { + delete stack.back(); + stack.pop_back(); + } + + // Verify coverage. + BOOST_CHECK(removed_all_caches); + BOOST_CHECK(reached_4_caches); + BOOST_CHECK(added_an_entry); + BOOST_CHECK(removed_an_entry); + BOOST_CHECK(updated_an_entry); + BOOST_CHECK(found_an_entry); + BOOST_CHECK(missed_an_entry); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp index 719955ba85..b4e4f2046f 100644 --- a/src/test/compress_tests.cpp +++ b/src/test/compress_tests.cpp @@ -1,8 +1,8 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "main.h" +#include "compressor.h" #include "util.h" #include <stdint.h> diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index a3eec270ee..47bfd710cd 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -1,15 +1,20 @@ // Copyright (c) 2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "crypto/rfc6979_hmac_sha256.h" #include "crypto/ripemd160.h" #include "crypto/sha1.h" -#include "crypto/sha2.h" +#include "crypto/sha256.h" +#include "crypto/sha512.h" +#include "crypto/hmac_sha256.h" +#include "crypto/hmac_sha512.h" #include "random.h" #include "utilstrencodings.h" #include <vector> +#include <boost/assign/list_of.hpp> #include <boost/test/unit_test.hpp> BOOST_AUTO_TEST_SUITE(crypto_tests) @@ -32,7 +37,7 @@ void TestVector(const Hasher &h, const In &in, const Out &out) { size_t len = insecure_rand() % ((in.size() - pos + 1) / 2 + 1); hasher.Write((unsigned char*)&in[pos], len); pos += len; - if (pos > 0 && pos + 2 * out.size() > in.size()) { + if (pos > 0 && pos + 2 * out.size() > in.size() && pos < in.size()) { // Test that writing the rest at once to a copy of a hasher works. Hasher(hasher).Write((unsigned char*)&in[pos], in.size() - pos).Finalize(&hash[0]); BOOST_CHECK(hash == out); @@ -48,6 +53,11 @@ void TestSHA256(const std::string &in, const std::string &hexout) { TestVector(C void TestSHA512(const std::string &in, const std::string &hexout) { TestVector(CSHA512(), in, ParseHex(hexout));} void TestRIPEMD160(const std::string &in, const std::string &hexout) { TestVector(CRIPEMD160(), in, ParseHex(hexout));} +void TestHMACSHA256(const std::string &hexkey, const std::string &hexin, const std::string &hexout) { + std::vector<unsigned char> key = ParseHex(hexkey); + TestVector(CHMAC_SHA256(&key[0], key.size()), ParseHex(hexin), ParseHex(hexout)); +} + void TestHMACSHA512(const std::string &hexkey, const std::string &hexin, const std::string &hexout) { std::vector<unsigned char> key = ParseHex(hexkey); TestVector(CHMAC_SHA512(&key[0], key.size()), ParseHex(hexin), ParseHex(hexout)); @@ -158,6 +168,43 @@ BOOST_AUTO_TEST_CASE(sha512_testvectors) { "37de8c3ef5459d76a52cedc02dc499a3c9ed9dedbfb3281afd9653b8a112fafc"); } +BOOST_AUTO_TEST_CASE(hmac_sha256_testvectors) { + // test cases 1, 2, 3, 4, 6 and 7 of RFC 4231 + TestHMACSHA256("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", + "4869205468657265", + "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"); + TestHMACSHA256("4a656665", + "7768617420646f2079612077616e7420666f72206e6f7468696e673f", + "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"); + TestHMACSHA256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddddddd", + "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe"); + TestHMACSHA256("0102030405060708090a0b0c0d0e0f10111213141516171819", + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", + "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"); + TestHMACSHA256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa", + "54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a" + "65204b6579202d2048617368204b6579204669727374", + "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54"); + TestHMACSHA256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa", + "5468697320697320612074657374207573696e672061206c6172676572207468" + "616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074" + "68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565" + "647320746f20626520686173686564206265666f7265206265696e6720757365" + "642062792074686520484d414320616c676f726974686d2e", + "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2"); +} + BOOST_AUTO_TEST_CASE(hmac_sha512_testvectors) { // test cases 1, 2, 3, 4, 6 and 7 of RFC 4231 TestHMACSHA512("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", @@ -201,4 +248,38 @@ BOOST_AUTO_TEST_CASE(hmac_sha512_testvectors) { "b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58"); } +void TestRFC6979(const std::string& hexkey, const std::string& hexmsg, const std::vector<std::string>& hexout) +{ + std::vector<unsigned char> key = ParseHex(hexkey); + std::vector<unsigned char> msg = ParseHex(hexmsg); + RFC6979_HMAC_SHA256 rng(&key[0], key.size(), &msg[0], msg.size()); + + for (unsigned int i = 0; i < hexout.size(); i++) { + std::vector<unsigned char> out = ParseHex(hexout[i]); + std::vector<unsigned char> gen; + gen.resize(out.size()); + rng.Generate(&gen[0], gen.size()); + BOOST_CHECK(out == gen); + } +} + +BOOST_AUTO_TEST_CASE(rfc6979_hmac_sha256) +{ + TestRFC6979( + "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f00", + "4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a", + boost::assign::list_of + ("4fe29525b2086809159acdf0506efb86b0ec932c7ba44256ab321e421e67e9fb") + ("2bf0fff1d3c378a22dc5de1d856522325c65b504491a0cbd01cb8f3aa67ffd4a") + ("f528b410cb541f77000d7afb6c5b53c5c471eab43e466d9ac5190c39c82fd82e")); + + TestRFC6979( + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + boost::assign::list_of + ("9c236c165b82ae0cd590659e100b6bab3036e7ba8b06749baf6981e16f1a2b95") + ("df471061625bc0ea14b682feee2c9c02f235da04204c1d62a1536c6e17aed7a9") + ("7597887cbd76321f32e30440679a22cf7f8d9d2eac390e581fea091ce202ba94")); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/data/README.md b/src/test/data/README.md index f69a021ca0..55ac95739c 100644 --- a/src/test/data/README.md +++ b/src/test/data/README.md @@ -9,6 +9,6 @@ License The data files in this directory are Copyright (c) 2012-2014 The Bitcoin Core developers - Distributed under the MIT/X11 software license, see the accompanying + Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index cb74d73ef2..f8424b72a3 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -1,33 +1,41 @@ [ - { "exec": ["./bitcoin-tx", "-create"], + { "exec": "././bitcoin-tx", + "args": ["-create"], "output_cmp": "blanktx.hex" }, - { "exec": ["./bitcoin-tx", "-"], + { "exec": "./bitcoin-tx", + "args": ["-"], "input": "blanktx.hex", "output_cmp": "blanktx.hex" }, - { "exec": ["./bitcoin-tx", "-", "delin=1"], + { "exec": "./bitcoin-tx", + "args": ["-", "delin=1"], "input": "tx394b54bb.hex", "output_cmp": "tt-delin1-out.hex" }, - { "exec": ["./bitcoin-tx", "-", "delin=31"], + { "exec": "./bitcoin-tx", + "args": ["-", "delin=31"], "input": "tx394b54bb.hex", "return_code": 1 }, - { "exec": ["./bitcoin-tx", "-", "delout=1"], + { "exec": "./bitcoin-tx", + "args": ["-", "delout=1"], "input": "tx394b54bb.hex", "output_cmp": "tt-delout1-out.hex" }, - { "exec": ["./bitcoin-tx", "-", "delout=2"], + { "exec": "./bitcoin-tx", + "args": ["-", "delout=2"], "input": "tx394b54bb.hex", "return_code": 1 }, - { "exec": ["./bitcoin-tx", "-", "locktime=317000"], + { "exec": "./bitcoin-tx", + "args": ["-", "locktime=317000"], "input": "tx394b54bb.hex", "output_cmp": "tt-locktime317000-out.hex" }, - { "exec": - ["./bitcoin-tx", "-create", + { "exec": "./bitcoin-tx", + "args": + ["-create", "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", "in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18", "in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1", @@ -35,7 +43,8 @@ "outaddr=4:1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"], "output_cmp": "txcreate1.hex" }, - { "exec": ["./bitcoin-tx", "-create", "outscript=0:"], + { "exec": "./bitcoin-tx", + "args": ["-create", "outscript=0:"], "output_cmp": "txcreate2.hex" } ] diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 75de4716f8..44e0dca8be 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -1,4 +1,11 @@ [ +["Format is: [scriptSig, scriptPubKey, flags, ... comments]"], +["It is evaluated as if there was a crediting coinbase transaction with two 0"], +["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"], +["followed by a spending transaction which spends this output as only input (and"], +["correct prevout hash), using the given scriptSig. All nLockTimes are 0, all"], +["nSequences are max."], + ["", "DEPTH", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation"], [" ", "DEPTH", "P2SH,STRICTENC", "and multiple spaces should not change that."], [" ", "DEPTH", "P2SH,STRICTENC"], @@ -154,6 +161,23 @@ ["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"], ["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"], +["Ensure 100% coverage of discouraged NOPS"], +["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP2", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP8", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP9", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP10", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], + +["NOP10", "1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in scriptSig"], + +["1 0x01 0xb9", "HASH160 0x14 0x15727299b05b45fdaf9ac9ecf7565cfe27c3e567 EQUAL", + "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript"], + ["0x50","1", "P2SH,STRICTENC", "opcode 0x50 is reserved"], ["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "opcodes above NOP10 invalid if executed"], ["1", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC"], @@ -373,5 +397,276 @@ ["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "P2SH,STRICTENC", "OP_RESERVED in P2SH should fail"], ["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "P2SH,STRICTENC", "OP_VER in P2SH should fail"], -["0x00", "'00' EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"] +["0x00", "'00' EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"], + +["MINIMALDATA enforcement for PUSHDATAs"], + +["0x4c 0x00", "DROP 1", "MINIMALDATA", "Empty vector minimally represented by OP_0"], +["0x01 0x81", "DROP 1", "MINIMALDATA", "-1 minimally represented by OP_1NEGATE"], +["0x01 0x01", "DROP 1", "MINIMALDATA", "1 to 16 minimally represented by OP_1 to OP_16"], +["0x01 0x02", "DROP 1", "MINIMALDATA"], +["0x01 0x03", "DROP 1", "MINIMALDATA"], +["0x01 0x04", "DROP 1", "MINIMALDATA"], +["0x01 0x05", "DROP 1", "MINIMALDATA"], +["0x01 0x06", "DROP 1", "MINIMALDATA"], +["0x01 0x07", "DROP 1", "MINIMALDATA"], +["0x01 0x08", "DROP 1", "MINIMALDATA"], +["0x01 0x09", "DROP 1", "MINIMALDATA"], +["0x01 0x0a", "DROP 1", "MINIMALDATA"], +["0x01 0x0b", "DROP 1", "MINIMALDATA"], +["0x01 0x0c", "DROP 1", "MINIMALDATA"], +["0x01 0x0d", "DROP 1", "MINIMALDATA"], +["0x01 0x0e", "DROP 1", "MINIMALDATA"], +["0x01 0x0f", "DROP 1", "MINIMALDATA"], +["0x01 0x10", "DROP 1", "MINIMALDATA"], + +["0x4c 0x48 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", + "PUSHDATA1 of 72 bytes minimally represented by direct push"], + +["0x4d 0xFF00 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", + "PUSHDATA2 of 255 bytes minimally represented by PUSHDATA1"], + +["0x4f 0x00100000 0x11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "DROP 1", "MINIMALDATA", + "PUSHDATA4 of 256 bytes minimally represented by PUSHDATA2"], + + +["MINIMALDATA enforcement for numeric arguments"], + +["0x01 0x00", "NOT DROP 1", "MINIMALDATA", "numequals 0"], +["0x02 0x0000", "NOT DROP 1", "MINIMALDATA", "numequals 0"], +["0x01 0x80", "NOT DROP 1", "MINIMALDATA", "0x80 (negative zero) numequals 0"], +["0x02 0x0080", "NOT DROP 1", "MINIMALDATA", "numequals 0"], +["0x02 0x0500", "NOT DROP 1", "MINIMALDATA", "numequals 5"], +["0x03 0x050000", "NOT DROP 1", "MINIMALDATA", "numequals 5"], +["0x02 0x0580", "NOT DROP 1", "MINIMALDATA", "numequals -5"], +["0x03 0x050080", "NOT DROP 1", "MINIMALDATA", "numequals -5"], +["0x03 0xff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff"], +["0x03 0xff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xff7f"], +["0x04 0xffff7f80", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffffff"], +["0x04 0xffff7f00", "NOT DROP 1", "MINIMALDATA", "Minimal encoding is 0xffff7f"], + +["Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule"], + +["1 0x02 0x0000", "PICK DROP", "MINIMALDATA"], +["1 0x02 0x0000", "ROLL DROP 1", "MINIMALDATA"], +["0x02 0x0000", "1ADD DROP 1", "MINIMALDATA"], +["0x02 0x0000", "1SUB DROP 1", "MINIMALDATA"], +["0x02 0x0000", "NEGATE DROP 1", "MINIMALDATA"], +["0x02 0x0000", "ABS DROP 1", "MINIMALDATA"], +["0x02 0x0000", "NOT DROP 1", "MINIMALDATA"], +["0x02 0x0000", "0NOTEQUAL DROP 1", "MINIMALDATA"], + +["0 0x02 0x0000", "ADD DROP 1", "MINIMALDATA"], +["0x02 0x0000 0", "ADD DROP 1", "MINIMALDATA"], +["0 0x02 0x0000", "SUB DROP 1", "MINIMALDATA"], +["0x02 0x0000 0", "SUB DROP 1", "MINIMALDATA"], +["0 0x02 0x0000", "BOOLAND DROP 1", "MINIMALDATA"], +["0x02 0x0000 0", "BOOLAND DROP 1", "MINIMALDATA"], +["0 0x02 0x0000", "BOOLOR DROP 1", "MINIMALDATA"], +["0x02 0x0000 0", "BOOLOR DROP 1", "MINIMALDATA"], +["0 0x02 0x0000", "NUMEQUAL DROP 1", "MINIMALDATA"], +["0x02 0x0000 1", "NUMEQUAL DROP 1", "MINIMALDATA"], +["0 0x02 0x0000", "NUMEQUALVERIFY 1", "MINIMALDATA"], +["0x02 0x0000 0", "NUMEQUALVERIFY 1", "MINIMALDATA"], +["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", "MINIMALDATA"], +["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", "MINIMALDATA"], +["0 0x02 0x0000", "LESSTHAN DROP 1", "MINIMALDATA"], +["0x02 0x0000 0", "LESSTHAN DROP 1", "MINIMALDATA"], +["0 0x02 0x0000", "GREATERTHAN DROP 1", "MINIMALDATA"], +["0x02 0x0000 0", "GREATERTHAN DROP 1", "MINIMALDATA"], +["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", "MINIMALDATA"], +["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", "MINIMALDATA"], +["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA"], +["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", "MINIMALDATA"], +["0 0x02 0x0000", "MIN DROP 1", "MINIMALDATA"], +["0x02 0x0000 0", "MIN DROP 1", "MINIMALDATA"], +["0 0x02 0x0000", "MAX DROP 1", "MINIMALDATA"], +["0x02 0x0000 0", "MAX DROP 1", "MINIMALDATA"], + +["0x02 0x0000 0 0", "WITHIN DROP 1", "MINIMALDATA"], +["0 0x02 0x0000 0", "WITHIN DROP 1", "MINIMALDATA"], +["0 0 0x02 0x0000", "WITHIN DROP 1", "MINIMALDATA"], + +["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", "MINIMALDATA"], +["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", "MINIMALDATA"], +["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", "MINIMALDATA"], +["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", "MINIMALDATA"], +["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "MINIMALDATA"], + + +["Order of CHECKMULTISIG evaluation tests, inverted by swapping the order of"], +["pubkeys/signatures so they fail due to the STRICTENC rules on validly encoded"], +["signatures and pubkeys."], +[ + "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501", + "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0 2 CHECKMULTISIG NOT", + "STRICTENC", + "2-of-2 CHECKMULTISIG NOT with the first pubkey invalid, and both signatures validly encoded." +], +[ + "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0", + "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT", + "STRICTENC", + "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid." +], + +["Automatically generated test cases"], +[ + "0x47 0x3044022053205076a7bb12d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801", + "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", + "", + "P2PK, bad sig" +], +[ + "0x47 0x30440220151ea78fa148b59f399b23731b634645ebc142f299ee9838d46fb78cf7e0bc0102200d62327dcd54ac6bcfb1516b035b1bf8eaea438c52c62d3450d1f3a8f030e0de01 0x21 0x03363d90d446b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640", + "DUP HASH160 0x14 0xc0834c0c158f53be706d234c38fd52de7eece656 EQUALVERIFY CHECKSIG", + "", + "P2PKH, bad pubkey" +], +[ + "0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790201", + "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", + "", + "P2PK anyonecanpay marked with normal hashtype" +], +[ + "0x47 0x304402202166fcd5e607de452d3c6f15e059505cf21654346592f9650ba906b9e8be88fa022005d976d28eb8de477102feba28807b3ad361e7fa24796d259c9d61452f7c318c01 0x23 0x210279be667ef9dcbbac54a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", + "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", + "P2SH", + "P2SH(P2PK), bad redeemscript" +], +[ + "0x47 0x3044022064cc90ca89ad721384b231653b945579359a24b928ef8539b331172628c9cc6102203e238869ab5dac3fc293db53c12e7dd3079e86cfde9024b689efc7227e4d671001 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", + "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", + "P2SH", + "P2SH(P2PKH), bad sig" +], +[ + "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402206d32e6d6b131ef2fe77b6a9b90b120d74e3e238e79dcffb10523a6ec94f93d65022067ae8772632ddf4c389258c6b70ed0ff94f20ee8f60207aa192a52a2469cddd901 0", + "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "", + "3-of-3, 2 sigs" +], +[ + "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", + "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL", + "P2SH", + "P2SH(2-of-3), 1 sig" +], +[ + "0x47 0x30440220001d6702bfa4f49c3a2542af9b1c2844a2eaac55f86f310f42d26a5dd17d6a8002202cdadbe608c00b50dd951c6ba0877d5b07a970f3e265c18697bc413a0a86f69901", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "DERSIG", + "P2PK with too much R padding" +], +[ + "0x48 0x304502207d2b258e959605e2ea50b46fea1325b7391ffb0c14a5b58ef8ad3851da3644380221007e75136df5f2e38216c4338b31c97e8307102edb97d611e06914e1f8fba68ead01", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "DERSIG", + "P2PK with too much S padding" +], +[ + "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "DERSIG", + "P2PK with too little R padding" +], +[ + "0x47 0x30440220003040725f724b0e2142fc44ac71f6e13161f6410aeb6dee477952ede3b6a6ca022041ff4940ee3d88116ad281d7cc556e1f2c9427d82290bd7974a25addbcd5bede01", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", + "DERSIG", + "P2PK NOT with bad sig with too much R padding" +], +[ + "0x47 0x30440220003040725f724a0e2142fc44ac71f6e13161f6410aeb6dee477952ede3b6a6ca022041ff4940ee3d88116ad281d7cc556e1f2c9427d82290bd7974a25addbcd5bede01", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", + "", + "P2PK NOT with too much R padding but no DERSIG" +], +[ + "0x47 0x30440220003040725f724a0e2142fc44ac71f6e13161f6410aeb6dee477952ede3b6a6ca022041ff4940ee3d88116ad281d7cc556e1f2c9427d82290bd7974a25addbcd5bede01", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", + "DERSIG", + "P2PK NOT with too much R padding" +], +[ + "0x49 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef05101", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", + "LOW_S", + "P2PK with high S" +], +[ + "0x47 0x30440220745d63eb70d45652128b450aa5ca7d9b513439963f261cb1c40a60f0785e7ee402204877785b38945ca9dbec78e1c1d4dd12148cc25c868bd27480023b49ae0f310501", + "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", + "STRICTENC", + "P2PK with hybrid pubkey" +], +[ + "0x47 0x30440220606f6f9f6cebc94ebfb6a4bff0b682bd99f05511295545ce9b275e98be3c946102206871d6a76f4e1b43d9763cfc5647844e4811682b1cab0325f060f44ddf44002201", + "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", + "", + "P2PK NOT with hybrid pubkey but no STRICTENC" +], +[ + "0x47 0x30440220606f6f9f6cebc94ebfb6a4bff0b682bd99f05511295545ce9b275e98be3c946102206871d6a76f4e1b43d9763cfc5647844e4811682b1cab0325f060f44ddf44002201", + "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", + "STRICTENC", + "P2PK NOT with hybrid pubkey" +], +[ + "0x47 0x30440220606f6f9f6cebc84ebfb6a4bff0b682bd99f05511295545ce9b275e98be3c946102206871d6a76f4e1b43d9763cfc5647844e4811682b1cab0325f060f44ddf44002201", + "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", + "STRICTENC", + "P2PK NOT with invalid hybrid pubkey" +], +[ + "0 0x47 0x304402203cdcf66792fe97e3955655ede5dad004950e58b369831ffa7743132c507b272c022031fbcfb4a72b3e00217abf2f5557585f1f9891f12827d2f0a2ae2978e7f9f11001", + "1 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 2 CHECKMULTISIG", + "STRICTENC", + "1-of-2 with the first 1 hybrid pubkey" +], +[ + "0x47 0x304402201c215cb13e4954e60ce4f6de74941904c771f998de7b1d9627e82a1949fde517022031c2197455f3dbecbb78321201308d7b039424e38d480772d7cd4eb465a083f405", + "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", + "STRICTENC", + "P2PK with undefined hashtype" +], +[ + "0x47 0x304402207409b5b320296e5e2136a7b281a7f803028ca4ca44e2b83eebd46932677725de02202d4eea1c8d3c98e6f42614f54764e6e5e6542e213eb4d079737e9a8b6e9812ec05", + "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT", + "STRICTENC", + "P2PK NOT with invalid sig and undefined hashtype" +], +[ + "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402206d32e6d6b131ef2fe77b6a9b90b120d74e3e238e79dcffb10523a6ec94f93d65022067ae8772632ddf4c389258c6b70ed0ff94f20ee8f60207aa192a52a2469cddd901 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", + "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "NULLDUMMY", + "3-of-3 with nonzero dummy" +], +[ + "1 0x47 0x304402201bb2edab700a5d020236df174fefed78087697143731f659bea59642c759c16d022061f42cdbae5bcd3e8790f20bf76687443436e94a634321c16a72aa54cbc7c2ea01 0x47 0x304402204bb4a64f2a6e5c7fb2f07fef85ee56fde5e6da234c6a984262307a20e99842d702206f8303aaba5e625d223897e2ffd3f88ef1bcffef55f38dc3768e5f2e94c923f901 0x47 0x3044022040c2809b71fffb155ec8b82fe7a27f666bd97f941207be4e14ade85a1249dd4d02204d56c85ec525dd18e29a0533d5ddf61b6b1bb32980c2f63edf951aebf7a27bfe01", + "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", + "NULLDUMMY", + "3-of-3 NOT with invalid sig with nonzero dummy" +], +[ + "0 0x47 0x304402206cb053202e1501e6faa24e6e309bf46a2f9255aa9484ff4a26efb7434f78a58a0220132b10419c3b99601f154bf86cf12259aacd8c6f363a73dacb1d0b941680bb4c01 DUP", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", + "SIGPUSHONLY", + "2-of-2 with two identical keys and sigs pushed using OP_DUP" +], +[ + "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", + "", + "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY" +], +[ + "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", + "SIGPUSHONLY", + "P2SH(P2PK) with non-push scriptSig" +], + +["The End"] ] diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index c1db4c6061..a1b7b119ef 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -1,4 +1,11 @@ [ +["Format is: [scriptSig, scriptPubKey, flags, ... comments]"], +["It is evaluated as if there was a crediting coinbase transaction with two 0"], +["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"], +["followed by a spending transaction which spends this output as only input (and"], +["correct prevout hash), using the given scriptSig. All nLockTimes are 0, all"], +["nSequences are max."], + ["", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation"], [" ", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "and multiple spaces should not change that."], [" ", "DEPTH 0 EQUAL", "P2SH,STRICTENC"], @@ -226,6 +233,11 @@ ["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"], ["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"], +["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "Discourage NOPx flag allows OP_NOP"], + +["0", "IF NOP10 ENDIF 1", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", + "Discouraged NOPs are allowed if not executed"], + ["0", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "opcodes above NOP10 invalid if executed"], ["0", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC"], ["0", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC"], @@ -518,5 +530,292 @@ "P2SH,STRICTENC", "Basic PUSHDATA1 signedness check"], -["0x00", "SIZE 0 EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"] +["all PUSHDATA forms are equivalent"], + +["0x4c 0x4b 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "0x4b 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 EQUAL", "", "PUSHDATA1 of 75 bytes equals direct push of it"], +["0x4d 0xFF00 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", "0x4c 0xFF 0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 EQUAL", "", "PUSHDATA2 of 255 bytes equals PUSHDATA1 of it"], + +["0x00", "SIZE 0 EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"], + +["Numeric pushes"], + +["0x01 0x81", "0x4f EQUAL", "", "OP1_NEGATE pushes 0x81"], +["0x01 0x01", "0x51 EQUAL", "", "OP_1 pushes 0x01"], +["0x01 0x02", "0x52 EQUAL", "", "OP_2 pushes 0x02"], +["0x01 0x03", "0x53 EQUAL", "", "OP_3 pushes 0x03"], +["0x01 0x04", "0x54 EQUAL", "", "OP_4 pushes 0x04"], +["0x01 0x05", "0x55 EQUAL", "", "OP_5 pushes 0x05"], +["0x01 0x06", "0x56 EQUAL", "", "OP_6 pushes 0x06"], +["0x01 0x07", "0x57 EQUAL", "", "OP_7 pushes 0x07"], +["0x01 0x08", "0x58 EQUAL", "", "OP_8 pushes 0x08"], +["0x01 0x09", "0x59 EQUAL", "", "OP_9 pushes 0x09"], +["0x01 0x0a", "0x5a EQUAL", "", "OP_10 pushes 0x0a"], +["0x01 0x0b", "0x5b EQUAL", "", "OP_11 pushes 0x0b"], +["0x01 0x0c", "0x5c EQUAL", "", "OP_12 pushes 0x0c"], +["0x01 0x0d", "0x5d EQUAL", "", "OP_13 pushes 0x0d"], +["0x01 0x0e", "0x5e EQUAL", "", "OP_14 pushes 0x0e"], +["0x01 0x0f", "0x5f EQUAL", "", "OP_15 pushes 0x0f"], +["0x01 0x10", "0x60 EQUAL", "", "OP_16 pushes 0x10"], + +["Equivalency of different numeric encodings"], + +["0x02 0x8000", "128 NUMEQUAL", "", "0x8000 equals 128"], +["0x01 0x00", "0 NUMEQUAL", "", "0x00 numequals 0"], +["0x01 0x80", "0 NUMEQUAL", "", "0x80 (negative zero) numequals 0"], +["0x02 0x0080", "0 NUMEQUAL", "", "0x0080 numequals 0"], +["0x02 0x0500", "5 NUMEQUAL", "", "0x0500 numequals 5"], +["0x03 0xff7f80", "0x02 0xffff NUMEQUAL", "", ""], +["0x03 0xff7f00", "0x02 0xff7f NUMEQUAL", "", ""], +["0x04 0xffff7f80", "0x03 0xffffff NUMEQUAL", "", ""], +["0x04 0xffff7f00", "0x03 0xffff7f NUMEQUAL", "", ""], + +["Unevaluated non-minimal pushes are ignored"], + +["0 IF 0x4c 0x00 ENDIF 1", "", "MINIMALDATA", "non-minimal PUSHDATA1 ignored"], +["0 IF 0x4d 0x0000 ENDIF 1", "", "MINIMALDATA", "non-minimal PUSHDATA2 ignored"], +["0 IF 0x4c 0x00000000 ENDIF 1", "", "MINIMALDATA", "non-minimal PUSHDATA4 ignored"], +["0 IF 0x01 0x81 ENDIF 1", "", "MINIMALDATA", "1NEGATE equiv"], +["0 IF 0x01 0x01 ENDIF 1", "", "MINIMALDATA", "OP_1 equiv"], +["0 IF 0x01 0x02 ENDIF 1", "", "MINIMALDATA", "OP_2 equiv"], +["0 IF 0x01 0x03 ENDIF 1", "", "MINIMALDATA", "OP_3 equiv"], +["0 IF 0x01 0x04 ENDIF 1", "", "MINIMALDATA", "OP_4 equiv"], +["0 IF 0x01 0x05 ENDIF 1", "", "MINIMALDATA", "OP_5 equiv"], +["0 IF 0x01 0x06 ENDIF 1", "", "MINIMALDATA", "OP_6 equiv"], +["0 IF 0x01 0x07 ENDIF 1", "", "MINIMALDATA", "OP_7 equiv"], +["0 IF 0x01 0x08 ENDIF 1", "", "MINIMALDATA", "OP_8 equiv"], +["0 IF 0x01 0x09 ENDIF 1", "", "MINIMALDATA", "OP_9 equiv"], +["0 IF 0x01 0x0a ENDIF 1", "", "MINIMALDATA", "OP_10 equiv"], +["0 IF 0x01 0x0b ENDIF 1", "", "MINIMALDATA", "OP_11 equiv"], +["0 IF 0x01 0x0c ENDIF 1", "", "MINIMALDATA", "OP_12 equiv"], +["0 IF 0x01 0x0d ENDIF 1", "", "MINIMALDATA", "OP_13 equiv"], +["0 IF 0x01 0x0e ENDIF 1", "", "MINIMALDATA", "OP_14 equiv"], +["0 IF 0x01 0x0f ENDIF 1", "", "MINIMALDATA", "OP_15 equiv"], +["0 IF 0x01 0x10 ENDIF 1", "", "MINIMALDATA", "OP_16 equiv"], + +["Numeric minimaldata rules are only applied when a stack item is numerically evaluated; the push itself is allowed"], + +["0x01 0x00", "1", "MINIMALDATA"], +["0x01 0x80", "1", "MINIMALDATA"], +["0x02 0x0180", "1", "MINIMALDATA"], +["0x02 0x0100", "1", "MINIMALDATA"], +["0x02 0x0200", "1", "MINIMALDATA"], +["0x02 0x0300", "1", "MINIMALDATA"], +["0x02 0x0400", "1", "MINIMALDATA"], +["0x02 0x0500", "1", "MINIMALDATA"], +["0x02 0x0600", "1", "MINIMALDATA"], +["0x02 0x0700", "1", "MINIMALDATA"], +["0x02 0x0800", "1", "MINIMALDATA"], +["0x02 0x0900", "1", "MINIMALDATA"], +["0x02 0x0a00", "1", "MINIMALDATA"], +["0x02 0x0b00", "1", "MINIMALDATA"], +["0x02 0x0c00", "1", "MINIMALDATA"], +["0x02 0x0d00", "1", "MINIMALDATA"], +["0x02 0x0e00", "1", "MINIMALDATA"], +["0x02 0x0f00", "1", "MINIMALDATA"], +["0x02 0x1000", "1", "MINIMALDATA"], + +["Valid version of the 'Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule' script_invalid test"], + +["1 0x02 0x0000", "PICK DROP", ""], +["1 0x02 0x0000", "ROLL DROP 1", ""], +["0x02 0x0000", "1ADD DROP 1", ""], +["0x02 0x0000", "1SUB DROP 1", ""], +["0x02 0x0000", "NEGATE DROP 1", ""], +["0x02 0x0000", "ABS DROP 1", ""], +["0x02 0x0000", "NOT DROP 1", ""], +["0x02 0x0000", "0NOTEQUAL DROP 1", ""], + +["0 0x02 0x0000", "ADD DROP 1", ""], +["0x02 0x0000 0", "ADD DROP 1", ""], +["0 0x02 0x0000", "SUB DROP 1", ""], +["0x02 0x0000 0", "SUB DROP 1", ""], +["0 0x02 0x0000", "BOOLAND DROP 1", ""], +["0x02 0x0000 0", "BOOLAND DROP 1", ""], +["0 0x02 0x0000", "BOOLOR DROP 1", ""], +["0x02 0x0000 0", "BOOLOR DROP 1", ""], +["0 0x02 0x0000", "NUMEQUAL DROP 1", ""], +["0x02 0x0000 1", "NUMEQUAL DROP 1", ""], +["0 0x02 0x0000", "NUMEQUALVERIFY 1", ""], +["0x02 0x0000 0", "NUMEQUALVERIFY 1", ""], +["0 0x02 0x0000", "NUMNOTEQUAL DROP 1", ""], +["0x02 0x0000 0", "NUMNOTEQUAL DROP 1", ""], +["0 0x02 0x0000", "LESSTHAN DROP 1", ""], +["0x02 0x0000 0", "LESSTHAN DROP 1", ""], +["0 0x02 0x0000", "GREATERTHAN DROP 1", ""], +["0x02 0x0000 0", "GREATERTHAN DROP 1", ""], +["0 0x02 0x0000", "LESSTHANOREQUAL DROP 1", ""], +["0x02 0x0000 0", "LESSTHANOREQUAL DROP 1", ""], +["0 0x02 0x0000", "GREATERTHANOREQUAL DROP 1", ""], +["0x02 0x0000 0", "GREATERTHANOREQUAL DROP 1", ""], +["0 0x02 0x0000", "MIN DROP 1", ""], +["0x02 0x0000 0", "MIN DROP 1", ""], +["0 0x02 0x0000", "MAX DROP 1", ""], +["0x02 0x0000 0", "MAX DROP 1", ""], + +["0x02 0x0000 0 0", "WITHIN DROP 1", ""], +["0 0x02 0x0000 0", "WITHIN DROP 1", ""], +["0 0 0x02 0x0000", "WITHIN DROP 1", ""], + +["0 0 0x02 0x0000", "CHECKMULTISIG DROP 1", ""], +["0 0x02 0x0000 0", "CHECKMULTISIG DROP 1", ""], +["0 0x02 0x0000 0 1", "CHECKMULTISIG DROP 1", ""], +["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", ""], +["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", ""], + +["CHECKMULTISIG evaluation order tests. CHECKMULTISIG evaluates signatures and"], +["pubkeys in a specific order, and will exit early if the number of signatures"], +["left to check is greater than the number of keys left. As STRICTENC fails the"], +["script when it reaches an invalidly encoded signature or pubkey, we can use it"], +["to test the exact order in which signatures and pubkeys are evaluated by"], +["distinguishing CHECKMULTISIG returning false on the stack and the script as a"], +["whole failing."], +["See also the corresponding inverted versions of these tests in script_invalid.json"], +[ + "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501", + "2 0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT", + "STRICTENC", + "2-of-2 CHECKMULTISIG NOT with the second pubkey invalid, and both signatures validly encoded. Valid pubkey fails, and CHECKMULTISIG exits early, prior to evaluation of second invalid pubkey." +], +[ + "0 0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501", + "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT", + "STRICTENC", + "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but second signature invalid. Valid pubkey fails, and CHECKMULTISIG exits early, prior to evaluation of second invalid signature." +], + +["Automatically generated test cases"], +[ + "0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801", + "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", + "", + "P2PK" +], +[ + "0x47 0x304402206e05a6fe23c59196ffe176c9ddc31e73a9885638f9d1328d47c0c703863b8876022076feb53811aa5b04e0e79f938eb19906cc5e67548bc555a8e8b8b0fc603d840c01 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508", + "DUP HASH160 0x14 0x1018853670f9f3b0582c5b9ee8ce93764ac32b93 EQUALVERIFY CHECKSIG", + "", + "P2PKH" +], +[ + "0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790281", + "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", + "", + "P2PK anyonecanpay" +], +[ + "0x47 0x304402202166fcd5e607de452d3c6f15e059505cf21654346592f9650ba906b9e8be88fa022005d976d28eb8de477102feba28807b3ad361e7fa24796d259c9d61452f7c318c01 0x23 0x210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", + "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", + "P2SH", + "P2SH(P2PK)" +], +[ + "0x47 0x3044022064cc90ca89ad721384b231653b945579359a24b928ef8539b331172628c9cc6102203e238869ab5dac3fc293db53c12e7dd3079e86cfde9024b689efc7227e4d671001 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", + "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", + "", + "P2SH(P2PKH), bad sig but no VERIFY_P2SH" +], +[ + "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402206d32e6d6b131ef2fe77b6a9b90b120d74e3e238e79dcffb10523a6ec94f93d65022067ae8772632ddf4c389258c6b70ed0ff94f20ee8f60207aa192a52a2469cddd901 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", + "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "", + "3-of-3" +], +[ + "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0x47 0x304402204511cf05e85c2be07c6c176c5338a08ed3cb34212667f39613340881169986c002207cc48b27aa3691a20706a5773ec9923cadd20fedffd00c24457d85f83f0b51fe01 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", + "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL", + "P2SH", + "P2SH(2-of-3)" +], +[ + "0x47 0x30440220001d6702bfa4f49c3a2542af9b1c2844a2eaac55f86f310f42d26a5dd17d6a8002202cdadbe608c00b50dd951c6ba0877d5b07a970f3e265c18697bc413a0a86f69901", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "", + "P2PK with too much R padding but no DERSIG" +], +[ + "0x48 0x304502207d2b258e959605e2ea50b46fea1325b7391ffb0c14a5b58ef8ad3851da3644380221007e75136df5f2e38216c4338b31c97e8307102edb97d611e06914e1f8fba68ead01", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "", + "P2PK with too much S padding but no DERSIG" +], +[ + "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", + "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", + "", + "P2PK with too little R padding but no DERSIG" +], +[ + "0x47 0x30440220003040725f724b0e2142fc44ac71f6e13161f6410aeb6dee477952ede3b6a6ca022041ff4940ee3d88116ad281d7cc556e1f2c9427d82290bd7974a25addbcd5bede01", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", + "", + "P2PK NOT with bad sig with too much R padding but no DERSIG" +], +[ + "0x49 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef05101", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", + "", + "P2PK with high S but no LOW_S" +], +[ + "0x47 0x30440220745d63eb70d45652128b450aa5ca7d9b513439963f261cb1c40a60f0785e7ee402204877785b38945ca9dbec78e1c1d4dd12148cc25c868bd27480023b49ae0f310501", + "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", + "", + "P2PK with hybrid pubkey but no STRICTENC" +], +[ + "0x47 0x30440220606f6f9f6cebc84ebfb6a4bff0b682bd99f05511295545ce9b275e98be3c946102206871d6a76f4e1b43d9763cfc5647844e4811682b1cab0325f060f44ddf44002201", + "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", + "", + "P2PK NOT with invalid hybrid pubkey but no STRICTENC" +], +[ + "0 0x47 0x304402203a5ee39032637c431af0a3ac42e32e0627390bd44f6f98c9c04e6d714635ad0202207b42fcd889c3ae8a1b515608f38535f1f9be815176ee8d1b65a27c767cf37aed01", + "1 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", + "", + "1-of-2 with the second 1 hybrid pubkey and no STRICTENC" +], +[ + "0 0x47 0x304402203a5ee39032637c431af0a3ac42e32e0627390bd44f6f98c9c04e6d714635ad0202207b42fcd889c3ae8a1b515608f38535f1f9be815176ee8d1b65a27c767cf37aed01", + "1 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", + "STRICTENC", + "1-of-2 with the second 1 hybrid pubkey" +], +[ + "0x47 0x304402201c215cb13e4954e60ce4f6de74941904c771f998de7b1d9627e82a1949fde517022031c2197455f3dbecbb78321201308d7b039424e38d480772d7cd4eb465a083f405", + "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", + "", + "P2PK with undefined hashtype but no STRICTENC" +], +[ + "0x47 0x304402207409b5b320296e5e2136a7b281a7f803028ca4ca44e2b83eebd46932677725de02202d4eea1c8d3c98e6f42614f54764e6e5e6542e213eb4d079737e9a8b6e9812ec05", + "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT", + "", + "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC" +], +[ + "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402206d32e6d6b131ef2fe77b6a9b90b120d74e3e238e79dcffb10523a6ec94f93d65022067ae8772632ddf4c389258c6b70ed0ff94f20ee8f60207aa192a52a2469cddd901 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901", + "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", + "", + "3-of-3 with nonzero dummy but no NULLDUMMY" +], +[ + "1 0x47 0x304402201bb2edab700a5d020236df174fefed78087697143731f659bea59642c759c16d022061f42cdbae5bcd3e8790f20bf76687443436e94a634321c16a72aa54cbc7c2ea01 0x47 0x304402204bb4a64f2a6e5c7fb2f07fef85ee56fde5e6da234c6a984262307a20e99842d702206f8303aaba5e625d223897e2ffd3f88ef1bcffef55f38dc3768e5f2e94c923f901 0x47 0x3044022040c2809b71fffb155ec8b82fe7a27f666bd97f941207be4e14ade85a1249dd4d02204d56c85ec525dd18e29a0533d5ddf61b6b1bb32980c2f63edf951aebf7a27bfe01", + "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT", + "", + "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY" +], +[ + "0 0x47 0x304402206cb053202e1501e6faa24e6e309bf46a2f9255aa9484ff4a26efb7434f78a58a0220132b10419c3b99601f154bf86cf12259aacd8c6f363a73dacb1d0b941680bb4c01 DUP", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", + "", + "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY" +], +[ + "0 0x47 0x304402206cb053202e1501e6faa24e6e309bf46a2f9255aa9484ff4a26efb7434f78a58a0220132b10419c3b99601f154bf86cf12259aacd8c6f363a73dacb1d0b941680bb4c01 0x47 0x304402206cb053202e1501e6faa24e6e309bf46a2f9255aa9484ff4a26efb7434f78a58a0220132b10419c3b99601f154bf86cf12259aacd8c6f363a73dacb1d0b941680bb4c01", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", + "SIGPUSHONLY", + "2-of-2 with two identical keys and sigs pushed" +], + +["The End"] ] diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 638a705f9f..456e0d2f7b 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -103,5 +103,17 @@ [[["ad503f72c18df5801ee64d76090afe4c607fb2b822e9b7b63c5826c50e22fc3b", 0, "0x21 0x027c3a97665bf283a102a587a62a30a0c102d4d3b141015e2cae6f64e2543113e5 CHECKSIG NOT"]], "01000000013bfc220ec526583cb6b7e922b8b27f604cfe0a09764de61e80f58dc1723f50ad0000000000ffffffff0101000000000000002321027c3a97665bf283a102a587a62a30a0c102d4d3b141015e2cae6f64e2543113e5ac00000000", "P2SH"], + +["Inverted versions of tx_valid CODESEPARATOR IF block tests"], + +["CODESEPARATOR in an unexecuted IF block does not change what is hashed"], +[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]], +"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a48304502207a6974a77c591fa13dff60cabbb85a0de9e025c09c65a4b2285e47ce8e22f761022100f0efaac9ff8ac36b10721e0aae1fb975c90500b50c56e8a0cc52b0403f0425dd0151ffffffff010000000000000000016a00000000", "P2SH"], + +["As above, with the IF block executed"], +[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]], +"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a483045022100fa4a74ba9fd59c59f46c3960cf90cbe0d2b743c471d24a3d5d6db6002af5eebb02204d70ec490fd0f7055a7c45f86514336e3a7f03503dacecabb247fc23f15c83510100ffffffff010000000000000000016a00000000", "P2SH"], + + ["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 aa8e5ca6c3..182b88ef67 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -149,6 +149,15 @@ [[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIGVERIFY CODESEPARATOR 0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIGVERIFY CODESEPARATOR 1"]], "010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a900000000924830450221009c0a27f886a1d8cb87f6f595fbc3163d28f7a81ec3c4b252ee7f3ac77fd13ffa02203caa8dfa09713c8c4d7ef575c75ed97812072405d932bd11e6a1593a98b679370148304502201e3861ef39a526406bad1e20ecad06be7375ad40ddb582c9be42d26c3a0d7b240221009d0a3985e96522e59635d19cc4448547477396ce0ef17a58e7d74c3ef464292301ffffffff010000000000000000016a00000000", "P2SH"], +["CODESEPARATOR in an unexecuted IF block does not change what is hashed"], +[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]], +"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a48304502207a6974a77c591fa13dff60cabbb85a0de9e025c09c65a4b2285e47ce8e22f761022100f0efaac9ff8ac36b10721e0aae1fb975c90500b50c56e8a0cc52b0403f0425dd0100ffffffff010000000000000000016a00000000", "P2SH"], + +["As above, with the IF block executed"], +[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]], +"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a483045022100fa4a74ba9fd59c59f46c3960cf90cbe0d2b743c471d24a3d5d6db6002af5eebb02204d70ec490fd0f7055a7c45f86514336e3a7f03503dacecabb247fc23f15c83510151ffffffff010000000000000000016a00000000", "P2SH"], + + ["CHECKSIG is legal in scriptSigs"], [[["ccf7f4053a02e653c36ac75c891b7496d0dc5ce5214f6c913d9cf8f1329ebee0", 0, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]], "0100000001e0be9e32f1f89c3d916c4f21e55cdcd096741b895cc76ac353e6023a05f4f7cc00000000d86149304602210086e5f736a2c3622ebb62bd9d93d8e5d76508b98be922b97160edc3dcca6d8c47022100b23c312ac232a4473f19d2aeb95ab7bdf2b65518911a0d72d50e38b5dd31dc820121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ac4730440220508fa761865c8abd81244a168392876ee1d94e8ed83897066b5e2df2400dad24022043f5ee7538e87e9c6aef7ef55133d3e51da7cc522830a9c4d736977a76ef755c0121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH"], diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index 8cadcdd716..5fb0f4ccdd 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "util.h" @@ -16,7 +16,8 @@ BOOST_AUTO_TEST_SUITE(getarg_tests) static void ResetArgs(const std::string& strArg) { std::vector<std::string> vecArg; - boost::split(vecArg, strArg, boost::is_space(), boost::token_compress_on); + if (strArg.size()) + boost::split(vecArg, strArg, boost::is_space(), boost::token_compress_on); // Insert dummy executable name: vecArg.insert(vecArg.begin(), "testbitcoin"); diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index b8e290f071..f1ad25e6ee 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "hash.h" diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 203c20731a..1333aba471 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "key.h" @@ -8,6 +8,7 @@ #include "script/script.h" #include "uint256.h" #include "util.h" +#include "utilstrencodings.h" #include <string> #include <vector> @@ -75,13 +76,33 @@ BOOST_AUTO_TEST_CASE(key_test1) CKey key1C = bsecret1C.GetKey(); BOOST_CHECK(key1C.IsCompressed() == true); CKey key2C = bsecret2C.GetKey(); - BOOST_CHECK(key1C.IsCompressed() == true); + BOOST_CHECK(key2C.IsCompressed() == true); CPubKey pubkey1 = key1. GetPubKey(); CPubKey pubkey2 = key2. GetPubKey(); CPubKey pubkey1C = key1C.GetPubKey(); CPubKey pubkey2C = key2C.GetPubKey(); + BOOST_CHECK(key1.VerifyPubKey(pubkey1)); + BOOST_CHECK(!key1.VerifyPubKey(pubkey1C)); + BOOST_CHECK(!key1.VerifyPubKey(pubkey2)); + BOOST_CHECK(!key1.VerifyPubKey(pubkey2C)); + + BOOST_CHECK(!key1C.VerifyPubKey(pubkey1)); + BOOST_CHECK(key1C.VerifyPubKey(pubkey1C)); + BOOST_CHECK(!key1C.VerifyPubKey(pubkey2)); + BOOST_CHECK(!key1C.VerifyPubKey(pubkey2C)); + + BOOST_CHECK(!key2.VerifyPubKey(pubkey1)); + BOOST_CHECK(!key2.VerifyPubKey(pubkey1C)); + BOOST_CHECK(key2.VerifyPubKey(pubkey2)); + BOOST_CHECK(!key2.VerifyPubKey(pubkey2C)); + + BOOST_CHECK(!key2C.VerifyPubKey(pubkey1)); + BOOST_CHECK(!key2C.VerifyPubKey(pubkey1C)); + BOOST_CHECK(!key2C.VerifyPubKey(pubkey2)); + BOOST_CHECK(key2C.VerifyPubKey(pubkey2C)); + BOOST_CHECK(addr1.Get() == CTxDestination(pubkey1.GetID())); BOOST_CHECK(addr2.Get() == CTxDestination(pubkey2.GetID())); BOOST_CHECK(addr1C.Get() == CTxDestination(pubkey1C.GetID())); @@ -142,6 +163,28 @@ BOOST_AUTO_TEST_CASE(key_test1) BOOST_CHECK(rkey1C == pubkey1C); BOOST_CHECK(rkey2C == pubkey2C); } + + // test deterministic signing + + std::vector<unsigned char> detsig, detsigc; + string strMsg = "Very deterministic message"; + uint256 hashMsg = Hash(strMsg.begin(), strMsg.end()); + BOOST_CHECK(key1.Sign(hashMsg, detsig)); + BOOST_CHECK(key1C.Sign(hashMsg, detsigc)); + BOOST_CHECK(detsig == detsigc); + BOOST_CHECK(detsig == ParseHex("304402205dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2d377bbe59d31d022014ddda21494a4e221f0824f0b8b924c43fa43c0ad57dccdaa11f81a6bd4582f6")); + BOOST_CHECK(key2.Sign(hashMsg, detsig)); + BOOST_CHECK(key2C.Sign(hashMsg, detsigc)); + BOOST_CHECK(detsig == detsigc); + BOOST_CHECK(detsig == ParseHex("3044022052d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2bfa8ac9dc1cd5022061d8ae5e0f6c1a16bde3719c64c2fd70e404b6428ab9a69566962e8771b5944d")); + BOOST_CHECK(key1.SignCompact(hashMsg, detsig)); + BOOST_CHECK(key1C.SignCompact(hashMsg, detsigc)); + BOOST_CHECK(detsig == ParseHex("1c5dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2d377bbe59d31d14ddda21494a4e221f0824f0b8b924c43fa43c0ad57dccdaa11f81a6bd4582f6")); + BOOST_CHECK(detsigc == ParseHex("205dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2d377bbe59d31d14ddda21494a4e221f0824f0b8b924c43fa43c0ad57dccdaa11f81a6bd4582f6")); + BOOST_CHECK(key2.SignCompact(hashMsg, detsig)); + BOOST_CHECK(key2C.SignCompact(hashMsg, detsigc)); + BOOST_CHECK(detsig == ParseHex("1c52d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2bfa8ac9dc1cd561d8ae5e0f6c1a16bde3719c64c2fd70e404b6428ab9a69566962e8771b5944d")); + BOOST_CHECK(detsigc == ParseHex("2052d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2bfa8ac9dc1cd561d8ae5e0f6c1a16bde3719c64c2fd70e404b6428ab9a69566962e8771b5944d")); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index 8863ba4004..2a72a220a4 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -1,8 +1,8 @@ // Copyright (c) 2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "core.h" +#include "primitives/transaction.h" #include "main.h" #include <boost/test/unit_test.hpp> @@ -11,9 +11,9 @@ BOOST_AUTO_TEST_SUITE(main_tests) BOOST_AUTO_TEST_CASE(subsidy_limit_test) { - uint64_t nSum = 0; + CAmount nSum = 0; for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) { - uint64_t nSubsidy = GetBlockValue(nHeight, 0); + CAmount nSubsidy = GetBlockValue(nHeight, 0); BOOST_CHECK(nSubsidy <= 50 * COIN); nSum += nSubsidy * 1000; BOOST_CHECK(MoneyRange(nSum)); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 9e4669eba9..44c57a8eaf 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -1,9 +1,10 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "main.h" #include "miner.h" +#include "pubkey.h" #include "uint256.h" #include "util.h" @@ -56,6 +57,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) uint256 hash; LOCK(cs_main); + Checkpoints::fEnabled = false; // Simple block creation, nothing special yet: BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); @@ -79,7 +81,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) pblock->hashMerkleRoot = pblock->BuildMerkleTree(); pblock->nNonce = blockinfo[i].nonce; CValidationState state; - BOOST_CHECK(ProcessBlock(state, NULL, pblock)); + BOOST_CHECK(ProcessNewBlock(state, NULL, pblock)); BOOST_CHECK(state.IsValid()); pblock->hashPrevBlock = pblock->GetHash(); } @@ -170,7 +172,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].scriptSig = CScript() << OP_1; tx.vout[0].nValue = 4900000000LL; script = CScript() << OP_0; - tx.vout[0].scriptPubKey = GetScriptForDestination(script.GetID()); + tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script)); hash = tx.GetHash(); mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); tx.vin[0].prevout.hash = hash; @@ -253,10 +255,12 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) chainActive.Tip()->nHeight--; SetMockTime(0); + mempool.clear(); BOOST_FOREACH(CTransaction *tx, txFirst) delete tx; + Checkpoints::fEnabled = true; } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp index 547cd1090c..813ec9b8b2 100644 --- a/src/test/mruset_tests.cpp +++ b/src/test/mruset_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "mruset.h" diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index cb37740068..42a159cda2 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -1,11 +1,12 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "key.h" #include "keystore.h" #include "main.h" #include "script/script.h" +#include "script/script_error.h" #include "script/interpreter.h" #include "script/sign.h" #include "uint256.h" @@ -46,18 +47,19 @@ BOOST_AUTO_TEST_CASE(multisig_verify) { unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; + ScriptError err; CKey key[4]; for (int i = 0; i < 4; i++) key[i].MakeNewKey(true); CScript a_and_b; - a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG; CScript a_or_b; - a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG; CScript escrow; - escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG; CMutableTransaction txFrom; // Funding transaction txFrom.vout.resize(3); @@ -82,19 +84,22 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys.clear(); keys += key[0],key[1]; // magic operator+= from boost.assign s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK(VerifyScript(s, a_and_b, txTo[0], 0, flags)); + BOOST_CHECK(VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); for (int i = 0; i < 4; i++) { keys.clear(); keys += key[i]; s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, flags), strprintf("a&b 1: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err), strprintf("a&b 1: %d", i)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); keys.clear(); keys += key[1],key[i]; s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, flags), strprintf("a&b 2: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err), strprintf("a&b 2: %d", i)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } // Test a OR b: @@ -104,16 +109,24 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys += key[i]; s = sign_multisig(a_or_b, keys, txTo[1], 0); if (i == 0 || i == 1) - BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, txTo[1], 0, flags), strprintf("a|b: %d", i)); + { + BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); + } else - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, txTo[1], 0, flags), strprintf("a|b: %d", i)); + { + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); + } } s.clear(); s << OP_0 << OP_0; - BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, flags)); + BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err)); s.clear(); s << OP_0 << OP_1; - BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, flags)); + BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err)); for (int i = 0; i < 4; i++) @@ -123,9 +136,15 @@ BOOST_AUTO_TEST_CASE(multisig_verify) keys += key[i],key[j]; s = sign_multisig(escrow, keys, txTo[2], 0); if (i < j && i < 3 && j < 3) - BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, txTo[2], 0, flags), strprintf("escrow 1: %d %d", i, j)); + { + BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); + } else - BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, txTo[2], 0, flags), strprintf("escrow 2: %d %d", i, j)); + { + BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); + } } } @@ -138,28 +157,28 @@ BOOST_AUTO_TEST_CASE(multisig_IsStandard) txnouttype whichType; CScript a_and_b; - a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG; BOOST_CHECK(::IsStandard(a_and_b, whichType)); CScript a_or_b; - a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG; BOOST_CHECK(::IsStandard(a_or_b, whichType)); CScript escrow; - escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG; BOOST_CHECK(::IsStandard(escrow, whichType)); CScript one_of_four; - one_of_four << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << key[3].GetPubKey() << OP_4 << OP_CHECKMULTISIG; + one_of_four << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << ToByteVector(key[3].GetPubKey()) << OP_4 << OP_CHECKMULTISIG; BOOST_CHECK(!::IsStandard(one_of_four, whichType)); CScript malformed[6]; - malformed[0] << OP_3 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; - malformed[1] << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_3 << OP_CHECKMULTISIG; - malformed[2] << OP_0 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; - malformed[3] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_0 << OP_CHECKMULTISIG; - malformed[4] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_CHECKMULTISIG; - malformed[5] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey(); + malformed[0] << OP_3 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG; + malformed[1] << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_3 << OP_CHECKMULTISIG; + malformed[2] << OP_0 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG; + malformed[3] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_0 << OP_CHECKMULTISIG; + malformed[4] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_CHECKMULTISIG; + malformed[5] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()); for (int i = 0; i < 6; i++) BOOST_CHECK(!::IsStandard(malformed[i], whichType)); @@ -192,7 +211,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) vector<valtype> solutions; txnouttype whichType; CScript s; - s << key[0].GetPubKey() << OP_CHECKSIG; + s << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG; BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK(solutions.size() == 1); CTxDestination addr; @@ -207,7 +226,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) vector<valtype> solutions; txnouttype whichType; CScript s; - s << OP_DUP << OP_HASH160 << key[0].GetPubKey().GetID() << OP_EQUALVERIFY << OP_CHECKSIG; + s << OP_DUP << OP_HASH160 << ToByteVector(key[0].GetPubKey().GetID()) << OP_EQUALVERIFY << OP_CHECKSIG; BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK(solutions.size() == 1); CTxDestination addr; @@ -222,7 +241,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) vector<valtype> solutions; txnouttype whichType; CScript s; - s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + s << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG; BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK_EQUAL(solutions.size(), 4U); CTxDestination addr; @@ -237,7 +256,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) vector<valtype> solutions; txnouttype whichType; CScript s; - s << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + s << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG; BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK_EQUAL(solutions.size(), 4U); vector<CTxDestination> addrs; @@ -256,7 +275,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) vector<valtype> solutions; txnouttype whichType; CScript s; - s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + s << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG; BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK(solutions.size() == 5); } @@ -274,13 +293,13 @@ BOOST_AUTO_TEST_CASE(multisig_Sign) } CScript a_and_b; - a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG; CScript a_or_b; - a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; + a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG; CScript escrow; - escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; + escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG; CMutableTransaction txFrom; // Funding transaction txFrom.vout.resize(3); diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index c26e738384..9361459949 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "netbase.h" diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index 9dce4daac6..807a5d1e5f 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -1,10 +1,12 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "main.h" +#include "merkleblock.h" #include "serialize.h" +#include "streams.h" #include "uint256.h" +#include "version.h" #include <vector> diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index d5475a92bf..1c6963001f 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "rpcserver.h" @@ -39,8 +39,7 @@ Value CallRPC(string args) Value result = (*method)(params, false); return result; } - catch (Object& objError) - { + catch (const Object& objError) { throw runtime_error(find_value(objError, "message").get_str()); } } diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 1dc2a3d82f..57c49c2dfc 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2013-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "rpcserver.h" @@ -14,7 +14,7 @@ using namespace std; using namespace json_spirit; -extern Array createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL); +extern Array createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL); extern Value CallRPC(string args); extern CWallet* pwalletMain; @@ -53,10 +53,10 @@ BOOST_AUTO_TEST_CASE(rpc_addmultisig) BOOST_CHECK_THROW(addmultisig(createArgs(1, ""), false), runtime_error); BOOST_CHECK_THROW(addmultisig(createArgs(1, "NotAValidPubkey"), false), runtime_error); - string short1(address1Hex, address1Hex+sizeof(address1Hex)-2); // last byte missing + string short1(address1Hex, address1Hex + sizeof(address1Hex) - 2); // last byte missing BOOST_CHECK_THROW(addmultisig(createArgs(2, short1.c_str()), false), runtime_error); - string short2(address1Hex+1, address1Hex+sizeof(address1Hex)); // first byte missing + string short2(address1Hex + 1, address1Hex + sizeof(address1Hex)); // first byte missing BOOST_CHECK_THROW(addmultisig(createArgs(2, short2.c_str()), false), runtime_error); } @@ -68,26 +68,37 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) LOCK2(cs_main, pwalletMain->cs_wallet); CPubKey demoPubkey = pwalletMain->GenerateNewKey(); - CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID())); - Value 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); - }); - - - /********************************* - * setaccount - *********************************/ - BOOST_CHECK_NO_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ nullaccount")); - BOOST_CHECK_THROW(CallRPC("setaccount"), runtime_error); - /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X (33 chars) is an illegal address (should be 34 chars) */ - BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X nullaccount"), runtime_error); + CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID())); + Value 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())); + + /********************************* + * setaccount + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("setaccount " + setaccountDemoAddress.ToString() + " nullaccount")); + /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ is not owned by the test wallet. */ + BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ nullaccount"), runtime_error); + BOOST_CHECK_THROW(CallRPC("setaccount"), runtime_error); + /* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X (33 chars) is an illegal address (should be 34 chars) */ + BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X nullaccount"), runtime_error); + + + /********************************* + * getbalance + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("getbalance")); + BOOST_CHECK_NO_THROW(CallRPC("getbalance " + demoAddress.ToString())); /********************************* * listunspent @@ -97,12 +108,12 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) BOOST_CHECK_THROW(CallRPC("listunspent 0 string"), runtime_error); BOOST_CHECK_THROW(CallRPC("listunspent 0 1 not_array"), runtime_error); BOOST_CHECK_THROW(CallRPC("listunspent 0 1 [] extra"), runtime_error); - BOOST_CHECK_NO_THROW(r=CallRPC("listunspent 0 1 []")); + BOOST_CHECK_NO_THROW(r = CallRPC("listunspent 0 1 []")); BOOST_CHECK(r.get_array().empty()); /********************************* - * listreceivedbyaddress - *********************************/ + * listreceivedbyaddress + *********************************/ BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress")); BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0")); BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress not_int"), runtime_error); @@ -111,8 +122,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 true extra"), runtime_error); /********************************* - * listreceivedbyaccount - *********************************/ + * listreceivedbyaccount + *********************************/ BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount")); BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0")); BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount not_int"), runtime_error); @@ -121,60 +132,87 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 true extra"), runtime_error); /********************************* - * getrawchangeaddress - *********************************/ + * listsinceblock + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("listsinceblock")); + + /********************************* + * listtransactions + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("listtransactions")); + BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString())); + BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20")); + BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20 0")); + BOOST_CHECK_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " not_int"), runtime_error); + + /********************************* + * listlockunspent + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("listlockunspent")); + + /********************************* + * listaccounts + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("listaccounts")); + + /********************************* + * listaddressgroupings + *********************************/ + BOOST_CHECK_NO_THROW(CallRPC("listaddressgroupings")); + + /********************************* + * getrawchangeaddress + *********************************/ BOOST_CHECK_NO_THROW(CallRPC("getrawchangeaddress")); /********************************* - * getnewaddress - *********************************/ + * getnewaddress + *********************************/ BOOST_CHECK_NO_THROW(CallRPC("getnewaddress")); BOOST_CHECK_NO_THROW(CallRPC("getnewaddress getnewaddress_demoaccount")); /********************************* - * getaccountaddress - *********************************/ + * getaccountaddress + *********************************/ BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress \"\"")); - BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress accountThatDoesntExists")); // Should generate a new account - BOOST_CHECK_NO_THROW(retValue = CallRPC("getaccountaddress " + strAccount)); - BOOST_CHECK(CBitcoinAddress(retValue.get_str()).Get() == demoAddress.Get()); - - /********************************* - * getaccount - *********************************/ - BOOST_CHECK_THROW(CallRPC("getaccount"), runtime_error); - BOOST_CHECK_NO_THROW(CallRPC("getaccount " + demoAddress.ToString())); - - /********************************* - * signmessage + verifymessage - *********************************/ - BOOST_CHECK_NO_THROW(retValue = CallRPC("signmessage " + demoAddress.ToString() + " mymessage")); - BOOST_CHECK_THROW(CallRPC("signmessage"), runtime_error); - /* Should throw error because this address is not loaded in the wallet */ - BOOST_CHECK_THROW(CallRPC("signmessage 1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ mymessage"), runtime_error); - - /* missing arguments */ - BOOST_CHECK_THROW(CallRPC("verifymessage "+ demoAddress.ToString()), runtime_error); - BOOST_CHECK_THROW(CallRPC("verifymessage "+ demoAddress.ToString() + " " + retValue.get_str()), runtime_error); - /* Illegal address */ - BOOST_CHECK_THROW(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X " + retValue.get_str() + " mymessage"), runtime_error); - /* wrong address */ - BOOST_CHECK(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ " + retValue.get_str() + " mymessage").get_bool() == false); - /* Correct address and signature but wrong message */ - BOOST_CHECK(CallRPC("verifymessage "+ demoAddress.ToString() + " " + retValue.get_str() + " wrongmessage").get_bool() == false); - /* Correct address, message and signature*/ - BOOST_CHECK(CallRPC("verifymessage "+ demoAddress.ToString() + " " + retValue.get_str() + " mymessage").get_bool() == true); - - /********************************* - * getaddressesbyaccount - *********************************/ - BOOST_CHECK_THROW(CallRPC("getaddressesbyaccount"), runtime_error); - BOOST_CHECK_NO_THROW(retValue = CallRPC("getaddressesbyaccount " + strAccount)); - Array arr = retValue.get_array(); - BOOST_CHECK(arr.size() > 0); - BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get()); + BOOST_CHECK_NO_THROW(CallRPC("getaccountaddress accountThatDoesntExists")); // Should generate a new account + BOOST_CHECK_NO_THROW(retValue = CallRPC("getaccountaddress " + strAccount)); + BOOST_CHECK(CBitcoinAddress(retValue.get_str()).Get() == demoAddress.Get()); -} + /********************************* + * getaccount + *********************************/ + BOOST_CHECK_THROW(CallRPC("getaccount"), runtime_error); + BOOST_CHECK_NO_THROW(CallRPC("getaccount " + demoAddress.ToString())); + /********************************* + * signmessage + verifymessage + *********************************/ + BOOST_CHECK_NO_THROW(retValue = CallRPC("signmessage " + demoAddress.ToString() + " mymessage")); + BOOST_CHECK_THROW(CallRPC("signmessage"), runtime_error); + /* Should throw error because this address is not loaded in the wallet */ + BOOST_CHECK_THROW(CallRPC("signmessage 1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ mymessage"), runtime_error); + + /* missing arguments */ + BOOST_CHECK_THROW(CallRPC("verifymessage " + demoAddress.ToString()), runtime_error); + BOOST_CHECK_THROW(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str()), runtime_error); + /* Illegal address */ + BOOST_CHECK_THROW(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X " + retValue.get_str() + " mymessage"), runtime_error); + /* wrong address */ + BOOST_CHECK(CallRPC("verifymessage 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ " + retValue.get_str() + " mymessage").get_bool() == false); + /* Correct address and signature but wrong message */ + BOOST_CHECK(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str() + " wrongmessage").get_bool() == false); + /* Correct address, message and signature*/ + BOOST_CHECK(CallRPC("verifymessage " + demoAddress.ToString() + " " + retValue.get_str() + " mymessage").get_bool() == true); + + /********************************* + * getaddressesbyaccount + *********************************/ + BOOST_CHECK_THROW(CallRPC("getaddressesbyaccount"), runtime_error); + BOOST_CHECK_NO_THROW(retValue = CallRPC("getaddressesbyaccount " + strAccount)); + Array arr = retValue.get_array(); + BOOST_CHECK(arr.size() > 0); + BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get()); +} BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index e6cf00c2d0..63553556ec 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -1,11 +1,12 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "key.h" #include "keystore.h" #include "main.h" #include "script/script.h" +#include "script/script_error.h" #include "script/sign.h" #ifdef ENABLE_WALLET @@ -27,7 +28,7 @@ Serialize(const CScript& s) } static bool -Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict) +Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, ScriptError& err) { // Create dummy to/from transactions: CMutableTransaction txFrom; @@ -42,7 +43,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict) txTo.vin[0].scriptSig = scriptSig; txTo.vout[0].nValue = 1; - return VerifyScript(scriptSig, scriptPubKey, txTo, 0, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE); + return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, SignatureChecker(txTo, 0), &err); } @@ -67,15 +68,15 @@ BOOST_AUTO_TEST_CASE(sign) // 8 Scripts: checking all combinations of // different keys, straight/P2SH, pubkey/pubkeyhash CScript standardScripts[4]; - standardScripts[0] << key[0].GetPubKey() << OP_CHECKSIG; + standardScripts[0] << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG; standardScripts[1] = GetScriptForDestination(key[1].GetPubKey().GetID()); - standardScripts[2] << key[1].GetPubKey() << OP_CHECKSIG; + standardScripts[2] << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG; standardScripts[3] = GetScriptForDestination(key[2].GetPubKey().GetID()); CScript evalScripts[4]; for (int i = 0; i < 4; i++) { keystore.AddCScript(standardScripts[i]); - evalScripts[i] = GetScriptForDestination(standardScripts[i].GetID()); + evalScripts[i] = GetScriptForDestination(CScriptID(standardScripts[i])); } CMutableTransaction txFrom; // Funding transaction: @@ -113,7 +114,7 @@ BOOST_AUTO_TEST_CASE(sign) { CScript sigSave = txTo[i].vin[0].scriptSig; txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig; - bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC)(); + bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false)(); if (i == j) BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j)); else @@ -124,26 +125,29 @@ BOOST_AUTO_TEST_CASE(sign) BOOST_AUTO_TEST_CASE(norecurse) { + ScriptError err; // Make sure only the outer pay-to-script-hash does the // extra-validation thing: CScript invalidAsScript; invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE; - CScript p2sh = GetScriptForDestination(invalidAsScript.GetID()); + CScript p2sh = GetScriptForDestination(CScriptID(invalidAsScript)); CScript scriptSig; scriptSig << Serialize(invalidAsScript); // Should not verify, because it will try to execute OP_INVALIDOPCODE - BOOST_CHECK(!Verify(scriptSig, p2sh, true)); + BOOST_CHECK(!Verify(scriptSig, p2sh, true, err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_BAD_OPCODE, ScriptErrorString(err)); // Try to recur, and verification should succeed because // the inner HASH160 <> EQUAL should only check the hash: - CScript p2sh2 = GetScriptForDestination(p2sh.GetID()); + CScript p2sh2 = GetScriptForDestination(CScriptID(p2sh)); CScript scriptSig2; scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh); - BOOST_CHECK(Verify(scriptSig2, p2sh2, true)); + BOOST_CHECK(Verify(scriptSig2, p2sh2, true, err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } BOOST_AUTO_TEST_CASE(set) @@ -169,7 +173,7 @@ BOOST_AUTO_TEST_CASE(set) CScript outer[4]; for (int i = 0; i < 4; i++) { - outer[i] = GetScriptForDestination(inner[i].GetID()); + outer[i] = GetScriptForDestination(CScriptID(inner[i])); keystore.AddCScript(inner[i]); } @@ -206,9 +210,9 @@ BOOST_AUTO_TEST_CASE(set) BOOST_AUTO_TEST_CASE(is) { // Test CScript::IsPayToScriptHash() - uint160 dummy; + uint160 dummy(0); CScript p2sh; - p2sh << OP_HASH160 << dummy << OP_EQUAL; + p2sh << OP_HASH160 << ToByteVector(dummy) << OP_EQUAL; BOOST_CHECK(p2sh.IsPayToScriptHash()); // Not considered pay-to-script-hash if using one of the OP_PUSHDATA opcodes: @@ -224,13 +228,13 @@ BOOST_AUTO_TEST_CASE(is) CScript not_p2sh; BOOST_CHECK(!not_p2sh.IsPayToScriptHash()); - not_p2sh.clear(); not_p2sh << OP_HASH160 << dummy << dummy << OP_EQUAL; + not_p2sh.clear(); not_p2sh << OP_HASH160 << ToByteVector(dummy) << ToByteVector(dummy) << OP_EQUAL; BOOST_CHECK(!not_p2sh.IsPayToScriptHash()); - not_p2sh.clear(); not_p2sh << OP_NOP << dummy << OP_EQUAL; + not_p2sh.clear(); not_p2sh << OP_NOP << ToByteVector(dummy) << OP_EQUAL; BOOST_CHECK(!not_p2sh.IsPayToScriptHash()); - not_p2sh.clear(); not_p2sh << OP_HASH160 << dummy << OP_CHECKSIG; + not_p2sh.clear(); not_p2sh << OP_HASH160 << ToByteVector(dummy) << OP_CHECKSIG; BOOST_CHECK(!not_p2sh.IsPayToScriptHash()); } @@ -238,24 +242,27 @@ BOOST_AUTO_TEST_CASE(switchover) { // Test switch over code CScript notValid; + ScriptError err; notValid << OP_11 << OP_12 << OP_EQUALVERIFY; CScript scriptSig; scriptSig << Serialize(notValid); - CScript fund = GetScriptForDestination(notValid.GetID()); + CScript fund = GetScriptForDestination(CScriptID(notValid)); // Validation should succeed under old rules (hash is correct): - BOOST_CHECK(Verify(scriptSig, fund, false)); + BOOST_CHECK(Verify(scriptSig, fund, false, err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); // Fail under new: - BOOST_CHECK(!Verify(scriptSig, fund, true)); + BOOST_CHECK(!Verify(scriptSig, fund, true, err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EQUALVERIFY, ScriptErrorString(err)); } BOOST_AUTO_TEST_CASE(AreInputsStandard) { LOCK(cs_main); CCoinsView coinsDummy; - CCoinsViewCache coins(coinsDummy); + CCoinsViewCache coins(&coinsDummy); CBasicKeyStore keystore; CKey key[6]; vector<CPubKey> keys; @@ -275,7 +282,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) keystore.AddCScript(pay1); CScript pay1of3 = GetScriptForMultisig(1, keys); - txFrom.vout[0].scriptPubKey = GetScriptForDestination(pay1.GetID()); // P2SH (OP_CHECKSIG) + txFrom.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(pay1)); // P2SH (OP_CHECKSIG) txFrom.vout[0].nValue = 1000; txFrom.vout[1].scriptPubKey = pay1; // ordinary OP_CHECKSIG txFrom.vout[1].nValue = 2000; @@ -285,35 +292,34 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) // vout[3] is complicated 1-of-3 AND 2-of-3 // ... that is OK if wrapped in P2SH: CScript oneAndTwo; - oneAndTwo << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey(); + oneAndTwo << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()); oneAndTwo << OP_3 << OP_CHECKMULTISIGVERIFY; - oneAndTwo << OP_2 << key[3].GetPubKey() << key[4].GetPubKey() << key[5].GetPubKey(); + oneAndTwo << OP_2 << ToByteVector(key[3].GetPubKey()) << ToByteVector(key[4].GetPubKey()) << ToByteVector(key[5].GetPubKey()); oneAndTwo << OP_3 << OP_CHECKMULTISIG; keystore.AddCScript(oneAndTwo); - txFrom.vout[3].scriptPubKey = GetScriptForDestination(oneAndTwo.GetID()); + txFrom.vout[3].scriptPubKey = GetScriptForDestination(CScriptID(oneAndTwo)); txFrom.vout[3].nValue = 4000; // vout[4] is max sigops: CScript fifteenSigops; fifteenSigops << OP_1; for (unsigned i = 0; i < MAX_P2SH_SIGOPS; i++) - fifteenSigops << key[i%3].GetPubKey(); + fifteenSigops << ToByteVector(key[i%3].GetPubKey()); fifteenSigops << OP_15 << OP_CHECKMULTISIG; keystore.AddCScript(fifteenSigops); - txFrom.vout[4].scriptPubKey = GetScriptForDestination(fifteenSigops.GetID()); + txFrom.vout[4].scriptPubKey = GetScriptForDestination(CScriptID(fifteenSigops)); txFrom.vout[4].nValue = 5000; // vout[5/6] are non-standard because they exceed MAX_P2SH_SIGOPS CScript sixteenSigops; sixteenSigops << OP_16 << OP_CHECKMULTISIG; keystore.AddCScript(sixteenSigops); - txFrom.vout[5].scriptPubKey = GetScriptForDestination(fifteenSigops.GetID()); + txFrom.vout[5].scriptPubKey = GetScriptForDestination(CScriptID(fifteenSigops)); txFrom.vout[5].nValue = 5000; CScript twentySigops; twentySigops << OP_CHECKMULTISIG; keystore.AddCScript(twentySigops); - txFrom.vout[6].scriptPubKey = GetScriptForDestination(twentySigops.GetID()); + txFrom.vout[6].scriptPubKey = GetScriptForDestination(CScriptID(twentySigops)); txFrom.vout[6].nValue = 6000; - - coins.SetCoins(txFrom.GetHash(), CCoins(txFrom, 0)); + coins.ModifyCoins(txFrom.GetHash())->FromTx(txFrom, 0); CMutableTransaction txTo; txTo.vout.resize(1); diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index cb543a0cf1..4d2a9aff45 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -1,16 +1,22 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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 "data/script_invalid.json.h" #include "data/script_valid.json.h" +#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 "core_io.h" +#include "util.h" + +#if defined(HAVE_CONSENSUS_LIB) +#include "script/bitcoinconsensus.h" +#endif #include <fstream> #include <stdint.h> @@ -33,9 +39,13 @@ using namespace std; using namespace json_spirit; using namespace boost::algorithm; +// Uncomment if you want to output updated JSON tests. +// #define UPDATE_JSON_TESTS + static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; unsigned int ParseScriptFlags(string strFlags); +string FormatScriptFlags(unsigned int flags); Array read_json(const std::string& jsondata) @@ -52,6 +62,484 @@ read_json(const std::string& jsondata) BOOST_AUTO_TEST_SUITE(script_tests) +CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey) +{ + CMutableTransaction txCredit; + txCredit.nVersion = 1; + txCredit.nLockTime = 0; + txCredit.vin.resize(1); + txCredit.vout.resize(1); + txCredit.vin[0].prevout.SetNull(); + txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0); + txCredit.vin[0].nSequence = std::numeric_limits<unsigned int>::max(); + txCredit.vout[0].scriptPubKey = scriptPubKey; + txCredit.vout[0].nValue = 0; + + return txCredit; +} + +CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMutableTransaction& txCredit) +{ + CMutableTransaction txSpend; + txSpend.nVersion = 1; + txSpend.nLockTime = 0; + txSpend.vin.resize(1); + txSpend.vout.resize(1); + txSpend.vin[0].prevout.hash = txCredit.GetHash(); + txSpend.vin[0].prevout.n = 0; + txSpend.vin[0].scriptSig = scriptSig; + txSpend.vin[0].nSequence = std::numeric_limits<unsigned int>::max(); + txSpend.vout[0].scriptPubKey = CScript(); + txSpend.vout[0].nValue = 0; + + return txSpend; +} + +void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message) +{ + ScriptError err; + CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)); + CMutableTransaction tx2 = tx; + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, SignatureChecker(tx, 0), &err) == expect, message); + BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message); +#if defined(HAVE_CONSENSUS_LIB) + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << tx2; + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(begin_ptr(scriptPubKey), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect,message); +#endif +} + +void static NegateSignatureS(std::vector<unsigned char>& vchSig) { + // Parse the signature. + std::vector<unsigned char> r, s; + r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]); + s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]); + unsigned char hashtype = vchSig.back(); + + // Really ugly to implement mod-n negation here, but it would be feature creep to expose such functionality from libsecp256k1. + static const unsigned char order[33] = { + 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, + 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 + }; + while (s.size() < 33) { + s.insert(s.begin(), 0x00); + } + int carry = 0; + for (int p = 32; p >= 1; p--) { + int n = (int)order[p] - s[p] - carry; + s[p] = (n + 256) & 0xFF; + carry = (n < 0); + } + assert(carry == 0); + if (s.size() > 1 && s[0] == 0 && s[1] < 0x80) { + s.erase(s.begin()); + } + + // Reconstruct the signature. + vchSig.clear(); + vchSig.push_back(0x30); + vchSig.push_back(4 + r.size() + s.size()); + vchSig.push_back(0x02); + vchSig.push_back(r.size()); + vchSig.insert(vchSig.end(), r.begin(), r.end()); + vchSig.push_back(0x02); + vchSig.push_back(s.size()); + vchSig.insert(vchSig.end(), s.begin(), s.end()); + vchSig.push_back(hashtype); +} + +namespace +{ +const unsigned char vchKey0[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; +const unsigned char vchKey1[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}; +const unsigned char vchKey2[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0}; + +struct KeyData +{ + CKey key0, key0C, key1, key1C, key2, key2C; + CPubKey pubkey0, pubkey0C, pubkey0H; + CPubKey pubkey1, pubkey1C; + CPubKey pubkey2, pubkey2C; + + KeyData() + { + + key0.Set(vchKey0, vchKey0 + 32, false); + key0C.Set(vchKey0, vchKey0 + 32, true); + pubkey0 = key0.GetPubKey(); + pubkey0H = key0.GetPubKey(); + pubkey0C = key0C.GetPubKey(); + *const_cast<unsigned char*>(&pubkey0H[0]) = 0x06 | (pubkey0H[64] & 1); + + key1.Set(vchKey1, vchKey1 + 32, false); + key1C.Set(vchKey1, vchKey1 + 32, true); + pubkey1 = key1.GetPubKey(); + pubkey1C = key1C.GetPubKey(); + + key2.Set(vchKey2, vchKey2 + 32, false); + key2C.Set(vchKey2, vchKey2 + 32, true); + pubkey2 = key2.GetPubKey(); + pubkey2C = key2C.GetPubKey(); + } +}; + + +class TestBuilder +{ +private: + CScript scriptPubKey; + CTransaction creditTx; + CMutableTransaction spendTx; + bool havePush; + std::vector<unsigned char> push; + std::string comment; + int flags; + + void DoPush() + { + if (havePush) { + spendTx.vin[0].scriptSig << push; + havePush = false; + } + } + + void DoPush(const std::vector<unsigned char>& data) + { + DoPush(); + push = data; + havePush = true; + } + +public: + TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_) + { + if (P2SH) { + creditTx = BuildCreditingTransaction(CScript() << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL); + } else { + creditTx = BuildCreditingTransaction(redeemScript); + } + spendTx = BuildSpendingTransaction(CScript(), creditTx); + } + + TestBuilder& Add(const CScript& script) + { + DoPush(); + spendTx.vin[0].scriptSig += script; + return *this; + } + + TestBuilder& Num(int num) + { + DoPush(); + spendTx.vin[0].scriptSig << num; + return *this; + } + + TestBuilder& Push(const std::string& hex) + { + DoPush(ParseHex(hex)); + return *this; + } + + TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32) + { + uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType); + std::vector<unsigned char> vchSig, r, s; + uint32_t iter = 0; + do { + key.Sign(hash, vchSig, iter++); + if ((lenS == 33) != (vchSig[5 + vchSig[3]] == 33)) { + NegateSignatureS(vchSig); + } + r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]); + s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]); + } while (lenR != r.size() || lenS != s.size()); + vchSig.push_back(static_cast<unsigned char>(nHashType)); + DoPush(vchSig); + return *this; + } + + TestBuilder& Push(const CPubKey& pubkey) + { + DoPush(std::vector<unsigned char>(pubkey.begin(), pubkey.end())); + return *this; + } + + TestBuilder& PushRedeem() + { + DoPush(static_cast<std::vector<unsigned char> >(scriptPubKey)); + return *this; + } + + TestBuilder& EditPush(unsigned int pos, const std::string& hexin, const std::string& hexout) + { + assert(havePush); + std::vector<unsigned char> datain = ParseHex(hexin); + std::vector<unsigned char> dataout = ParseHex(hexout); + assert(pos + datain.size() <= push.size()); + BOOST_CHECK_MESSAGE(std::vector<unsigned char>(push.begin() + pos, push.begin() + pos + datain.size()) == datain, comment); + push.erase(push.begin() + pos, push.begin() + pos + datain.size()); + push.insert(push.begin() + pos, dataout.begin(), dataout.end()); + return *this; + } + + TestBuilder& DamagePush(unsigned int pos) + { + assert(havePush); + assert(pos < push.size()); + push[pos] ^= 1; + return *this; + } + + TestBuilder& Test(bool expect) + { + TestBuilder copy = *this; // Make a copy so we can rollback the push. + DoPush(); + DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, expect, comment); + *this = copy; + return *this; + } + + Array GetJSON() + { + DoPush(); + Array array; + array.push_back(FormatScript(spendTx.vin[0].scriptSig)); + array.push_back(FormatScript(creditTx.vout[0].scriptPubKey)); + array.push_back(FormatScriptFlags(flags)); + array.push_back(comment); + return array; + } + + std::string GetComment() + { + return comment; + } + + const CScript& GetScriptPubKey() + { + return creditTx.vout[0].scriptPubKey; + } +}; +} + +BOOST_AUTO_TEST_CASE(script_build) +{ + const KeyData keys; + + std::vector<TestBuilder> good; + std::vector<TestBuilder> bad; + + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2PK", 0 + ).PushSig(keys.key0)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, + "P2PK, bad sig", 0 + ).PushSig(keys.key0).DamagePush(10)); + + good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, + "P2PKH", 0 + ).PushSig(keys.key1).Push(keys.pubkey1C)); + bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey2C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, + "P2PKH, bad pubkey", 0 + ).PushSig(keys.key2).Push(keys.pubkey2C).DamagePush(5)); + + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, + "P2PK anyonecanpay", 0 + ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, + "P2PK anyonecanpay marked with normal hashtype", 0 + ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY).EditPush(70, "81", "01")); + + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, + "P2SH(P2PK)", SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key0).PushRedeem()); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, + "P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key0).PushRedeem().DamagePush(10)); + + good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, + "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0, true + ).PushSig(keys.key0).DamagePush(10).PushRedeem()); + bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, + "P2SH(P2PKH), bad sig", SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key0).DamagePush(10).PushRedeem()); + + good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, + "3-of-3", 0 + ).Num(0).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2)); + bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, + "3-of-3, 2 sigs", 0 + ).Num(0).PushSig(keys.key0).PushSig(keys.key1).Num(0)); + + good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, + "P2SH(2-of-3)", SCRIPT_VERIFY_P2SH, true + ).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem()); + bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, + "P2SH(2-of-3), 1 sig", SCRIPT_VERIFY_P2SH, true + ).Num(0).PushSig(keys.key1).Num(0).PushRedeem()); + + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "P2PK with too much R padding but no DERSIG", 0 + ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "P2PK with too much R padding", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "P2PK with too much S padding but no DERSIG", 0 + ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100")); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "P2PK with too much S padding", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100")); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "P2PK with too little R padding but no DERSIG", 0 + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, + "P2PK with too little R padding", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with bad sig with too much R padding but no DERSIG", 0 + ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with bad sig with too much R padding", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with too much R padding but no DERSIG", 0 + ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with too much R padding", SCRIPT_VERIFY_DERSIG + ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); + + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2PK with high S but no LOW_S", 0 + ).PushSig(keys.key2, SIGHASH_ALL, 32, 33)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2PK with high S", SCRIPT_VERIFY_LOW_S + ).PushSig(keys.key2, SIGHASH_ALL, 32, 33)); + + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG, + "P2PK with hybrid pubkey but no STRICTENC", 0 + ).PushSig(keys.key0, SIGHASH_ALL)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG, + "P2PK with hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key0, SIGHASH_ALL)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with hybrid pubkey but no STRICTENC", 0 + ).PushSig(keys.key0, SIGHASH_ALL)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key0, SIGHASH_ALL)); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0 + ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with invalid hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10)); + good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, + "1-of-2 with the second 1 hybrid pubkey and no STRICTENC", 0 + ).Num(0).PushSig(keys.key1, SIGHASH_ALL)); + good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, + "1-of-2 with the second 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).Num(0).PushSig(keys.key1, SIGHASH_ALL)); + bad.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0H) << OP_2 << OP_CHECKMULTISIG, + "1-of-2 with the first 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).Num(0).PushSig(keys.key1, SIGHASH_ALL)); + + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, + "P2PK with undefined hashtype but no STRICTENC", 0 + ).PushSig(keys.key1, 5)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, + "P2PK with undefined hashtype", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key1, 5)); + good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", 0 + ).PushSig(keys.key1, 5).DamagePush(10)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with invalid sig and undefined hashtype", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key1, 5).DamagePush(10)); + + good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, + "3-of-3 with nonzero dummy but no NULLDUMMY", 0 + ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2)); + bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, + "3-of-3 with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY + ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2)); + good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT, + "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY", 0 + ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10)); + bad.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT, + "3-of-3 NOT with invalid sig with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY + ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10)); + + good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, + "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY", 0 + ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP)); + bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, + "2-of-2 with two identical keys and sigs pushed using OP_DUP", SCRIPT_VERIFY_SIGPUSHONLY + ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", 0 + ).PushSig(keys.key2).PushRedeem()); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, + "P2SH(P2PK) with non-push scriptSig", SCRIPT_VERIFY_SIGPUSHONLY + ).PushSig(keys.key2).PushRedeem()); + good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, + "2-of-2 with two identical keys and sigs pushed", SCRIPT_VERIFY_SIGPUSHONLY + ).Num(0).PushSig(keys.key1).PushSig(keys.key1)); + + + std::set<std::string> tests_good; + 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))); + + BOOST_FOREACH(Value& tv, json_good) { + tests_good.insert(write_string(Value(tv.get_array()), true)); + } + BOOST_FOREACH(Value& tv, json_bad) { + tests_bad.insert(write_string(Value(tv.get_array()), true)); + } + } + + std::string strGood; + std::string strBad; + + BOOST_FOREACH(TestBuilder& test, good) { + test.Test(true); + std::string str = write_string(Value(test.GetJSON()), true); +#ifndef UPDATE_JSON_TESTS + if (tests_good.count(str) == 0) { + BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + test.GetComment()); + } +#endif + strGood += str + ",\n"; + } + BOOST_FOREACH(TestBuilder& test, bad) { + test.Test(false); + std::string str = write_string(Value(test.GetJSON()), true); +#ifndef UPDATE_JSON_TESTS + if (tests_bad.count(str) == 0) { + BOOST_CHECK_MESSAGE(false, "Missing auto script_invalid test: " + test.GetComment()); + } +#endif + strBad += str + ",\n"; + } + +#ifdef UPDATE_JSON_TESTS + FILE* valid = fopen("script_valid.json.gen", "w"); + fputs(strGood.c_str(), valid); + fclose(valid); + FILE* invalid = fopen("script_invalid.json.gen", "w"); + fputs(strBad.c_str(), invalid); + fclose(invalid); +#endif +} + BOOST_AUTO_TEST_CASE(script_valid) { // Read tests from test/data/script_valid.json @@ -67,7 +555,9 @@ BOOST_AUTO_TEST_CASE(script_valid) string strTest = write_string(tv, false); if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments) { - BOOST_ERROR("Bad test: " << strTest); + if (test.size() != 1) { + BOOST_ERROR("Bad test: " << strTest); + } continue; } string scriptSigString = test[0].get_str(); @@ -76,8 +566,7 @@ BOOST_AUTO_TEST_CASE(script_valid) CScript scriptPubKey = ParseScript(scriptPubKeyString); unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); - CTransaction tx; - BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, tx, 0, scriptflags), strTest); + DoTest(scriptPubKey, scriptSig, scriptflags, true, strTest); } } @@ -90,9 +579,11 @@ BOOST_AUTO_TEST_CASE(script_invalid) { Array test = tv.get_array(); string strTest = write_string(tv, false); - if (test.size() < 2) // Allow size > 2; extra stuff ignored (useful for comments) + if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments) { - BOOST_ERROR("Bad test: " << strTest); + if (test.size() != 1) { + BOOST_ERROR("Bad test: " << strTest); + } continue; } string scriptSigString = test[0].get_str(); @@ -101,8 +592,7 @@ BOOST_AUTO_TEST_CASE(script_invalid) CScript scriptPubKey = ParseScript(scriptPubKeyString); unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); - CTransaction tx; - BOOST_CHECK_MESSAGE(!VerifyScript(scriptSig, scriptPubKey, tx, 0, scriptflags), strTest); + DoTest(scriptPubKey, scriptSig, scriptflags, false, strTest); } } @@ -115,20 +605,25 @@ BOOST_AUTO_TEST_CASE(script_PushData) static const unsigned char pushdata2[] = { OP_PUSHDATA2, 1, 0, 0x5a }; static const unsigned char pushdata4[] = { OP_PUSHDATA4, 1, 0, 0, 0, 0x5a }; + ScriptError err; vector<vector<unsigned char> > directStack; - BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), CTransaction(), 0, true)); + BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), true, BaseSignatureChecker(), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); vector<vector<unsigned char> > pushdata1Stack; - BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), CTransaction(), 0, true)); + BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), true, BaseSignatureChecker(), &err)); BOOST_CHECK(pushdata1Stack == directStack); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); vector<vector<unsigned char> > pushdata2Stack; - BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), CTransaction(), 0, true)); + BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), true, BaseSignatureChecker(), &err)); BOOST_CHECK(pushdata2Stack == directStack); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); vector<vector<unsigned char> > pushdata4Stack; - BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), CTransaction(), 0, true)); + BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), true, BaseSignatureChecker(), &err)); BOOST_CHECK(pushdata4Stack == directStack); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } CScript @@ -165,39 +660,37 @@ sign_multisig(CScript scriptPubKey, const CKey &key, CTransaction transaction) BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) { + ScriptError err; CKey key1, key2, key3; key1.MakeNewKey(true); key2.MakeNewKey(false); key3.MakeNewKey(true); CScript scriptPubKey12; - scriptPubKey12 << OP_1 << key1.GetPubKey() << key2.GetPubKey() << OP_2 << OP_CHECKMULTISIG; - - CMutableTransaction txFrom12; - txFrom12.vout.resize(1); - txFrom12.vout[0].scriptPubKey = scriptPubKey12; + scriptPubKey12 << OP_1 << ToByteVector(key1.GetPubKey()) << ToByteVector(key2.GetPubKey()) << OP_2 << OP_CHECKMULTISIG; - CMutableTransaction txTo12; - txTo12.vin.resize(1); - txTo12.vout.resize(1); - txTo12.vin[0].prevout.n = 0; - txTo12.vin[0].prevout.hash = txFrom12.GetHash(); - txTo12.vout[0].nValue = 1; + CMutableTransaction txFrom12 = BuildCreditingTransaction(scriptPubKey12); + CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12); CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, flags)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); txTo12.vout[0].nValue = 2; - BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, flags)); + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, txTo12, 0, flags)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, txTo12, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) { + ScriptError err; CKey key1, key2, key3, key4; key1.MakeNewKey(true); key2.MakeNewKey(false); @@ -205,62 +698,63 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) key4.MakeNewKey(false); CScript scriptPubKey23; - scriptPubKey23 << OP_2 << key1.GetPubKey() << key2.GetPubKey() << key3.GetPubKey() << OP_3 << OP_CHECKMULTISIG; - - CMutableTransaction txFrom23; - txFrom23.vout.resize(1); - txFrom23.vout[0].scriptPubKey = scriptPubKey23; + scriptPubKey23 << OP_2 << ToByteVector(key1.GetPubKey()) << ToByteVector(key2.GetPubKey()) << ToByteVector(key3.GetPubKey()) << OP_3 << OP_CHECKMULTISIG; - CMutableTransaction txTo23; - txTo23.vin.resize(1); - txTo23.vout.resize(1); - txTo23.vin[0].prevout.n = 0; - txTo23.vin[0].prevout.hash = txFrom23.GetHash(); - txTo23.vout[0].nValue = 1; + CMutableTransaction txFrom23 = BuildCreditingTransaction(scriptPubKey23); + CMutableTransaction txTo23 = BuildSpendingTransaction(CScript(), txFrom23); std::vector<CKey> keys; keys.push_back(key1); keys.push_back(key2); CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key3); CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key3); CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key2); // Can't re-use sig CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); // Must have signatures CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, txTo23, 0, flags)); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err)); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); } BOOST_AUTO_TEST_CASE(script_combineSigs) @@ -278,17 +772,10 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) keystore.AddKey(key); } - CMutableTransaction txFrom; - txFrom.vout.resize(1); - txFrom.vout[0].scriptPubKey = GetScriptForDestination(keys[0].GetPubKey().GetID()); + CMutableTransaction txFrom = BuildCreditingTransaction(GetScriptForDestination(keys[0].GetPubKey().GetID())); + CMutableTransaction txTo = BuildSpendingTransaction(CScript(), txFrom); CScript& scriptPubKey = txFrom.vout[0].scriptPubKey; - CMutableTransaction txTo; - txTo.vin.resize(1); - txTo.vout.resize(1); - txTo.vin[0].prevout.n = 0; - txTo.vin[0].prevout.hash = txFrom.GetHash(); CScript& scriptSig = txTo.vin[0].scriptSig; - txTo.vout[0].nValue = 1; CScript empty; CScript combined = CombineSignatures(scriptPubKey, txTo, 0, empty, empty); @@ -307,9 +794,9 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig); // P2SH, single-signature case: - CScript pkSingle; pkSingle << keys[0].GetPubKey() << OP_CHECKSIG; + CScript pkSingle; pkSingle << ToByteVector(keys[0].GetPubKey()) << OP_CHECKSIG; keystore.AddCScript(pkSingle); - scriptPubKey = GetScriptForDestination(pkSingle.GetID()); + scriptPubKey = GetScriptForDestination(CScriptID(pkSingle)); SignSignature(keystore, txFrom, txTo, 0); combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); BOOST_CHECK(combined == scriptSig); @@ -381,19 +868,22 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) BOOST_AUTO_TEST_CASE(script_standard_push) { - for (int i=0; i<1000; i++) { + ScriptError err; + for (int i=0; i<67000; i++) { CScript script; script << i; BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Number " << i << " is not pure push."); - BOOST_CHECK_MESSAGE(script.HasCanonicalPushes(), "Number " << i << " push is not canonical."); + BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Number " << i << " push is not minimal data."); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } - for (int i=0; i<1000; i++) { + for (unsigned int i=0; i<=MAX_SCRIPT_ELEMENT_SIZE; i++) { std::vector<unsigned char> data(i, '\111'); CScript script; script << data; BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Length " << i << " is not pure push."); - BOOST_CHECK_MESSAGE(script.HasCanonicalPushes(), "Length " << i << " push is not canonical."); + BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Length " << i << " push is not minimal data."); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } } diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp index ac60fa426f..cfbaf26e70 100644 --- a/src/test/scriptnum_tests.cpp +++ b/src/test/scriptnum_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "bignum.h" @@ -25,11 +25,11 @@ static void CheckCreateVch(const int64_t& num) BOOST_CHECK(verify(bignum, scriptnum)); CBigNum bignum2(bignum.getvch()); - CScriptNum scriptnum2(scriptnum.getvch()); + CScriptNum scriptnum2(scriptnum.getvch(), false); BOOST_CHECK(verify(bignum2, scriptnum2)); CBigNum bignum3(scriptnum2.getvch()); - CScriptNum scriptnum3(bignum2.getvch()); + CScriptNum scriptnum3(bignum2.getvch(), false); BOOST_CHECK(verify(bignum3, scriptnum3)); } diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index 867a7df888..fe49af711b 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -1,8 +1,9 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "serialize.h" +#include "streams.h" #include <stdint.h> diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 8abde887ce..a9d2f9e8ca 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "data/sighash.json.h" diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index 62a6cd63d6..3326601492 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -1,7 +1,8 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "pubkey.h" #include "key.h" #include "script/script.h" #include "script/standard.h" @@ -31,14 +32,14 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount) BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0U); BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0U); - uint160 dummy; - s1 << OP_1 << dummy << dummy << OP_2 << OP_CHECKMULTISIG; + uint160 dummy(0); + s1 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << OP_2 << OP_CHECKMULTISIG; BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2U); s1 << OP_IF << OP_CHECKSIG << OP_ENDIF; BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 3U); BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21U); - CScript p2sh = GetScriptForDestination(s1.GetID()); + CScript p2sh = GetScriptForDestination(CScriptID(s1)); CScript scriptSig; scriptSig << OP_0 << Serialize(s1); BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3U); @@ -54,11 +55,11 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount) BOOST_CHECK_EQUAL(s2.GetSigOpCount(true), 3U); BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20U); - p2sh = GetScriptForDestination(s2.GetID()); + p2sh = GetScriptForDestination(CScriptID(s2)); BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(true), 0U); BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0U); CScript scriptSig2; - scriptSig2 << OP_1 << dummy << dummy << Serialize(s2); + scriptSig2 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << Serialize(s2); BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig2), 3U); } diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index a123f1d197..646c7e6ade 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "main.h" diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 68fad8d038..f2dae99d69 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #define BOOST_TEST_MODULE Bitcoin Test Suite @@ -31,7 +31,7 @@ struct TestingSetup { TestingSetup() { fPrintToDebugLog = false; // don't want to write to debug.log file - SelectParams(CBaseChainParams::MAIN); + SelectParams(CBaseChainParams::UNITTEST); noui_connect(); #ifdef ENABLE_WALLET bitdb.MakeMock(); @@ -41,13 +41,13 @@ struct TestingSetup { mapArgs["-datadir"] = pathTemp.string(); pblocktree = new CBlockTreeDB(1 << 20, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true); - pcoinsTip = new CCoinsViewCache(*pcoinsdbview); + pcoinsTip = new CCoinsViewCache(pcoinsdbview); InitBlockIndex(); #ifdef ENABLE_WALLET bool fFirstRun; pwalletMain = new CWallet("wallet.dat"); pwalletMain->LoadWallet(fFirstRun); - RegisterWallet(pwalletMain); + RegisterValidationInterface(pwalletMain); #endif nScriptCheckThreads = 3; for (int i=0; i < nScriptCheckThreads-1; i++) diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp index aa4fa0d500..58ed963274 100644 --- a/src/test/timedata_tests.cpp +++ b/src/test/timedata_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // #include "timedata.h" diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 41d8ee9f19..2594f89ac3 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -1,14 +1,16 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "data/tx_invalid.json.h" #include "data/tx_valid.json.h" +#include "clientversion.h" #include "key.h" #include "keystore.h" #include "main.h" #include "script/script.h" +#include "script/script_error.h" #include "core_io.h" #include <map> @@ -17,6 +19,7 @@ #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/split.hpp> #include <boost/test/unit_test.hpp> +#include <boost/assign/list_of.hpp> #include "json/json_spirit_writer_template.h" using namespace std; @@ -26,22 +29,26 @@ using namespace boost::algorithm; // In script_tests.cpp extern Array read_json(const std::string& jsondata); -unsigned int ParseScriptFlags(string strFlags){ +static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of + (string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE) + (string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH) + (string("STRICTENC"), (unsigned int)SCRIPT_VERIFY_STRICTENC) + (string("DERSIG"), (unsigned int)SCRIPT_VERIFY_DERSIG) + (string("LOW_S"), (unsigned int)SCRIPT_VERIFY_LOW_S) + (string("SIGPUSHONLY"), (unsigned int)SCRIPT_VERIFY_SIGPUSHONLY) + (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); + +unsigned int ParseScriptFlags(string strFlags) +{ + if (strFlags.empty()) { + return 0; + } unsigned int flags = 0; vector<string> words; split(words, strFlags, is_any_of(",")); - // Note how NOCACHE is not included as it is a runtime-only flag. - static map<string, unsigned int> mapFlagNames; - if (mapFlagNames.size() == 0) - { - mapFlagNames["NONE"] = SCRIPT_VERIFY_NONE; - mapFlagNames["P2SH"] = SCRIPT_VERIFY_P2SH; - mapFlagNames["STRICTENC"] = SCRIPT_VERIFY_STRICTENC; - mapFlagNames["LOW_S"] = SCRIPT_VERIFY_LOW_S; - mapFlagNames["NULLDUMMY"] = SCRIPT_VERIFY_NULLDUMMY; - } - BOOST_FOREACH(string word, words) { if (!mapFlagNames.count(word)) @@ -52,6 +59,22 @@ unsigned int ParseScriptFlags(string strFlags){ return flags; } +string FormatScriptFlags(unsigned int flags) +{ + if (flags == 0) { + return ""; + } + string ret; + std::map<string, unsigned int>::const_iterator it = mapFlagNames.begin(); + while (it != mapFlagNames.end()) { + if (flags & it->second) { + ret += it->first + ","; + } + it++; + } + return ret.substr(0, ret.size() - 1); +} + BOOST_AUTO_TEST_SUITE(transaction_tests) BOOST_AUTO_TEST_CASE(tx_valid) @@ -65,6 +88,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) // 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))); + ScriptError err; BOOST_FOREACH(Value& tv, tests) { Array test = tv.get_array(); @@ -121,8 +145,9 @@ BOOST_AUTO_TEST_CASE(tx_valid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - tx, i, verify_flags), + verify_flags, SignatureChecker(tx, i), &err), strTest); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } } } @@ -139,6 +164,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) // 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))); + ScriptError err; BOOST_FOREACH(Value& tv, tests) { Array test = tv.get_array(); @@ -194,10 +220,10 @@ BOOST_AUTO_TEST_CASE(tx_invalid) unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - tx, i, verify_flags); + verify_flags, SignatureChecker(tx, i), &err); } - BOOST_CHECK_MESSAGE(!fValid, strTest); + BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err)); } } } @@ -225,7 +251,7 @@ BOOST_AUTO_TEST_CASE(basic_transaction_tests) // paid to a TX_PUBKEYHASH. // static std::vector<CMutableTransaction> -SetupDummyInputs(CBasicKeyStore& keystoreRet, CCoinsView & coinsRet) +SetupDummyInputs(CBasicKeyStore& keystoreRet, CCoinsViewCache& coinsRet) { std::vector<CMutableTransaction> dummyTransactions; dummyTransactions.resize(2); @@ -241,17 +267,17 @@ SetupDummyInputs(CBasicKeyStore& keystoreRet, CCoinsView & coinsRet) // Create some dummy input transactions dummyTransactions[0].vout.resize(2); dummyTransactions[0].vout[0].nValue = 11*CENT; - dummyTransactions[0].vout[0].scriptPubKey << key[0].GetPubKey() << OP_CHECKSIG; + dummyTransactions[0].vout[0].scriptPubKey << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG; dummyTransactions[0].vout[1].nValue = 50*CENT; - dummyTransactions[0].vout[1].scriptPubKey << key[1].GetPubKey() << OP_CHECKSIG; - coinsRet.SetCoins(dummyTransactions[0].GetHash(), CCoins(dummyTransactions[0], 0)); + dummyTransactions[0].vout[1].scriptPubKey << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG; + coinsRet.ModifyCoins(dummyTransactions[0].GetHash())->FromTx(dummyTransactions[0], 0); dummyTransactions[1].vout.resize(2); dummyTransactions[1].vout[0].nValue = 21*CENT; dummyTransactions[1].vout[0].scriptPubKey = GetScriptForDestination(key[2].GetPubKey().GetID()); dummyTransactions[1].vout[1].nValue = 22*CENT; dummyTransactions[1].vout[1].scriptPubKey = GetScriptForDestination(key[3].GetPubKey().GetID()); - coinsRet.SetCoins(dummyTransactions[1].GetHash(), CCoins(dummyTransactions[1], 0)); + coinsRet.ModifyCoins(dummyTransactions[1].GetHash())->FromTx(dummyTransactions[1], 0); return dummyTransactions; } @@ -260,7 +286,7 @@ BOOST_AUTO_TEST_CASE(test_Get) { CBasicKeyStore keystore; CCoinsView coinsDummy; - CCoinsViewCache coins(coinsDummy); + CCoinsViewCache coins(&coinsDummy); std::vector<CMutableTransaction> dummyTransactions = SetupDummyInputs(keystore, coins); CMutableTransaction t1; @@ -295,7 +321,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) LOCK(cs_main); CBasicKeyStore keystore; CCoinsView coinsDummy; - CCoinsViewCache coins(coinsDummy); + CCoinsViewCache coins(&coinsDummy); std::vector<CMutableTransaction> dummyTransactions = SetupDummyInputs(keystore, coins); CMutableTransaction t; diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index 4b1a2ae58f..d05b28956c 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2011-2013 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <boost/test/unit_test.hpp> diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 23bc5f6b12..5f0c1deb8e 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -1,5 +1,5 @@ // Copyright 2014 BitPay, Inc. -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <stdint.h> diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index e077c9de3b..1c5778abed 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1,10 +1,11 @@ // Copyright (c) 2011-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "util.h" -#include "core.h" +#include "clientversion.h" +#include "primitives/transaction.h" #include "random.h" #include "sync.h" #include "utilstrencodings.h" @@ -171,7 +172,7 @@ BOOST_AUTO_TEST_CASE(util_FormatMoney) BOOST_AUTO_TEST_CASE(util_ParseMoney) { - int64_t ret = 0; + CAmount ret = 0; BOOST_CHECK(ParseMoney("0.0", ret)); BOOST_CHECK_EQUAL(ret, 0); @@ -339,6 +340,18 @@ BOOST_AUTO_TEST_CASE(test_FormatParagraph) BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 0), "test\ntest"); BOOST_CHECK_EQUAL(FormatParagraph("testerde test ", 4, 0), "testerde\ntest"); BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 4), "test\n test"); + BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string. This is a second sentence in the very long test string."), "This is a very long test string. This is a second sentence in the very long\ntest string."); } +BOOST_AUTO_TEST_CASE(test_FormatSubVersion) +{ + std::vector<std::string> comments; + comments.push_back(std::string("comment1")); + std::vector<std::string> comments2; + comments2.push_back(std::string("comment1")); + comments2.push_back(std::string("comment2")); + 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_AUTO_TEST_SUITE_END() diff --git a/src/test/wallet_tests.cpp b/src/test/wallet_tests.cpp index 3887efbd0d..289cc8c905 100644 --- a/src/test/wallet_tests.cpp +++ b/src/test/wallet_tests.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "wallet.h" @@ -28,7 +28,7 @@ BOOST_AUTO_TEST_SUITE(wallet_tests) static CWallet wallet; static vector<COutput> vCoins; -static void add_coin(int64_t nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0) +static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0) { static int nextLockTime = 0; CMutableTransaction tx; @@ -66,7 +66,7 @@ static bool equal_sets(CoinSet a, CoinSet b) BOOST_AUTO_TEST_CASE(coin_selection_tests) { CoinSet setCoinsRet, setCoinsRet2; - int64_t nValueRet; + CAmount nValueRet; LOCK(wallet.cs_wallet); diff --git a/src/threadsafety.h b/src/threadsafety.h index 7515d050e7..d01c50abb6 100644 --- a/src/threadsafety.h +++ b/src/threadsafety.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-2012 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_THREADSAFETY_H diff --git a/src/timedata.cpp b/src/timedata.cpp index 40cdb33f7a..d04f3d2f78 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "timedata.h" @@ -17,14 +17,13 @@ using namespace std; static CCriticalSection cs_nTimeOffset; static int64_t nTimeOffset = 0; -// -// "Never go to sea with two chronometers; take one or three." -// Our three time sources are: -// - System clock -// - Median of other nodes clocks -// - The user (asking the user to fix the system clock if the first two disagree) -// -// +/** + * "Never go to sea with two chronometers; take one or three." + * Our three time sources are: + * - System clock + * - Median of other nodes clocks + * - The user (asking the user to fix the system clock if the first two disagree) + */ int64_t GetTimeOffset() { LOCK(cs_nTimeOffset); diff --git a/src/timedata.h b/src/timedata.h index 2c20f4efd5..2296baf11b 100644 --- a/src/timedata.h +++ b/src/timedata.h @@ -1,5 +1,5 @@ -// Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_TIMEDATA_H @@ -12,7 +12,8 @@ class CNetAddr; -/** Median filter over a stream of values. +/** + * Median filter over a stream of values. * Returns the median of the last N numbers */ template <typename T> @@ -67,7 +68,7 @@ public: } }; -/* Functions to keep track of adjusted P2P time */ +/** Functions to keep track of adjusted P2P time */ int64_t GetTimeOffset(); int64_t GetAdjustedTime(); void AddTimeData(const CNetAddr& ip, int64_t nTime); diff --git a/src/txdb.cpp b/src/txdb.cpp index 79838b6116..5096ab19a5 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -1,11 +1,10 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "txdb.h" -#include "core.h" #include "pow.h" #include "uint256.h" @@ -33,12 +32,6 @@ bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) const { return db.Read(make_pair('c', txid), coins); } -bool CCoinsViewDB::SetCoins(const uint256 &txid, const CCoins &coins) { - CLevelDBBatch batch; - BatchWriteCoins(batch, txid, coins); - return db.WriteBatch(batch); -} - bool CCoinsViewDB::HaveCoins(const uint256 &txid) const { return db.Exists(make_pair('c', txid)); } @@ -50,47 +43,33 @@ uint256 CCoinsViewDB::GetBestBlock() const { return hashBestChain; } -bool CCoinsViewDB::SetBestBlock(const uint256 &hashBlock) { - CLevelDBBatch batch; - BatchWriteHashBestChain(batch, hashBlock); - return db.WriteBatch(batch); -} - bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { - LogPrint("coindb", "Committing %u changed transactions to coin database...\n", (unsigned int)mapCoins.size()); - CLevelDBBatch batch; + size_t count = 0; + size_t changed = 0; for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) { - BatchWriteCoins(batch, it->first, it->second); + if (it->second.flags & CCoinsCacheEntry::DIRTY) { + BatchWriteCoins(batch, it->first, it->second.coins); + changed++; + } + count++; CCoinsMap::iterator itOld = it++; mapCoins.erase(itOld); } if (hashBlock != uint256(0)) BatchWriteHashBestChain(batch, hashBlock); + LogPrint("coindb", "Committing %u changed transactions (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count); return db.WriteBatch(batch); } CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevelDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) { } -bool CBlockTreeDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) -{ - return Write(make_pair('b', blockindex.GetBlockHash()), blockindex); -} - -bool CBlockTreeDB::WriteBlockFileInfo(int nFile, const CBlockFileInfo &info) { - return Write(make_pair('f', nFile), info); -} - bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) { return Read(make_pair('f', nFile), info); } -bool CBlockTreeDB::WriteLastBlockFile(int nFile) { - return Write('l', nFile); -} - bool CBlockTreeDB::WriteReindexing(bool fReindexing) { if (fReindexing) return Write('R', '1'); @@ -111,13 +90,13 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { /* It seems that there are no "const iterators" for LevelDB. Since we only need read operations on it, use a const-cast to get around that restriction. */ - leveldb::Iterator *pcursor = const_cast<CLevelDBWrapper*>(&db)->NewIterator(); + boost::scoped_ptr<leveldb::Iterator> pcursor(const_cast<CLevelDBWrapper*>(&db)->NewIterator()); pcursor->SeekToFirst(); CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); stats.hashBlock = GetBestBlock(); ss << stats.hashBlock; - int64_t nTotalAmount = 0; + CAmount nTotalAmount = 0; while (pcursor->Valid()) { boost::this_thread::interruption_point(); try { @@ -150,7 +129,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { ss << VARINT(0); } pcursor->Next(); - } catch (std::exception &e) { + } catch (const std::exception& e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); } } @@ -160,6 +139,18 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { return true; } +bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) { + CLevelDBBatch batch; + for (std::vector<std::pair<int, const CBlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) { + batch.Write(make_pair('f', it->first), *it->second); + } + batch.Write('l', nLastFile); + for (std::vector<const CBlockIndex*>::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) { + batch.Write(make_pair('b', (*it)->GetBlockHash()), CDiskBlockIndex(*it)); + } + return WriteBatch(batch, true); +} + bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) { return Read(make_pair('t', txid), pos); } @@ -227,7 +218,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() } else { break; // if shutdown requested or finished loading block index } - } catch (std::exception &e) { + } catch (const std::exception& e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); } } diff --git a/src/txdb.h b/src/txdb.h index f0b6b9e1dd..f6b6b84fcf 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -1,10 +1,10 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_TXDB_LEVELDB_H -#define BITCOIN_TXDB_LEVELDB_H +#ifndef BITCOIN_TXDB_H +#define BITCOIN_TXDB_H #include "leveldbwrapper.h" #include "main.h" @@ -17,11 +17,11 @@ class CCoins; class uint256; -// -dbcache default (MiB) +//! -dbcache default (MiB) static const int64_t nDefaultDbCache = 100; -// max. -dbcache in (MiB) +//! max. -dbcache in (MiB) static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 4096 : 1024; -// min. -dbcache in (MiB) +//! min. -dbcache in (MiB) static const int64_t nMinDbCache = 4; /** CCoinsView backed by the LevelDB coin database (chainstate/) */ @@ -33,10 +33,8 @@ public: CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); bool GetCoins(const uint256 &txid, CCoins &coins) const; - bool SetCoins(const uint256 &txid, const CCoins &coins); bool HaveCoins(const uint256 &txid) const; uint256 GetBestBlock() const; - bool SetBestBlock(const uint256 &hashBlock); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); bool GetStats(CCoinsStats &stats) const; }; @@ -50,11 +48,9 @@ private: CBlockTreeDB(const CBlockTreeDB&); void operator=(const CBlockTreeDB&); public: - bool WriteBlockIndex(const CDiskBlockIndex& blockindex); + bool WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo); bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo); - bool WriteBlockFileInfo(int nFile, const CBlockFileInfo &fileinfo); bool ReadLastBlockFile(int &nFile); - bool WriteLastBlockFile(int nFile); bool WriteReindexing(bool fReindex); bool ReadReindexing(bool &fReindex); bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos); @@ -64,4 +60,4 @@ public: bool LoadBlockIndexGuts(); }; -#endif // BITCOIN_TXDB_LEVELDB_H +#endif // BITCOIN_TXDB_H diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 52d07bf6a0..01bf1ec080 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1,12 +1,16 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "txmempool.h" -#include "core.h" +#include "clientversion.h" +#include "main.h" +#include "streams.h" #include "util.h" +#include "utilmoneystr.h" +#include "version.h" #include <boost/circular_buffer.hpp> @@ -18,7 +22,7 @@ CTxMemPoolEntry::CTxMemPoolEntry(): nHeight = MEMPOOL_HEIGHT; } -CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, int64_t _nFee, +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) @@ -36,15 +40,15 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other) double CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const { - int64_t nValueIn = tx.GetValueOut()+nFee; + CAmount nValueIn = tx.GetValueOut()+nFee; double deltaPriority = ((double)(currentHeight-nHeight)*nValueIn)/nModSize; double dResult = dPriority + deltaPriority; return dResult; } -// -// Keep track of fee/priority for transactions confirmed within N blocks -// +/** + * Keep track of fee/priority for transactions confirmed within N blocks + */ class CBlockAverage { private: @@ -83,24 +87,36 @@ public: return prioritySamples.size(); } - // Used as belt-and-suspenders check when reading to detect - // file corruption - bool AreSane(const std::vector<CFeeRate>& vecFee, const CFeeRate& minRelayFee) + /** + * 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) + return false; + return true; + } + static bool AreSane(const std::vector<CFeeRate>& vecFee, const CFeeRate& minRelayFee) { BOOST_FOREACH(CFeeRate fee, vecFee) { - if (fee < CFeeRate(0)) - return false; - if (fee.GetFeePerK() > minRelayFee.GetFeePerK() * 10000) + if (!AreSane(fee, minRelayFee)) return false; } return true; } - bool AreSane(const std::vector<double> vecPriority) + static bool AreSane(const double priority) + { + return priority >= 0; + } + static bool AreSane(const std::vector<double> vecPriority) { BOOST_FOREACH(double priority, vecPriority) { - if (priority < 0) + if (!AreSane(priority)) return false; } return true; @@ -136,16 +152,20 @@ public: class CMinerPolicyEstimator { private: - // Records observed averages transactions that confirmed within one block, two blocks, - // three blocks etc. + /** + * 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. + /** + * 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". @@ -157,12 +177,12 @@ private: bool sufficientFee = (feeRate > minRelayFee); bool sufficientPriority = AllowFree(dPriority); const char* assignedTo = "unassigned"; - if (sufficientFee && !sufficientPriority) + if (sufficientFee && !sufficientPriority && CBlockAverage::AreSane(feeRate, minRelayFee)) { history[nBlocksTruncated].RecordFee(feeRate); assignedTo = "fee"; } - else if (sufficientPriority && !sufficientFee) + else if (sufficientPriority && !sufficientFee && CBlockAverage::AreSane(dPriority)) { history[nBlocksTruncated].RecordPriority(dPriority); assignedTo = "priority"; @@ -231,8 +251,8 @@ public: } } - //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 + // 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(); @@ -245,7 +265,9 @@ public: } } - // Can return CFeeRate(0) if we don't have any data for that many blocks back. nBlocksToConfirm is 1 based. + /** + * 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--; @@ -329,7 +351,7 @@ public: size_t numEntries; filein >> numEntries; if (numEntries <= 0 || numEntries > 10000) - throw runtime_error("Corrupt estimates file. Must have between 1 and 10k entires."); + throw runtime_error("Corrupt estimates file. Must have between 1 and 10k entries."); std::vector<CBlockAverage> fileHistory; @@ -340,8 +362,8 @@ public: fileHistory.push_back(entry); } - //Now that we've processed the entire fee estimate data file and not - //thrown any errors, we can copy it to our history + // 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); @@ -415,26 +437,32 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry) } -void CTxMemPool::remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive) +void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& removed, bool fRecursive) { // Remove transaction from memory pool { LOCK(cs); - uint256 hash = tx.GetHash(); - 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; - remove(*it->second.ptx, removed, true); - } - } - if (mapTx.count(hash)) + std::deque<uint256> txToRemove; + txToRemove.push_back(origTx.GetHash()); + while (!txToRemove.empty()) { - removed.push_front(tx); + 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()); + } + } BOOST_FOREACH(const CTxIn& txin, tx.vin) mapNextTx.erase(txin.prevout); + removed.push_back(tx); totalTxSize -= mapTx[hash].GetTxSize(); mapTx.erase(hash); nTransactionsUpdated++; @@ -442,6 +470,31 @@ void CTxMemPool::remove(const CTransaction &tx, std::list<CTransaction>& removed } } +void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight) +{ + // 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(); + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + std::map<uint256, CTxMemPoolEntry>::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)) { + transactionsToRemove.push_back(tx); + break; + } + } + } + BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) { + list<CTransaction> removed; + remove(tx, removed, true); + } +} + void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed) { // Remove transactions which depend on inputs of tx, recursively @@ -459,7 +512,9 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction> } } -// Called when a block is connected. Removes from mempool and updates the miner fee estimator. +/** + * 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) { @@ -500,17 +555,22 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const uint64_t checkTotal = 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++) { unsigned int i = 0; checkTotal += it->second.GetTxSize(); const CTransaction& tx = it->second.GetTx(); + bool fDependsWait = false; 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); if (it2 != mapTx.end()) { const CTransaction& tx2 = it2->second.GetTx(); assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull()); + fDependsWait = true; } else { const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash); assert(coins && coins->IsAvailable(txin.prevout.n)); @@ -522,6 +582,28 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const assert(it3->second.n == i); i++; } + if (fDependsWait) + waitingOnDependants.push_back(&it->second); + else { + CValidationState state; + assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL)); + UpdateCoins(tx, state, mempoolDuplicate, 1000000); + } + } + unsigned int stepsSinceLastRemove = 0; + while (!waitingOnDependants.empty()) { + const CTxMemPoolEntry* entry = waitingOnDependants.front(); + waitingOnDependants.pop_front(); + CValidationState state; + if (!mempoolDuplicate.HaveInputs(entry->GetTx())) { + waitingOnDependants.push_back(entry); + stepsSinceLastRemove++; + assert(stepsSinceLastRemove < waitingOnDependants.size()); + } else { + assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, NULL)); + UpdateCoins(entry->GetTx(), state, mempoolDuplicate, 1000000); + stepsSinceLastRemove = 0; + } } for (std::map<COutPoint, CInPoint>::const_iterator it = mapNextTx.begin(); it != mapNextTx.end(); it++) { uint256 hash = it->second.ptx->GetHash(); @@ -575,7 +657,7 @@ CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const fileout << CLIENT_VERSION; // version that wrote the file minerPolicyEstimator->Write(fileout); } - catch (const std::exception &) { + catch (const std::exception&) { LogPrintf("CTxMemPool::WriteFeeEstimates() : unable to write policy estimator data (non-fatal)"); return false; } @@ -594,31 +676,31 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein) LOCK(cs); minerPolicyEstimator->Read(filein, minRelayFee); } - catch (const std::exception &) { + catch (const std::exception&) { LogPrintf("CTxMemPool::ReadFeeEstimates() : unable to read policy estimator data (non-fatal)"); return false; } return true; } -void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, double dPriorityDelta, int64_t nFeeDelta) +void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, double dPriorityDelta, const CAmount& nFeeDelta) { { LOCK(cs); - std::pair<double, int64_t> &deltas = mapDeltas[hash]; + std::pair<double, CAmount> &deltas = mapDeltas[hash]; deltas.first += dPriorityDelta; deltas.second += nFeeDelta; } - LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, nFeeDelta); + LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta)); } -void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, int64_t &nFeeDelta) +void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta) { LOCK(cs); - std::map<uint256, std::pair<double, int64_t> >::iterator pos = mapDeltas.find(hash); + std::map<uint256, std::pair<double, CAmount> >::iterator pos = mapDeltas.find(hash); if (pos == mapDeltas.end()) return; - const std::pair<double, int64_t> &deltas = pos->second; + const std::pair<double, CAmount> &deltas = pos->second; dPriorityDelta += deltas.first; nFeeDelta += deltas.second; } @@ -630,7 +712,7 @@ void CTxMemPool::ClearPrioritisation(const uint256 hash) } -CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } +CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { } bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const { // If an entry in the mempool exists, always return that one, as it's guaranteed to never diff --git a/src/txmempool.h b/src/txmempool.h index b9d50ee0bc..0732af67e6 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_TXMEMPOOL_H @@ -8,43 +8,51 @@ #include <list> +#include "amount.h" #include "coins.h" -#include "core.h" +#include "primitives/transaction.h" #include "sync.h" +class CAutoFile; + +inline double AllowFreeThreshold() +{ + return COIN * 144 / 250; +} + inline bool AllowFree(double dPriority) { // Large (in bytes) low-priority (new, small-coin) transactions // need a fee. - return dPriority > COIN * 144 / 250; + return dPriority > AllowFreeThreshold(); } /** 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 CTxMemPoolEntry { private: CTransaction tx; - int64_t nFee; // Cached to avoid expensive parent-transaction lookups - size_t nTxSize; // ... and avoid recomputing tx size - size_t nModSize; // ... and modified size for priority - 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 + 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 + 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 public: - CTxMemPoolEntry(const CTransaction& _tx, int64_t _nFee, + CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _dPriority, unsigned int _nHeight); CTxMemPoolEntry(); CTxMemPoolEntry(const CTxMemPoolEntry& other); const CTransaction& GetTx() const { return this->tx; } double GetPriority(unsigned int currentHeight) const; - int64_t GetFee() const { return nFee; } + CAmount GetFee() const { return nFee; } size_t GetTxSize() const { return nTxSize; } int64_t GetTime() const { return nTime; } unsigned int GetHeight() const { return nHeight; } @@ -52,7 +60,20 @@ public: class CMinerPolicyEstimator; -/* +/** An inpoint - a combination of a transaction and an index n into its vin */ +class CInPoint +{ +public: + const CTransaction* ptx; + uint32_t n; + + CInPoint() { SetNull(); } + CInPoint(const CTransaction* ptxIn, uint32_t nIn) { ptx = ptxIn; n = nIn; } + void SetNull() { ptx = NULL; n = (uint32_t) -1; } + bool IsNull() const { return (ptx == NULL && n == (uint32_t) -1); } +}; + +/** * CTxMemPool stores valid-according-to-the-current-best-chain * transactions that may be included in the next block. * @@ -65,23 +86,23 @@ class CMinerPolicyEstimator; class CTxMemPool { private: - bool fSanityCheck; // Normally false, true if -checkmempool or -regtest + bool fSanityCheck; //! Normally false, true if -checkmempool or -regtest unsigned int nTransactionsUpdated; CMinerPolicyEstimator* minerPolicyEstimator; - CFeeRate minRelayFee; // Passed to constructor to avoid dependency on main - uint64_t totalTxSize; // sum of all mempool tx' byte sizes + CFeeRate minRelayFee; //! Passed to constructor to avoid dependency on main + uint64_t totalTxSize; //! sum of all mempool tx' byte sizes public: mutable CCriticalSection cs; std::map<uint256, CTxMemPoolEntry> mapTx; std::map<COutPoint, CInPoint> mapNextTx; - std::map<uint256, std::pair<double, int64_t> > mapDeltas; + std::map<uint256, std::pair<double, CAmount> > mapDeltas; CTxMemPool(const CFeeRate& _minRelayFee); ~CTxMemPool(); - /* + /** * If sanity-checking is turned on, check makes sure the pool is * consistent (does not contain two transactions that spend the same inputs, * all inputs are in the mapNextTx array). If sanity-checking is turned off, @@ -92,6 +113,7 @@ public: bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry); 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); @@ -102,8 +124,8 @@ public: void AddTransactionsUpdated(unsigned int n); /** Affect CreateNewBlock prioritisation of transactions */ - void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, int64_t nFeeDelta); - void ApplyDeltas(const uint256 hash, double &dPriorityDelta, int64_t &nFeeDelta); + 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); unsigned long size() @@ -125,26 +147,28 @@ public: bool lookup(uint256 hash, CTransaction& result) const; - // Estimate fee rate needed to get into the next - // nBlocks + /** Estimate fee rate needed to get into the next nBlocks */ CFeeRate estimateFee(int nBlocks) const; - // Estimate priority needed to get into the next - // nBlocks + + /** Estimate priority needed to get into the next nBlocks */ double estimatePriority(int nBlocks) const; - // Write/Read estimates to disk + + /** Write/Read estimates to disk */ bool WriteFeeEstimates(CAutoFile& fileout) const; bool ReadFeeEstimates(CAutoFile& filein); }; -/** CCoinsView that brings transactions from a memorypool into view. - It does not check for spendings by memory pool transactions. */ +/** + * CCoinsView that brings transactions from a memorypool into view. + * It does not check for spendings by memory pool transactions. + */ class CCoinsViewMemPool : public CCoinsViewBacked { protected: CTxMemPool &mempool; public: - CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn); + CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn); bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; }; diff --git a/src/ui_interface.h b/src/ui_interface.h index f5224ba57d..3f11a1ddab 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_UI_INTERFACE_H @@ -63,6 +63,9 @@ public: /** Force blocking, modal message box dialog (not just OS notification) */ MODAL = 0x10000000U, + /** Do not print contents of message to debug log */ + SECURE = 0x40000000U, + /** Predefined combinations for certain default usage cases */ MSG_INFORMATION = ICON_INFORMATION, MSG_WARNING = (ICON_WARNING | BTN_OK | MODAL), diff --git a/src/uint256.cpp b/src/uint256.cpp index 79406f2475..918c1a7cd7 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "uint256.h" @@ -99,7 +99,7 @@ base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b) if (div_bits > num_bits) // the result is certainly 0. return *this; int shift = num_bits - div_bits; - div <<= shift; // shift so that div and nun align. + div <<= shift; // shift so that div and num align. while (shift >= 0) { if (num >= div) { num -= div; diff --git a/src/uint256.h b/src/uint256.h index 28de540226..139270ac49 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_UINT256_H @@ -255,8 +255,10 @@ public: return sizeof(pn); } - // Returns the position of the highest bit set plus one, or zero if the - // value is zero. + /** + * Returns the position of the highest bit set plus one, or zero if the + * value is zero. + */ unsigned int bits() const; uint64_t GetLow64() const @@ -301,26 +303,27 @@ public: uint256(uint64_t b) : base_uint<256>(b) {} explicit uint256(const std::string& str) : base_uint<256>(str) {} explicit uint256(const std::vector<unsigned char>& vch) : base_uint<256>(vch) {} - - // The "compact" format is a representation of a whole - // number N using an unsigned 32bit number similar to a - // floating point format. - // The most significant 8 bits are the unsigned exponent of base 256. - // This exponent can be thought of as "number of bytes of N". - // The lower 23 bits are the mantissa. - // Bit number 24 (0x800000) represents the sign of N. - // N = (-1^sign) * mantissa * 256^(exponent-3) - // - // Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn(). - // MPI uses the most significant bit of the first byte as sign. - // Thus 0x1234560000 is compact (0x05123456) - // and 0xc0de000000 is compact (0x0600c0de) - // (0x05c0de00) would be -0x40de000000 - // - // Bitcoin only uses this "compact" format for encoding difficulty - // targets, which are unsigned 256bit quantities. Thus, all the - // complexities of the sign bit and using base 256 are probably an - // implementation accident. + + /** + * The "compact" format is a representation of a whole + * number N using an unsigned 32bit number similar to a + * floating point format. + * The most significant 8 bits are the unsigned exponent of base 256. + * This exponent can be thought of as "number of bytes of N". + * The lower 23 bits are the mantissa. + * Bit number 24 (0x800000) represents the sign of N. + * N = (-1^sign) * mantissa * 256^(exponent-3) + * + * Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn(). + * MPI uses the most significant bit of the first byte as sign. + * Thus 0x1234560000 is compact (0x05123456) + * and 0xc0de000000 is compact (0x0600c0de) + * + * Bitcoin only uses this "compact" format for encoding difficulty + * targets, which are unsigned 256bit quantities. Thus, all the + * complexities of the sign bit and using base 256 are probably an + * implementation accident. + */ uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL); uint32_t GetCompact(bool fNegative = false) const; diff --git a/src/undo.h b/src/undo.h new file mode 100644 index 0000000000..1c4ed95bf2 --- /dev/null +++ b/src/undo.h @@ -0,0 +1,85 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-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_UNDO_H +#define BITCOIN_UNDO_H + +#include "compressor.h" +#include "primitives/transaction.h" +#include "serialize.h" + +/** Undo information for a CTxIn + * + * Contains the prevout's CTxOut being spent, and if this was the + * last output of the affected transaction, its metadata as well + * (coinbase or not, height, transaction version) + */ +class CTxInUndo +{ +public: + CTxOut txout; // the txout data before being spent + bool fCoinBase; // if the outpoint was the last unspent: whether it belonged to a coinbase + unsigned int nHeight; // if the outpoint was the last unspent: its height + int nVersion; // if the outpoint was the last unspent: its version + + CTxInUndo() : txout(), fCoinBase(false), nHeight(0), nVersion(0) {} + CTxInUndo(const CTxOut &txoutIn, bool fCoinBaseIn = false, unsigned int nHeightIn = 0, int nVersionIn = 0) : txout(txoutIn), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), nVersion(nVersionIn) { } + + unsigned int GetSerializeSize(int nType, int nVersion) const { + return ::GetSerializeSize(VARINT(nHeight*2+(fCoinBase ? 1 : 0)), nType, nVersion) + + (nHeight > 0 ? ::GetSerializeSize(VARINT(this->nVersion), nType, nVersion) : 0) + + ::GetSerializeSize(CTxOutCompressor(REF(txout)), nType, nVersion); + } + + template<typename Stream> + void Serialize(Stream &s, int nType, int nVersion) const { + ::Serialize(s, VARINT(nHeight*2+(fCoinBase ? 1 : 0)), nType, nVersion); + if (nHeight > 0) + ::Serialize(s, VARINT(this->nVersion), nType, nVersion); + ::Serialize(s, CTxOutCompressor(REF(txout)), nType, nVersion); + } + + template<typename Stream> + void Unserialize(Stream &s, int nType, int nVersion) { + unsigned int nCode = 0; + ::Unserialize(s, VARINT(nCode), nType, nVersion); + nHeight = nCode / 2; + fCoinBase = nCode & 1; + if (nHeight > 0) + ::Unserialize(s, VARINT(this->nVersion), nType, nVersion); + ::Unserialize(s, REF(CTxOutCompressor(REF(txout))), nType, nVersion); + } +}; + +/** Undo information for a CTransaction */ +class CTxUndo +{ +public: + // undo information for all txins + std::vector<CTxInUndo> vprevout; + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(vprevout); + } +}; + +/** Undo information for a CBlock */ +class CBlockUndo +{ +public: + std::vector<CTxUndo> vtxundo; // for all but the coinbase + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(vtxundo); + } +}; + +#endif // BITCOIN_UNDO_H diff --git a/src/univalue/gen.cpp b/src/univalue/gen.cpp index 881948f46e..abebe88634 100644 --- a/src/univalue/gen.cpp +++ b/src/univalue/gen.cpp @@ -1,5 +1,5 @@ // Copyright 2014 BitPay Inc. -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // @@ -35,8 +35,8 @@ static void initJsonEscape() static void outputEscape() { printf( "// Automatically generated file. Do not modify.\n" - "#ifndef __UNIVALUE_ESCAPES_H__\n" - "#define __UNIVALUE_ESCAPES_H__\n" + "#ifndef BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H\n" + "#define BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H\n" "static const char *escapes[256] = {\n"); for (unsigned int i = 0; i < 256; i++) { @@ -66,7 +66,7 @@ static void outputEscape() } printf( "};\n" - "#endif // __UNIVALUE_ESCAPES_H__\n"); + "#endif // BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H\n"); } int main (int argc, char *argv[]) diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp index b0171e48c4..4e445a542a 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/univalue.cpp @@ -1,5 +1,5 @@ // Copyright 2014 BitPay Inc. -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <stdint.h> diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index 0a7bf3cceb..88d73b8c64 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -1,9 +1,9 @@ // Copyright 2014 BitPay Inc. -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef __UNIVALUE_H__ -#define __UNIVALUE_H__ +#ifndef BITCOIN_UNIVALUE_UNIVALUE_H +#define BITCOIN_UNIVALUE_UNIVALUE_H #include <stdint.h> #include <string> @@ -152,4 +152,4 @@ extern enum jtokentype getJsonToken(std::string& tokenVal, unsigned int& consumed, const char *raw); extern const char *uvTypeName(UniValue::VType t); -#endif // __UNIVALUE_H__ +#endif // BITCOIN_UNIVALUE_UNIVALUE_H diff --git a/src/univalue/univalue_escapes.h b/src/univalue/univalue_escapes.h index 1d3a70a968..0514118285 100644 --- a/src/univalue/univalue_escapes.h +++ b/src/univalue/univalue_escapes.h @@ -1,6 +1,6 @@ // Automatically generated file. Do not modify. -#ifndef __UNIVALUE_ESCAPES_H__ -#define __UNIVALUE_ESCAPES_H__ +#ifndef BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H +#define BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H static const char *escapes[256] = { NULL, NULL, @@ -259,4 +259,4 @@ static const char *escapes[256] = { NULL, NULL, }; -#endif // __UNIVALUE_ESCAPES_H__ +#endif // BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H diff --git a/src/univalue/univalue_read.cpp b/src/univalue/univalue_read.cpp index 405be3e81f..5cea778996 100644 --- a/src/univalue/univalue_read.cpp +++ b/src/univalue/univalue_read.cpp @@ -1,5 +1,5 @@ // Copyright 2014 BitPay Inc. -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <string.h> diff --git a/src/univalue/univalue_write.cpp b/src/univalue/univalue_write.cpp index 9565cfa11a..9a1d364c95 100644 --- a/src/univalue/univalue_write.cpp +++ b/src/univalue/univalue_write.cpp @@ -1,5 +1,5 @@ // Copyright 2014 BitPay Inc. -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <ctype.h> diff --git a/src/util.cpp b/src/util.cpp index f387fce8c7..0d0f7e5f91 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #if defined(HAVE_CONFIG_H) @@ -105,7 +105,7 @@ bool fLogTimestamps = false; bool fLogIPs = false; volatile bool fReopenDebugLog = false; -// Init OpenSSL library multithreading support +/** Init OpenSSL library multithreading support */ static CCriticalSection** ppmutexOpenSSL; void locking_callback(int mode, int i, const char* file, int line) { @@ -149,18 +149,22 @@ public: } instance_of_cinit; -// LogPrintf() has been broken a couple of times now -// by well-meaning people adding mutexes in the most straightforward way. -// It breaks because it may be called by global destructors during shutdown. -// Since the order of destruction of static/global objects is undefined, -// defining a mutex as a global object doesn't work (the mutex gets -// destroyed, and then some later destructor calls OutputDebugStringF, -// maybe indirectly, and you get a core dump at shutdown trying to lock -// the mutex). +/** + * LogPrintf() has been broken a couple of times now + * by well-meaning people adding mutexes in the most straightforward way. + * It breaks because it may be called by global destructors during shutdown. + * Since the order of destruction of static/global objects is undefined, + * defining a mutex as a global object doesn't work (the mutex gets + * destroyed, and then some later destructor calls OutputDebugStringF, + * maybe indirectly, and you get a core dump at shutdown trying to lock + * the mutex). + */ static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT; -// We use boost::call_once() to make sure these are initialized in -// in a thread-safe manner the first time it is called: +/** + * We use boost::call_once() to make sure these are initialized + * in a thread-safe manner the first time called: + */ static FILE* fileout = NULL; static boost::mutex* mutexDebugLog = NULL; @@ -342,7 +346,7 @@ bool SoftSetBoolArg(const std::string& strArg, bool fValue) return SoftSetArg(strArg, std::string("0")); } -static std::string FormatException(std::exception* pex, const char* pszThread) +static std::string FormatException(const std::exception* pex, const char* pszThread) { #ifdef WIN32 char pszModule[MAX_PATH] = ""; @@ -358,7 +362,7 @@ static std::string FormatException(std::exception* pex, const char* pszThread) "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); } -void PrintExceptionContinue(std::exception* pex, const char* pszThread) +void PrintExceptionContinue(const std::exception* pex, const char* pszThread) { std::string message = FormatException(pex, pszThread); LogPrintf("\n\n************************\n%s\n", message); @@ -395,7 +399,8 @@ boost::filesystem::path GetDefaultDataDir() #endif } -static boost::filesystem::path pathCached[CBaseChainParams::MAX_NETWORK_TYPES+1]; +static boost::filesystem::path pathCached; +static boost::filesystem::path pathCachedNetSpecific; static CCriticalSection csPathCached; const boost::filesystem::path &GetDataDir(bool fNetSpecific) @@ -404,10 +409,7 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific) LOCK(csPathCached); - int nNet = CBaseChainParams::MAX_NETWORK_TYPES; - if (fNetSpecific) nNet = BaseParams().NetworkID(); - - fs::path &path = pathCached[nNet]; + fs::path &path = fNetSpecific ? pathCachedNetSpecific : pathCached; // This can be called during exceptions by LogPrintf(), so we cache the // value so we don't have to do memory allocations after that. @@ -433,8 +435,8 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific) void ClearDatadirCache() { - std::fill(&pathCached[0], &pathCached[CBaseChainParams::MAX_NETWORK_TYPES+1], - boost::filesystem::path()); + pathCached = boost::filesystem::path(); + pathCachedNetSpecific = boost::filesystem::path(); } boost::filesystem::path GetConfigFile() @@ -502,15 +504,17 @@ bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest) #endif /* WIN32 */ } -// Ignores exceptions thrown by Boost's create_directory if the requested directory exists. -// Specifically handles case where path p exists, but it wasn't possible for the user to -// write to the parent directory. +/** + * Ignores exceptions thrown by Boost's create_directory if the requested directory exists. + * Specifically handles case where path p exists, but it wasn't possible for the user to + * write to the parent directory. + */ bool TryCreateDirectory(const boost::filesystem::path& p) { try { return boost::filesystem::create_directory(p); - } catch (boost::filesystem::filesystem_error) { + } catch (const boost::filesystem::filesystem_error&) { if (!boost::filesystem::exists(p) || !boost::filesystem::is_directory(p)) throw; } @@ -544,8 +548,10 @@ bool TruncateFile(FILE *file, unsigned int length) { #endif } -// this function tries to raise the file descriptor limit to the requested number. -// It returns the actual file descriptor limit (which may be more or less than nMinFD) +/** + * this function tries to raise the file descriptor limit to the requested number. + * It returns the actual file descriptor limit (which may be more or less than nMinFD) + */ int RaiseFileDescriptorLimit(int nMinFD) { #if defined(WIN32) return 2048; @@ -565,8 +571,10 @@ int RaiseFileDescriptorLimit(int nMinFD) { #endif } -// this function tries to make a particular range of a file allocated (corresponding to disk space) -// it is advisory, and the range specified in the arguments will never contain live data +/** + * this function tries to make a particular range of a file allocated (corresponding to disk space) + * it is advisory, and the range specified in the arguments will never contain live data + */ void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length) { #if defined(WIN32) // Windows-specific version @@ -618,7 +626,7 @@ void ShrinkDebugFile() { // Restart the file with some of the end std::vector <char> vch(200000,0); - fseek(file, -vch.size(), SEEK_END); + fseek(file, -((long)vch.size()), SEEK_END); int nBytes = fread(begin_ptr(vch), 1, vch.size(), file); fclose(file); @@ -713,8 +721,7 @@ void SetupEnvironment() #else // boost filesystem v2 std::locale(); // Raises runtime error if current locale is invalid #endif - } catch(std::runtime_error &e) - { + } catch (const std::runtime_error&) { setenv("LC_ALL", "C", 1); // Force C locale } #endif diff --git a/src/util.h b/src/util.h index 4b2415278b..bbb0e81039 100644 --- a/src/util.h +++ b/src/util.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. /** @@ -40,25 +40,26 @@ extern volatile bool fReopenDebugLog; void SetupEnvironment(); -/* Return true if log accepts specified category */ +/** Return true if log accepts specified category */ bool LogAcceptCategory(const char* category); -/* Send a string to the log output */ +/** Send a string to the log output */ int LogPrintStr(const std::string &str); #define LogPrintf(...) LogPrint(NULL, __VA_ARGS__) -/* When we switch to C++11, this can be switched to variadic templates instead +/** + * When we switch to C++11, this can be switched to variadic templates instead * of this macro-based construction (see tinyformat.h). */ #define MAKE_ERROR_AND_LOG_FUNC(n) \ - /* Print to debug.log if -debug=category switch is given OR category is NULL. */ \ + /** Print to debug.log if -debug=category switch is given OR category is NULL. */ \ template<TINYFORMAT_ARGTYPES(n)> \ static inline int LogPrint(const char* category, const char* format, TINYFORMAT_VARARGS(n)) \ { \ if(!LogAcceptCategory(category)) return 0; \ return LogPrintStr(tfm::format(format, TINYFORMAT_PASSARGS(n))); \ } \ - /* Log error and return false */ \ + /** Log error and return false */ \ template<TINYFORMAT_ARGTYPES(n)> \ static inline bool error(const char* format, TINYFORMAT_VARARGS(n)) \ { \ @@ -68,7 +69,8 @@ int LogPrintStr(const std::string &str); TINYFORMAT_FOREACH_ARGNUM(MAKE_ERROR_AND_LOG_FUNC) -/* Zero-arg versions of logging and error, these are not covered by +/** + * Zero-arg versions of logging and error, these are not covered by * TINYFORMAT_FOREACH_ARGNUM */ static inline int LogPrint(const char* category, const char* format) @@ -82,7 +84,7 @@ static inline bool error(const char* format) return false; } -void PrintExceptionContinue(std::exception* pex, const char* pszThread); +void PrintExceptionContinue(const std::exception *pex, const char* pszThread); void ParseParameters(int argc, const char*const argv[]); void FileCommit(FILE *fileout); bool TruncateFile(FILE *file, unsigned int length); @@ -162,13 +164,15 @@ bool SoftSetBoolArg(const std::string& strArg, bool fValue); 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)); +/** + * 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)); + */ template <typename Callable> void LoopForever(const char* name, Callable func, int64_t msecs) { std::string s = strprintf("bitcoin-%s", name); @@ -182,12 +186,12 @@ template <typename Callable> void LoopForever(const char* name, Callable func, func(); } } - catch (boost::thread_interrupted) + catch (const boost::thread_interrupted&) { LogPrintf("%s thread stop\n", name); throw; } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, name); throw; } @@ -196,7 +200,10 @@ template <typename Callable> void LoopForever(const char* name, Callable func, throw; } } -// .. and a wrapper that just calls func once + +/** + * .. and a wrapper that just calls func once + */ template <typename Callable> void TraceThread(const char* name, Callable func) { std::string s = strprintf("bitcoin-%s", name); @@ -207,12 +214,12 @@ template <typename Callable> void TraceThread(const char* name, Callable func) func(); LogPrintf("%s thread exit\n", name); } - catch (boost::thread_interrupted) + catch (const boost::thread_interrupted&) { LogPrintf("%s thread interrupt\n", name); throw; } - catch (std::exception& e) { + catch (const std::exception& e) { PrintExceptionContinue(&e, name); throw; } diff --git a/src/utilmoneystr.cpp b/src/utilmoneystr.cpp index c169355f05..2fbc048878 100644 --- a/src/utilmoneystr.cpp +++ b/src/utilmoneystr.cpp @@ -1,16 +1,17 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "utilmoneystr.h" -#include "core.h" +#include "primitives/transaction.h" #include "tinyformat.h" +#include "utilstrencodings.h" using namespace std; -string FormatMoney(int64_t n, bool fPlus) +string FormatMoney(const CAmount& n, bool fPlus) { // Note: not using straight sprintf here because we do NOT want // localized number formatting. @@ -34,12 +35,12 @@ string FormatMoney(int64_t n, bool fPlus) } -bool ParseMoney(const string& str, int64_t& nRet) +bool ParseMoney(const string& str, CAmount& nRet) { return ParseMoney(str.c_str(), nRet); } -bool ParseMoney(const char* pszIn, int64_t& nRet) +bool ParseMoney(const char* pszIn, CAmount& nRet) { string strWhole; int64_t nUnits = 0; @@ -73,7 +74,7 @@ bool ParseMoney(const char* pszIn, int64_t& nRet) if (nUnits < 0 || nUnits > COIN) return false; int64_t nWhole = atoi64(strWhole); - int64_t nValue = nWhole*COIN + nUnits; + CAmount nValue = nWhole*COIN + nUnits; nRet = nValue; return true; diff --git a/src/utilmoneystr.h b/src/utilmoneystr.h index f0c61aa138..cd9b04810d 100644 --- a/src/utilmoneystr.h +++ b/src/utilmoneystr.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. /** @@ -12,8 +12,10 @@ #include <stdint.h> #include <string> -std::string FormatMoney(int64_t n, bool fPlus=false); -bool ParseMoney(const std::string& str, int64_t& nRet); -bool ParseMoney(const char* pszIn, int64_t& nRet); +#include "amount.h" + +std::string FormatMoney(const CAmount& n, bool fPlus=false); +bool ParseMoney(const std::string& str, CAmount& nRet); +bool ParseMoney(const char* pszIn, CAmount& nRet); #endif // BITCOIN_UTILMONEYSTR_H diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 2cec3023b5..c15bddc6fb 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -1,24 +1,26 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "utilstrencodings.h" #include "tinyformat.h" +#include <cstdlib> +#include <cstring> #include <errno.h> #include <limits> -#include <boost/foreach.hpp> - using namespace std; -// safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything -// even possibly remotely dangerous like & or > -static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@"); string SanitizeString(const string& str) { + /** + * 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++) { @@ -53,9 +55,9 @@ signed char HexDigit(char c) bool IsHex(const string& str) { - BOOST_FOREACH(char c, str) + for(std::string::const_iterator it(str.begin()); it != str.end(); ++it) { - if (HexDigit(c) < 0) + if (HexDigit(*it) < 0) return false; } return (str.size() > 0) && (str.size()%2 == 0); @@ -457,7 +459,7 @@ std::string FormatParagraph(const std::string in, size_t width, size_t indent) } // Append word out << in.substr(ptr, endword - ptr); - col += endword - ptr; + col += endword - ptr + 1; ptr = endword; } return out.str(); diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index 0b8c1a1781..b0edd8b542 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. /** @@ -19,7 +19,7 @@ #define UEND(a) ((unsigned char*)&((&(a))[1])) #define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) -// This is needed because the foreach macro can't get over the comma in pair<t1, t2> +/** 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); @@ -45,7 +45,7 @@ int atoi(const std::string& str); /** * Convert string to signed 32-bit integer with strict parse error feedback. * @returns true if the entire string could be parsed as valid integer, - * false if not the entire string could be parsed or when overflow or underflow occured. + * false if not the entire string could be parsed or when overflow or underflow occurred. */ bool ParseInt32(const std::string& str, int32_t *out); @@ -74,7 +74,8 @@ 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 +/** + * 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); diff --git a/src/utiltime.cpp b/src/utiltime.cpp index 78f0342cba..8f0dcae29d 100644 --- a/src/utiltime.cpp +++ b/src/utiltime.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #if defined(HAVE_CONFIG_H) @@ -14,7 +14,7 @@ using namespace std; -static int64_t nMockTime = 0; // For unit testing +static int64_t nMockTime = 0; //! For unit testing int64_t GetTime() { @@ -42,9 +42,12 @@ int64_t GetTimeMicros() void MilliSleep(int64_t n) { -// Boost's sleep_for was uninterruptable when backed by nanosleep from 1.50 -// until fixed in 1.52. Use the deprecated sleep method for the broken case. -// See: https://svn.boost.org/trac/boost/ticket/7238 + +/** + * Boost's sleep_for was uninterruptable when backed by nanosleep from 1.50 + * until fixed in 1.52. Use the deprecated sleep method for the broken case. + * See: https://svn.boost.org/trac/boost/ticket/7238 + */ #if defined(HAVE_WORKING_BOOST_SLEEP_FOR) boost::this_thread::sleep_for(boost::chrono::milliseconds(n)); #elif defined(HAVE_WORKING_BOOST_SLEEP) diff --git a/src/utiltime.h b/src/utiltime.h index 6f82e5a836..900992f871 100644 --- a/src/utiltime.h +++ b/src/utiltime.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_UTILTIME_H diff --git a/src/version.h b/src/version.h index 75cbec39b7..38b3d2e734 100644 --- a/src/version.h +++ b/src/version.h @@ -1,56 +1,37 @@ -// Copyright (c) 2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-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_VERSION_H #define BITCOIN_VERSION_H -#include "clientversion.h" - -#include <string> -#include <vector> - -// -// client versioning -// - -static const int CLIENT_VERSION = - 1000000 * CLIENT_VERSION_MAJOR - + 10000 * CLIENT_VERSION_MINOR - + 100 * CLIENT_VERSION_REVISION - + 1 * CLIENT_VERSION_BUILD; - -extern const std::string CLIENT_NAME; -extern const std::string CLIENT_BUILD; -extern const std::string CLIENT_DATE; - -// -// network protocol versioning -// +/** + * network protocol versioning + */ static const int PROTOCOL_VERSION = 70002; -// initial proto version, to be increased after version/verack negotiation +//! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; -// disconnect from peers older than this proto version -static const int MIN_PEER_PROTO_VERSION = 209; +//! In this version, 'getheaders' was introduced. +static const int GETHEADERS_VERSION = 31800; + +//! disconnect from peers older than this proto version +static const int MIN_PEER_PROTO_VERSION = GETHEADERS_VERSION; -// nTime field added to CAddress, starting with this version; -// if possible, avoid requesting addresses nodes older than this +//! nTime field added to CAddress, starting with this version; +//! if possible, avoid requesting addresses nodes older than this static const int CADDR_TIME_VERSION = 31402; -// only request blocks from nodes outside this range of versions +//! only request blocks from nodes outside this range of versions static const int NOBLKS_VERSION_START = 32000; static const int NOBLKS_VERSION_END = 32400; -// BIP 0031, pong message, is enabled for all versions AFTER this one +//! BIP 0031, pong message, is enabled for all versions AFTER this one static const int BIP0031_VERSION = 60000; -// "mempool" command, enhanced "getdata" behavior starts with this version +//! "mempool" command, enhanced "getdata" behavior starts with this version static const int MEMPOOL_GD_VERSION = 60002; -std::string FormatFullVersion(); -std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments); - #endif // BITCOIN_VERSION_H diff --git a/src/wallet.cpp b/src/wallet.cpp index e69f59aacd..8504c0a287 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "wallet.h" @@ -15,28 +15,38 @@ #include "util.h" #include "utilmoneystr.h" +#include <assert.h> + #include <boost/algorithm/string/replace.hpp> #include <boost/thread.hpp> using namespace std; -// Settings +/** + * Settings + */ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); +CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; unsigned int nTxConfirmTarget = 1; bool bSpendZeroConfChange = true; +bool fSendFreeTransactions = false; +bool fPayAtLeastCustomFee = true; -/** Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) */ -CFeeRate CWallet::minTxFee = CFeeRate(10000); // Override with -mintxfee +/** + * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) + * Override with -mintxfee + */ +CFeeRate CWallet::minTxFee = CFeeRate(1000); -////////////////////////////////////////////////////////////////////////////// -// -// mapWallet -// +/** @defgroup mapWallet + * + * @{ + */ struct CompareValueOnly { - bool operator()(const pair<int64_t, pair<const CWalletTx*, unsigned int> >& t1, - const pair<int64_t, pair<const CWalletTx*, unsigned int> >& t2) const + bool operator()(const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t1, + const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t2) const { return t1.first < t2.first; } @@ -70,6 +80,7 @@ CPubKey CWallet::GenerateNewKey() SetMinVersion(FEATURE_COMPRPUBKEY); CPubKey pubkey = secret.GetPubKey(); + assert(secret.VerifyPubKey(pubkey)); // Create new metadata int64_t nCreationTime = GetTime(); @@ -87,6 +98,13 @@ bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey) AssertLockHeld(cs_wallet); // mapKeyMetadata if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey)) return false; + + // check if we need to remove from watch-only + CScript script; + script = GetScriptForDestination(pubkey.GetID()); + if (HaveWatchOnly(script)) + RemoveWatchOnly(script); + if (!fFileBacked) return true; if (!IsCrypted()) { @@ -149,7 +167,7 @@ bool CWallet::LoadCScript(const CScript& redeemScript) * these. Do not add them to the wallet and warn. */ if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE) { - std::string strAddr = CBitcoinAddress(redeemScript.GetID()).ToString(); + std::string strAddr = CBitcoinAddress(CScriptID(redeemScript)).ToString(); LogPrintf("%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n", __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr); return true; @@ -169,6 +187,20 @@ bool CWallet::AddWatchOnly(const CScript &dest) return CWalletDB(strWalletFile).WriteWatchOnly(dest); } +bool CWallet::RemoveWatchOnly(const CScript &dest) +{ + AssertLockHeld(cs_wallet); + if (!CCryptoKeyStore::RemoveWatchOnly(dest)) + return false; + if (!HaveWatchOnly()) + NotifyWatchonlyChanged(false); + if (fFileBacked) + if (!CWalletDB(strWalletFile).EraseWatchOnly(dest)) + return false; + + return true; +} + bool CWallet::LoadWatchOnly(const CScript &dest) { return CCryptoKeyStore::AddWatchOnly(dest); @@ -344,8 +376,10 @@ void CWallet::SyncMetaData(pair<TxSpends::iterator, TxSpends::iterator> range) } } -// Outpoint is spent if any non-conflicted transaction -// spends it: +/** + * Outpoint is spent if any non-conflicted transaction + * spends it: + */ bool CWallet::IsSpent(const uint256& hash, unsigned int n) const { const COutPoint outpoint(hash, n); @@ -392,15 +426,13 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) RandAddSeedPerfmon(); vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE); - if (!GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE)) - return false; + GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); CMasterKey kMasterKey; RandAddSeedPerfmon(); kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE); - if (!GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE)) - return false; + GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); CCrypter crypter; int64_t nStartTime = GetTimeMillis(); @@ -426,17 +458,25 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) mapMasterKeys[++nMasterKeyMaxID] = kMasterKey; if (fFileBacked) { + assert(!pwalletdbEncryption); pwalletdbEncryption = new CWalletDB(strWalletFile); - if (!pwalletdbEncryption->TxnBegin()) + if (!pwalletdbEncryption->TxnBegin()) { + delete pwalletdbEncryption; + pwalletdbEncryption = NULL; return false; + } pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey); } if (!EncryptKeys(vMasterKey)) { - if (fFileBacked) + if (fFileBacked) { pwalletdbEncryption->TxnAbort(); - exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet. + 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. + assert(false); } // Encryption was introduced in version 0.4.0 @@ -444,8 +484,12 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) if (fFileBacked) { - if (!pwalletdbEncryption->TxnCommit()) - exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet. + 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. + assert(false); + } delete pwalletdbEncryption; pwalletdbEncryption = NULL; @@ -632,9 +676,11 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) return true; } -// Add a transaction to the wallet, or update it. -// pblock is optional, but should be provided if the transaction is known to be in a block. -// If fUpdate is true, existing transactions will be updated. +/** + * Add a transaction to the wallet, or update it. + * pblock is optional, but should be provided if the transaction is known to be in a block. + * If fUpdate is true, existing transactions will be updated. + */ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate) { { @@ -697,7 +743,7 @@ isminetype CWallet::IsMine(const CTxIn &txin) const return ISMINE_NO; } -int64_t CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const +CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const { { LOCK(cs_wallet); @@ -781,7 +827,7 @@ int CWalletTx::GetRequestCount() const } void CWalletTx::GetAmounts(list<COutputEntry>& listReceived, - list<COutputEntry>& listSent, int64_t& nFee, string& strSentAccount, const isminefilter& filter) const + list<COutputEntry>& listSent, CAmount& nFee, string& strSentAccount, const isminefilter& filter) const { nFee = 0; listReceived.clear(); @@ -789,10 +835,10 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived, strSentAccount = strFromAccount; // Compute fee: - int64_t nDebit = GetDebit(filter); + CAmount nDebit = GetDebit(filter); if (nDebit > 0) // debit>0 means we signed/sent this transaction { - int64_t nValueOut = GetValueOut(); + CAmount nValueOut = GetValueOut(); nFee = nDebit - nValueOut; } @@ -835,12 +881,12 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived, } -void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nReceived, - int64_t& nSent, int64_t& nFee, const isminefilter& filter) const +void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived, + CAmount& nSent, CAmount& nFee, const isminefilter& filter) const { nReceived = nSent = nFee = 0; - int64_t allFee; + CAmount allFee; string strSentAccount; list<COutputEntry> listReceived; list<COutputEntry> listSent; @@ -876,9 +922,11 @@ bool CWalletTx::WriteToDisk() return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this); } -// Scan the block chain (starting in pindexStart) for transactions -// from or to us. If fUpdate is true, found transactions that already -// exist in the wallet will be updated. +/** + * Scan the block chain (starting in pindexStart) for transactions + * from or to us. If fUpdate is true, found transactions that already + * exist in the wallet will be updated. + */ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) { int ret = 0; @@ -1000,20 +1048,20 @@ void CWallet::ResendWalletTransactions() } } +/** @} */ // end of mapWallet - -////////////////////////////////////////////////////////////////////////////// -// -// Actions -// +/** @defgroup Actions + * + * @{ + */ -int64_t CWallet::GetBalance() const +CAmount CWallet::GetBalance() const { - int64_t nTotal = 0; + CAmount nTotal = 0; { LOCK2(cs_main, cs_wallet); for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) @@ -1027,9 +1075,9 @@ int64_t CWallet::GetBalance() const return nTotal; } -int64_t CWallet::GetUnconfirmedBalance() const +CAmount CWallet::GetUnconfirmedBalance() const { - int64_t nTotal = 0; + CAmount nTotal = 0; { LOCK2(cs_main, cs_wallet); for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) @@ -1042,9 +1090,9 @@ int64_t CWallet::GetUnconfirmedBalance() const return nTotal; } -int64_t CWallet::GetImmatureBalance() const +CAmount CWallet::GetImmatureBalance() const { - int64_t nTotal = 0; + CAmount nTotal = 0; { LOCK2(cs_main, cs_wallet); for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) @@ -1056,9 +1104,9 @@ int64_t CWallet::GetImmatureBalance() const return nTotal; } -int64_t CWallet::GetWatchOnlyBalance() const +CAmount CWallet::GetWatchOnlyBalance() const { - int64_t nTotal = 0; + CAmount nTotal = 0; { LOCK2(cs_main, cs_wallet); for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) @@ -1068,13 +1116,13 @@ int64_t CWallet::GetWatchOnlyBalance() const nTotal += pcoin->GetAvailableWatchOnlyCredit(); } } - + return nTotal; } -int64_t CWallet::GetUnconfirmedWatchOnlyBalance() const +CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const { - int64_t nTotal = 0; + CAmount nTotal = 0; { LOCK2(cs_main, cs_wallet); for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) @@ -1087,9 +1135,9 @@ int64_t CWallet::GetUnconfirmedWatchOnlyBalance() const return nTotal; } -int64_t CWallet::GetImmatureWatchOnlyBalance() const +CAmount CWallet::GetImmatureWatchOnlyBalance() const { - int64_t nTotal = 0; + CAmount nTotal = 0; { LOCK2(cs_main, cs_wallet); for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) @@ -1101,7 +1149,9 @@ int64_t CWallet::GetImmatureWatchOnlyBalance() const return nTotal; } -// populate vCoins with vector of available COutputs. +/** + * populate vCoins with vector of available COutputs. + */ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl) const { vCoins.clear(); @@ -1137,8 +1187,8 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const } } -static void ApproximateBestSubset(vector<pair<int64_t, pair<const CWalletTx*,unsigned int> > >vValue, int64_t nTotalLower, int64_t nTargetValue, - vector<char>& vfBest, int64_t& nBest, int iterations = 1000) +static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > >vValue, const CAmount& nTotalLower, const CAmount& nTargetValue, + vector<char>& vfBest, CAmount& nBest, int iterations = 1000) { vector<char> vfIncluded; @@ -1150,7 +1200,7 @@ static void ApproximateBestSubset(vector<pair<int64_t, pair<const CWalletTx*,uns for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++) { vfIncluded.assign(vValue.size(), false); - int64_t nTotal = 0; + CAmount nTotal = 0; bool fReachedTarget = false; for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++) { @@ -1159,7 +1209,7 @@ static void ApproximateBestSubset(vector<pair<int64_t, pair<const CWalletTx*,uns //The solver here uses a randomized algorithm, //the randomness serves no real security purpose but is just //needed to prevent degenerate behavior and it is important - //that the rng fast. We do not use a constant random sequence, + //that the rng is fast. We do not use a constant random sequence, //because there may be some privacy improvement by making //the selection random. if (nPass == 0 ? insecure_rand()&1 : !vfIncluded[i]) @@ -1183,18 +1233,18 @@ static void ApproximateBestSubset(vector<pair<int64_t, pair<const CWalletTx*,uns } } -bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins, - set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet) const +bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins, + set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const { setCoinsRet.clear(); nValueRet = 0; // List of values less than target - pair<int64_t, pair<const CWalletTx*,unsigned int> > coinLowestLarger; - coinLowestLarger.first = std::numeric_limits<int64_t>::max(); + pair<CAmount, pair<const CWalletTx*,unsigned int> > coinLowestLarger; + coinLowestLarger.first = std::numeric_limits<CAmount>::max(); coinLowestLarger.second.first = NULL; - vector<pair<int64_t, pair<const CWalletTx*,unsigned int> > > vValue; - int64_t nTotalLower = 0; + vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > > vValue; + CAmount nTotalLower = 0; random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt); @@ -1209,9 +1259,9 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfT continue; int i = output.i; - int64_t n = pcoin->vout[i].nValue; + CAmount n = pcoin->vout[i].nValue; - pair<int64_t,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i)); + pair<CAmount,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i)); if (n == nTargetValue) { @@ -1252,7 +1302,7 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfT // Solve subset sum by stochastic approximation sort(vValue.rbegin(), vValue.rend(), CompareValueOnly()); vector<char> vfBest; - int64_t nBest; + CAmount nBest; ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000); if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT) @@ -1284,7 +1334,7 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfT return true; } -bool CWallet::SelectCoins(int64_t nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet, const CCoinControl* coinControl) const +bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl) const { vector<COutput> vCoins; AvailableCoins(vCoins, true, coinControl); @@ -1310,11 +1360,11 @@ bool CWallet::SelectCoins(int64_t nTargetValue, set<pair<const CWalletTx*,unsign -bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, - CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl) +bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend, + CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl) { - int64_t nValue = 0; - BOOST_FOREACH (const PAIRTYPE(CScript, int64_t)& s, vecSend) + CAmount nValue = 0; + BOOST_FOREACH (const PAIRTYPE(CScript, CAmount)& s, vecSend) { if (nValue < 0) { @@ -1333,20 +1383,42 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, wtxNew.BindWallet(this); CMutableTransaction txNew; + // Discourage fee sniping. + // + // However because of a off-by-one-error in previous versions we need to + // neuter it by setting nLockTime to at least one less than nBestHeight. + // Secondly currently propagation of transactions created for block heights + // corresponding to blocks that were just mined may be iffy - transactions + // aren't re-accepted into the mempool - we additionally neuter the code by + // going ten blocks back. Doesn't yet do anything for sniping, but does act + // to shake out wallet bugs like not showing nLockTime'd transactions at + // all. + txNew.nLockTime = std::max(0, chainActive.Height() - 10); + + // Secondly occasionally randomly pick a nLockTime even further back, so + // that transactions that are delayed after signing for whatever reason, + // e.g. high-latency mix networks and some CoinJoin implementations, have + // better privacy. + if (GetRandInt(10) == 0) + txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100)); + + assert(txNew.nLockTime <= (unsigned int)chainActive.Height()); + assert(txNew.nLockTime < LOCKTIME_THRESHOLD); + { LOCK2(cs_main, cs_wallet); { - nFeeRet = payTxFee.GetFeePerK(); + nFeeRet = 0; while (true) { txNew.vin.clear(); txNew.vout.clear(); wtxNew.fFromMe = true; - int64_t nTotalValue = nValue + nFeeRet; + CAmount nTotalValue = nValue + nFeeRet; double dPriority = 0; // vouts to the payees - BOOST_FOREACH (const PAIRTYPE(CScript, int64_t)& s, vecSend) + BOOST_FOREACH (const PAIRTYPE(CScript, CAmount)& s, vecSend) { CTxOut txout(s.second, s.first); if (txout.IsDust(::minRelayTxFee)) @@ -1359,7 +1431,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, // Choose coins to use set<pair<const CWalletTx*,unsigned int> > setCoins; - int64_t nValueIn = 0; + CAmount nValueIn = 0; if (!SelectCoins(nTotalValue, setCoins, nValueIn, coinControl)) { strFailReason = _("Insufficient funds"); @@ -1367,14 +1439,14 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, } BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) { - int64_t nCredit = pcoin.first->vout[pcoin.second].nValue; + CAmount nCredit = pcoin.first->vout[pcoin.second].nValue; //The priority after the next block (depth+1) is used instead of the current, //reflecting an assumption the user would accept a bit more delay for //a chance at a free transaction. dPriority += (double)nCredit * (pcoin.first->GetDepthInMainChain()+1); } - int64_t nChange = nValueIn - nValue - nFeeRet; + CAmount nChange = nValueIn - nValue - nFeeRet; if (nChange > 0) { @@ -1426,8 +1498,12 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, reservekey.ReturnKey(); // Fill vin + // + // Note how the sequence number is set to max()-1 so that the + // nLockTime set above actually works. BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) - txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second)); + txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(), + std::numeric_limits<unsigned int>::max()-1)); // Sign int nIn = 0; @@ -1450,27 +1526,32 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, } dPriority = wtxNew.ComputePriority(dPriority, nBytes); - int64_t nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool); + // Can we complete this as a free transaction? + if (fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE) + { + // Not enough fee: enough priority? + double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget); + // Not enough mempool history to estimate: use hard-coded AllowFree. + if (dPriorityNeeded <= 0 && AllowFree(dPriority)) + break; + + // Small enough, and priority high enough, to send for free + if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded) + break; + } - if (nFeeRet >= nFeeNeeded) - break; // Done, enough fee included. + CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool); - // Too big to send for free? Include more fee and try again: - if (nBytes > MAX_FREE_TRANSACTION_CREATE_SIZE) + // If we made it here and we aren't even able to meet the relay fee on the next pass, give up + // because we must be at the maximum allowed fee. + if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes)) { - nFeeRet = nFeeNeeded; - continue; + strFailReason = _("Transaction too large for fee policy"); + return false; } - // Not enough fee: enough priority? - double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget); - // Not enough mempool history to estimate: use hard-coded AllowFree. - if (dPriorityNeeded <= 0 && AllowFree(dPriority)) - break; - - // Small enough, and priority high enough, to send for free - if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded) - break; + if (nFeeRet >= nFeeNeeded) + break; // Done, enough fee included. // Include more fee and try again. nFeeRet = nFeeNeeded; @@ -1481,15 +1562,17 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, return true; } -bool CWallet::CreateTransaction(CScript scriptPubKey, int64_t nValue, - CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl) +bool CWallet::CreateTransaction(CScript scriptPubKey, const CAmount& nValue, + CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl) { - vector< pair<CScript, int64_t> > vecSend; + vector< pair<CScript, CAmount> > vecSend; vecSend.push_back(make_pair(scriptPubKey, nValue)); return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, strFailReason, coinControl); } -// Call after CreateTransaction unless you want to abort +/** + * Call after CreateTransaction unless you want to abort + */ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) { { @@ -1536,50 +1619,13 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) return true; } - - - -string CWallet::SendMoney(const CTxDestination &address, int64_t nValue, CWalletTx& wtxNew) -{ - // Check amount - if (nValue <= 0) - return _("Invalid amount"); - if (nValue > GetBalance()) - return _("Insufficient funds"); - - string strError; - if (IsLocked()) - { - strError = _("Error: Wallet locked, unable to create transaction!"); - LogPrintf("SendMoney() : %s", strError); - return strError; - } - - // Parse Bitcoin address - CScript scriptPubKey = GetScriptForDestination(address); - - // Create and send the transaction - CReserveKey reservekey(this); - int64_t nFeeRequired; - if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError)) - { - if (nValue + nFeeRequired > GetBalance()) - strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!"), FormatMoney(nFeeRequired)); - LogPrintf("SendMoney() : %s\n", strError); - return strError; - } - if (!CommitTransaction(wtxNew, reservekey)) - return _("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."); - - return ""; -} - - - -int64_t CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool) +CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool) { // payTxFee is user-set "I want to pay this much" - int64_t nFeeNeeded = payTxFee.GetFee(nTxBytes); + CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes); + // user selected total at least (default=true) + if (fPayAtLeastCustomFee && nFeeNeeded > 0 && nFeeNeeded < payTxFee.GetFeePerK()) + nFeeNeeded = payTxFee.GetFeePerK(); // User didn't set: use -txconfirmtarget to estimate... if (nFeeNeeded == 0) nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes); @@ -1587,6 +1633,12 @@ int64_t CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge // back to a hard-coded fee if (nFeeNeeded == 0) nFeeNeeded = minTxFee.GetFee(nTxBytes); + // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee + if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes)) + nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes); + // But always obey the maximum + if (nFeeNeeded > maxTxFee) + nFeeNeeded = maxTxFee; return nFeeNeeded; } @@ -1634,7 +1686,7 @@ DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx) setKeyPool.clear(); // Note: can't top-up keypool here, because wallet is locked. // User will be prompted to unlock wallet the next operation - // the requires a new key. + // that requires a new key. } } @@ -1701,10 +1753,10 @@ bool CWallet::SetDefaultKey(const CPubKey &vchPubKey) return true; } -// -// Mark old keypool keys as used, -// and generate all new keys -// +/** + * Mark old keypool keys as used, + * and generate all new keys + */ bool CWallet::NewKeyPool() { { @@ -1838,9 +1890,9 @@ int64_t CWallet::GetOldestKeyPoolTime() return keypool.nTime; } -std::map<CTxDestination, int64_t> CWallet::GetAddressBalances() +std::map<CTxDestination, CAmount> CWallet::GetAddressBalances() { - map<CTxDestination, int64_t> balances; + map<CTxDestination, CAmount> balances; { LOCK(cs_wallet); @@ -1866,7 +1918,7 @@ std::map<CTxDestination, int64_t> CWallet::GetAddressBalances() if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr)) continue; - int64_t n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue; + CAmount n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue; if (!balances.count(addr)) balances[addr] = 0; @@ -1973,7 +2025,7 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings() set<CTxDestination> CWallet::GetAccountAddresses(string strAccount) const { - AssertLockHeld(cs_wallet); // mapWallet + LOCK(cs_wallet); set<CTxDestination> result; BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook) { @@ -2085,6 +2137,7 @@ void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts) } } +/** @} */ // end of Actions class CAffectedKeysVisitor : public boost::static_visitor<void> { private: @@ -2263,7 +2316,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block) return chainActive.Height() - pindex->nHeight + 1; } -int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const +int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const { if (hashBlock == 0 || nIndex == -1) return 0; @@ -2289,7 +2342,7 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const return chainActive.Height() - pindex->nHeight + 1; } -int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const +int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const { AssertLockHeld(cs_main); int nResult = GetDepthInMainChainINTERNAL(pindexRet); diff --git a/src/wallet.h b/src/wallet.h index fde87a8a2f..4d95d0ae2e 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -1,12 +1,14 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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_WALLET_H #define BITCOIN_WALLET_H -#include "core.h" +#include "amount.h" +#include "primitives/block.h" +#include "primitives/transaction.h" #include "crypter.h" #include "key.h" #include "keystore.h" @@ -24,16 +26,25 @@ #include <utility> #include <vector> -// Settings +/** + * Settings + */ extern CFeeRate payTxFee; +extern CAmount maxTxFee; extern unsigned int nTxConfirmTarget; extern bool bSpendZeroConfChange; - -// -paytxfee default -static const int64_t DEFAULT_TRANSACTION_FEE = 0; -// -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB -static const int nHighTransactionFeeWarning = 0.01 * COIN; -// Largest (in bytes) free transaction we're willing to create +extern bool fSendFreeTransactions; +extern bool fPayAtLeastCustomFee; + +//! -paytxfee default +static const CAmount DEFAULT_TRANSACTION_FEE = 0; +//! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB +static const CAmount nHighTransactionFeeWarning = 0.01 * COIN; +//! -maxtxfee default +static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; +//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis) +static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWarning; +//! Largest (in bytes) free transaction we're willing to create static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; class CAccountingEntry; @@ -92,28 +103,31 @@ public: StringMap destdata; }; -/** A CWallet is an extension of a keystore, which also maintains a set of transactions and balances, +/** + * A CWallet is an extension of a keystore, which also maintains a set of transactions and balances, * and provides the ability to create new transactions. */ -class CWallet : public CCryptoKeyStore, public CWalletInterface +class CWallet : public CCryptoKeyStore, public CValidationInterface { private: - bool SelectCoins(int64_t nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet, const CCoinControl *coinControl = NULL) const; + bool SelectCoins(const CAmount& nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const; CWalletDB *pwalletdbEncryption; - // the current wallet version: clients below this version are not able to load the wallet + //! the current wallet version: clients below this version are not able to load the wallet int nWalletVersion; - // the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded + //! the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded int nWalletMaxVersion; int64_t nNextResend; int64_t nLastResend; - // Used to keep track of spent outpoints, and - // detect and report conflicts (double-spends or - // mutated transactions where the mutant gets mined). + /** + * Used to keep track of spent outpoints, and + * detect and report conflicts (double-spends or + * mutated transactions where the mutant gets mined). + */ typedef std::multimap<COutPoint, uint256> TxSpends; TxSpends mapTxSpends; void AddToSpends(const COutPoint& outpoint, const uint256& wtxid); @@ -122,11 +136,13 @@ private: void SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator>); public: - /// Main wallet lock. - /// This lock protects all the fields added by CWallet - /// except for: - /// fFileBacked (immutable after instantiation) - /// strWalletFile (immutable after instantiation) + /* + * Main wallet lock. + * This lock protects all the fields added by CWallet + * except for: + * fFileBacked (immutable after instantiation) + * strWalletFile (immutable after instantiation) + */ mutable CCriticalSection cs_wallet; bool fFileBacked; @@ -143,6 +159,7 @@ public: { SetNull(); } + CWallet(std::string strWalletFileIn) { SetNull(); @@ -150,6 +167,13 @@ public: strWalletFile = strWalletFileIn; fFileBacked = true; } + + ~CWallet() + { + delete pwalletdbEncryption; + pwalletdbEncryption = NULL; + } + void SetNull() { nWalletVersion = FEATURE_BASE; @@ -178,11 +202,11 @@ public: const CWalletTx* GetWalletTx(const uint256& hash) const; - // check whether we are allowed to upgrade (or already support) to the named feature + //! check whether we are allowed to upgrade (or already support) to the named feature bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; } void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL) const; - bool SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet) const; + bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const; bool IsSpent(const uint256& hash, unsigned int n) const; @@ -192,37 +216,40 @@ public: void UnlockAllCoins(); void ListLockedCoins(std::vector<COutPoint>& vOutpts); - // keystore implementation - // Generate a new key + /** + * keystore implementation + * Generate a new key + */ CPubKey GenerateNewKey(); - // Adds a key to the store, and saves it to disk. + //! Adds a key to the store, and saves it to disk. bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); - // Adds a key to the store, without saving it to disk (used by LoadWallet) + //! Adds a key to the store, without saving it to disk (used by LoadWallet) bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); } - // Load metadata (used by LoadWallet) + //! Load metadata (used by LoadWallet) bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata); bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; } - // Adds an encrypted key to the store, and saves it to disk. + //! Adds an encrypted key to the store, and saves it to disk. bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); - // Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) + //! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); bool AddCScript(const CScript& redeemScript); bool LoadCScript(const CScript& redeemScript); - /// Adds a destination data tuple to the store, and saves it to disk + //! Adds a destination data tuple to the store, and saves it to disk bool AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value); - /// Erases a destination data tuple in the store and on disk + //! Erases a destination data tuple in the store and on disk bool EraseDestData(const CTxDestination &dest, const std::string &key); - /// Adds a destination data tuple to the store, without saving it to disk + //! Adds a destination data tuple to the store, without saving it to disk bool LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value); - /// Look up a destination data tuple in the store, return true if found false otherwise + //! Look up a destination data tuple in the store, return true if found false otherwise bool GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const; - // Adds a watch-only address to the store, and saves it to disk. + //! Adds a watch-only address to the store, and saves it to disk. bool AddWatchOnly(const CScript &dest); - // Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) + bool RemoveWatchOnly(const CScript &dest); + //! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) bool LoadWatchOnly(const CScript &dest); bool Unlock(const SecureString& strWalletPassphrase); @@ -231,17 +258,19 @@ public: void GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const; - /** Increment the next transaction order id - @return next transaction order id + /** + * Increment the next transaction order id + * @return next transaction order id */ int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL); typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair; typedef std::multimap<int64_t, TxPair > TxItems; - /** Get the wallet's activity log - @return multimap of ordered transactions and accounting entries - @warning Returned pointers are *only* valid within the scope of passed acentries + /** + * Get the wallet's activity log + * @return multimap of ordered transactions and accounting entries + * @warning Returned pointers are *only* valid within the scope of passed acentries */ TxItems OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount = ""); @@ -253,21 +282,20 @@ public: int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); void ReacceptWalletTransactions(); void ResendWalletTransactions(); - int64_t GetBalance() const; - int64_t GetUnconfirmedBalance() const; - int64_t GetImmatureBalance() const; - int64_t GetWatchOnlyBalance() const; - int64_t GetUnconfirmedWatchOnlyBalance() const; - int64_t GetImmatureWatchOnlyBalance() const; - bool CreateTransaction(const std::vector<std::pair<CScript, int64_t> >& vecSend, - CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); - bool CreateTransaction(CScript scriptPubKey, int64_t nValue, - CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); + CAmount GetBalance() const; + CAmount GetUnconfirmedBalance() const; + CAmount GetImmatureBalance() const; + CAmount GetWatchOnlyBalance() const; + CAmount GetUnconfirmedWatchOnlyBalance() const; + CAmount GetImmatureWatchOnlyBalance() const; + bool CreateTransaction(const std::vector<std::pair<CScript, CAmount> >& vecSend, + CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); + bool CreateTransaction(CScript scriptPubKey, const CAmount& nValue, + CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); - std::string SendMoney(const CTxDestination &address, int64_t nValue, CWalletTx& wtxNew); static CFeeRate minTxFee; - static int64_t GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool); + static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool); bool NewKeyPool(); bool TopUpKeyPool(unsigned int kpSize = 0); @@ -279,24 +307,24 @@ public: void GetAllReserveKeys(std::set<CKeyID>& setAddress) const; std::set< std::set<CTxDestination> > GetAddressGroupings(); - std::map<CTxDestination, int64_t> GetAddressBalances(); + std::map<CTxDestination, CAmount> GetAddressBalances(); std::set<CTxDestination> GetAccountAddresses(std::string strAccount) const; isminetype IsMine(const CTxIn& txin) const; - int64_t GetDebit(const CTxIn& txin, const isminefilter& filter) const; + CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const; isminetype IsMine(const CTxOut& txout) const { return ::IsMine(*this, txout.scriptPubKey); } - int64_t GetCredit(const CTxOut& txout, const isminefilter& filter) const + CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const { if (!MoneyRange(txout.nValue)) throw std::runtime_error("CWallet::GetCredit() : value out of range"); return ((IsMine(txout) & filter) ? txout.nValue : 0); } bool IsChange(const CTxOut& txout) const; - int64_t GetChange(const CTxOut& txout) const + CAmount GetChange(const CTxOut& txout) const { if (!MoneyRange(txout.nValue)) throw std::runtime_error("CWallet::GetChange() : value out of range"); @@ -309,13 +337,14 @@ public: return true; return false; } - bool IsFromMe(const CTransaction& tx) const // should probably be renamed to IsRelevantToMe + /** should probably be renamed to IsRelevantToMe */ + bool IsFromMe(const CTransaction& tx) const { return (GetDebit(tx, ISMINE_ALL) > 0); } - int64_t GetDebit(const CTransaction& tx, const isminefilter& filter) const + CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const { - int64_t nDebit = 0; + CAmount nDebit = 0; BOOST_FOREACH(const CTxIn& txin, tx.vin) { nDebit += GetDebit(txin, filter); @@ -324,9 +353,9 @@ public: } return nDebit; } - int64_t GetCredit(const CTransaction& tx, const isminefilter& filter) const + CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const { - int64_t nCredit = 0; + CAmount nCredit = 0; BOOST_FOREACH(const CTxOut& txout, tx.vout) { nCredit += GetCredit(txout, filter); @@ -335,9 +364,9 @@ public: } return nCredit; } - int64_t GetChange(const CTransaction& tx) const + CAmount GetChange(const CTransaction& tx) const { - int64_t nChange = 0; + CAmount nChange = 0; BOOST_FOREACH(const CTxOut& txout, tx.vout) { nChange += GetChange(txout); @@ -375,19 +404,20 @@ public: bool SetDefaultKey(const CPubKey &vchPubKey); - // signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower + //! signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false); - // change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format) + //! change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format) bool SetMaxVersion(int nVersion); - // get the current wallet format (the oldest client version guaranteed to understand this wallet) + //! get the current wallet format (the oldest client version guaranteed to understand this wallet) int GetVersion() { LOCK(cs_wallet); return nWalletVersion; } - // Get wallet transactions that conflict with given transaction (spend same outputs) + //! Get wallet transactions that conflict with given transaction (spend same outputs) std::set<uint256> GetConflicts(const uint256& txid) const; - /** Address book entry changed. + /** + * Address book entry changed. * @note called with lock cs_wallet held. */ boost::signals2::signal<void (CWallet *wallet, const CTxDestination @@ -395,7 +425,8 @@ public: const std::string &purpose, ChangeType status)> NotifyAddressBookChanged; - /** Wallet transaction added, removed or updated. + /** + * Wallet transaction added, removed or updated. * @note called with lock cs_wallet held. */ boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx, @@ -457,7 +488,7 @@ static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue) struct COutputEntry { CTxDestination destination; - int64_t amount; + CAmount amount; int vout; }; @@ -465,7 +496,7 @@ struct COutputEntry class CMerkleTx : public CTransaction { private: - int GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const; + int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const; public: uint256 hashBlock; @@ -506,18 +537,22 @@ public: int SetMerkleBranch(const CBlock& block); - // Return depth of transaction in blockchain: - // -1 : not in blockchain, and not in memory pool (conflicted transaction) - // 0 : in memory pool, waiting to be included in a block - // >=1 : this many blocks deep in the main chain - int GetDepthInMainChain(CBlockIndex* &pindexRet) const; - int GetDepthInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } - bool IsInMainChain() const { CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; } + + /** + * Return depth of transaction in blockchain: + * -1 : not in blockchain, and not in memory pool (conflicted transaction) + * 0 : in memory pool, waiting to be included in a block + * >=1 : this many blocks deep in the main chain + */ + int GetDepthInMainChain(const CBlockIndex* &pindexRet) const; + int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } + bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; } int GetBlocksToMaturity() const; bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectInsaneFee=true); }; -/** A transaction with a bunch of additional info that only the owner cares about. +/** + * A transaction with a bunch of additional info that only the owner cares about. * It includes any unrecorded transactions needed to link it back to the block chain. */ class CWalletTx : public CMerkleTx @@ -529,11 +564,11 @@ public: mapValue_t mapValue; std::vector<std::pair<std::string, std::string> > vOrderForm; unsigned int fTimeReceivedIsTxTime; - unsigned int nTimeReceived; // time received by this node + unsigned int nTimeReceived; //! time received by this node unsigned int nTimeSmart; char fFromMe; std::string strFromAccount; - int64_t nOrderPos; // position in ordered transaction list + int64_t nOrderPos; //! position in ordered transaction list // memory only mutable bool fDebitCached; @@ -545,15 +580,15 @@ public: mutable bool fImmatureWatchCreditCached; mutable bool fAvailableWatchCreditCached; mutable bool fChangeCached; - mutable int64_t nDebitCached; - mutable int64_t nCreditCached; - mutable int64_t nImmatureCreditCached; - mutable int64_t nAvailableCreditCached; - mutable int64_t nWatchDebitCached; - mutable int64_t nWatchCreditCached; - mutable int64_t nImmatureWatchCreditCached; - mutable int64_t nAvailableWatchCreditCached; - mutable int64_t nChangeCached; + mutable CAmount nDebitCached; + mutable CAmount nCreditCached; + mutable CAmount nImmatureCreditCached; + mutable CAmount nAvailableCreditCached; + mutable CAmount nWatchDebitCached; + mutable CAmount nWatchCreditCached; + mutable CAmount nImmatureWatchCreditCached; + mutable CAmount nAvailableWatchCreditCached; + mutable CAmount nChangeCached; CWalletTx() { @@ -625,7 +660,7 @@ public: } READWRITE(*(CMerkleTx*)this); - std::vector<CMerkleTx> vUnused; // Used to be vtxPrev + std::vector<CMerkleTx> vUnused; //! Used to be vtxPrev READWRITE(vUnused); READWRITE(mapValue); READWRITE(vOrderForm); @@ -650,7 +685,7 @@ public: mapValue.erase("timesmart"); } - // make sure balances are recalculated + //! make sure balances are recalculated void MarkDirty() { fCreditCached = false; @@ -669,13 +704,13 @@ public: MarkDirty(); } - // filter decides which addresses will count towards the debit - int64_t GetDebit(const isminefilter& filter) const + //! filter decides which addresses will count towards the debit + CAmount GetDebit(const isminefilter& filter) const { if (vin.empty()) return 0; - int64_t debit = 0; + CAmount debit = 0; if(filter & ISMINE_SPENDABLE) { if (fDebitCached) @@ -701,21 +736,40 @@ public: return debit; } - int64_t GetCredit(bool fUseCache=true) const + CAmount GetCredit(const isminefilter& filter) const { // Must wait until coinbase is safely deep enough in the chain before valuing it if (IsCoinBase() && GetBlocksToMaturity() > 0) return 0; - // GetBalance can assume transactions in mapWallet won't change - if (fUseCache && fCreditCached) - return nCreditCached; - nCreditCached = pwallet->GetCredit(*this, ISMINE_ALL); - fCreditCached = true; - return nCreditCached; + int64_t credit = 0; + if (filter & ISMINE_SPENDABLE) + { + // GetBalance can assume transactions in mapWallet won't change + if (fCreditCached) + credit += nCreditCached; + else + { + nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE); + fCreditCached = true; + credit += nCreditCached; + } + } + if (filter & ISMINE_WATCH_ONLY) + { + if (fWatchCreditCached) + credit += nWatchCreditCached; + else + { + nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY); + fWatchCreditCached = true; + credit += nWatchCreditCached; + } + } + return credit; } - int64_t GetImmatureCredit(bool fUseCache=true) const + CAmount GetImmatureCredit(bool fUseCache=true) const { if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) { @@ -729,7 +783,7 @@ public: return 0; } - int64_t GetAvailableCredit(bool fUseCache=true) const + CAmount GetAvailableCredit(bool fUseCache=true) const { if (pwallet == 0) return 0; @@ -741,7 +795,7 @@ public: if (fUseCache && fAvailableCreditCached) return nAvailableCreditCached; - int64_t nCredit = 0; + CAmount nCredit = 0; uint256 hashTx = GetHash(); for (unsigned int i = 0; i < vout.size(); i++) { @@ -759,7 +813,7 @@ public: return nCredit; } - int64_t GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const + CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const { if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) { @@ -773,7 +827,7 @@ public: return 0; } - int64_t GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const + CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const { if (pwallet == 0) return 0; @@ -785,7 +839,7 @@ public: if (fUseCache && fAvailableWatchCreditCached) return nAvailableWatchCreditCached; - int64_t nCredit = 0; + CAmount nCredit = 0; for (unsigned int i = 0; i < vout.size(); i++) { if (!pwallet->IsSpent(GetHash(), i)) @@ -802,7 +856,7 @@ public: return nCredit; } - int64_t GetChange() const + CAmount GetChange() const { if (fChangeCached) return nChangeCached; @@ -812,10 +866,10 @@ public: } void GetAmounts(std::list<COutputEntry>& listReceived, - std::list<COutputEntry>& listSent, int64_t& nFee, std::string& strSentAccount, const isminefilter& filter) const; + std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const; - void GetAccountAmounts(const std::string& strAccount, int64_t& nReceived, - int64_t& nSent, int64_t& nFee, const isminefilter& filter) const; + void GetAccountAmounts(const std::string& strAccount, CAmount& nReceived, + CAmount& nSent, CAmount& nFee, const isminefilter& filter) const; bool IsFromMe(const isminefilter& filter) const { @@ -889,8 +943,8 @@ public: int64_t nTimeCreated; int64_t nTimeExpires; std::string strComment; - //// todo: add something to note what created it (user, getnewaddress, change) - //// maybe should have a map<string, string> property map + //! todo: add something to note what created it (user, getnewaddress, change) + //! maybe should have a map<string, string> property map CWalletKey(int64_t nExpires=0); @@ -912,7 +966,8 @@ public: -/** Account information. +/** + * Account information. * Stored in wallet with key "acc"+string account name. */ class CAccount @@ -942,19 +997,20 @@ public: -/** Internal transfers. +/** + * Internal transfers. * Database key is acentry<account><counter>. */ class CAccountingEntry { public: std::string strAccount; - int64_t nCreditDebit; + CAmount nCreditDebit; int64_t nTime; std::string strOtherAccount; std::string strComment; mapValue_t mapValue; - int64_t nOrderPos; // position in ordered transaction list + int64_t nOrderPos; //! position in ordered transaction list uint64_t nEntryNo; CAccountingEntry() @@ -979,7 +1035,7 @@ public: inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { if (!(nType & SER_GETHASH)) READWRITE(nVersion); - // Note: strAccount is serialized as part of the key, not here. + //! Note: strAccount is serialized as part of the key, not here. READWRITE(nCreditDebit); READWRITE(nTime); READWRITE(LIMITED_STRING(strOtherAccount, 65536)); diff --git a/src/wallet_ismine.cpp b/src/wallet_ismine.cpp index 07149ebd0b..5482348e35 100644 --- a/src/wallet_ismine.cpp +++ b/src/wallet_ismine.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,6 +7,7 @@ #include "key.h" #include "keystore.h" +#include "script/script.h" #include "script/standard.h" #include <boost/foreach.hpp> @@ -73,7 +74,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) case TX_MULTISIG: { // Only consider transactions "mine" if we own ALL the - // keys involved. multi-signature transactions that are + // keys involved. Multi-signature transactions that are // partially owned (somebody else has a key that can spend // them) enable spend-out-from-under-you attacks, especially // in shared-wallet situations. diff --git a/src/wallet_ismine.h b/src/wallet_ismine.h index f326b86815..6293df8b10 100644 --- a/src/wallet_ismine.h +++ b/src/wallet_ismine.h @@ -1,10 +1,10 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef H_BITCOIN_WALLET_ISMINE -#define H_BITCOIN_WALLET_ISMINE +#ifndef BITCOIN_WALLET_ISMINE_H +#define BITCOIN_WALLET_ISMINE_H #include "key.h" #include "script/standard.h" @@ -26,4 +26,4 @@ typedef uint8_t isminefilter; isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest); -#endif // H_BITCOIN_WALLET_ISMINE +#endif // BITCOIN_WALLET_ISMINE_H diff --git a/src/walletdb.cpp b/src/walletdb.cpp index a84f44db01..4fd7eb512b 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// 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. #include "walletdb.h" @@ -15,11 +15,11 @@ #include <boost/filesystem.hpp> #include <boost/foreach.hpp> +#include <boost/scoped_ptr.hpp> #include <boost/thread.hpp> -using namespace std; using namespace boost; - +using namespace std; static uint64_t nAccountingEntryNumber = 0; @@ -121,6 +121,12 @@ bool CWalletDB::WriteWatchOnly(const CScript &dest) return Write(std::make_pair(std::string("watchs"), dest), '1'); } +bool CWalletDB::EraseWatchOnly(const CScript &dest) +{ + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("watchs"), dest)); +} + bool CWalletDB::WriteBestBlock(const CBlockLocator& locator) { nWalletDBUpdated++; @@ -179,7 +185,7 @@ bool CWalletDB::WriteAccount(const string& strAccount, const CAccount& account) bool CWalletDB::WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry) { - return Write(boost::make_tuple(string("acentry"), acentry.strAccount, nAccEntryNum), acentry); + return Write(std::make_pair(std::string("acentry"), std::make_pair(acentry.strAccount, nAccEntryNum)), acentry); } bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry) @@ -187,12 +193,12 @@ bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry) return WriteAccountingEntry(++nAccountingEntryNumber, acentry); } -int64_t CWalletDB::GetAccountCreditDebit(const string& strAccount) +CAmount CWalletDB::GetAccountCreditDebit(const string& strAccount) { list<CAccountingEntry> entries; ListAccountCreditDebit(strAccount, entries); - int64_t nCreditDebit = 0; + CAmount nCreditDebit = 0; BOOST_FOREACH (const CAccountingEntry& entry, entries) nCreditDebit += entry.nCreditDebit; @@ -212,7 +218,7 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountin // Read next record CDataStream ssKey(SER_DISK, CLIENT_VERSION); if (fFlags == DB_SET_RANGE) - ssKey << boost::make_tuple(string("acentry"), (fAllAccounts? string("") : strAccount), uint64_t(0)); + ssKey << std::make_pair(std::string("acentry"), std::make_pair((fAllAccounts ? string("") : strAccount), uint64_t(0))); CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); fFlags = DB_NEXT; @@ -391,13 +397,6 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, wss.fAnyUnordered = true; pwallet->AddToWallet(wtx, true); - //// debug print - //LogPrintf("LoadWallet %s\n", wtx.GetHash().ToString()); - //LogPrintf(" %12d %s %s %s\n", - // wtx.vout[0].nValue, - // DateTimeStrFormat("%Y-%m-%d %H:%M:%S", wtx.GetBlockTime()), - // wtx.hashBlock.ToString(), - // wtx.mapValue["message"]); } else if (strType == "acentry") { @@ -461,7 +460,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, { ssValue >> hash; } - catch(...){} + catch (...) {} bool fSkipCheck = false; @@ -665,7 +664,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) } pcursor->close(); } - catch (boost::thread_interrupted) { + catch (const boost::thread_interrupted&) { throw; } catch (...) { @@ -708,7 +707,6 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, vector<uint256>& vTxHash, vector<CWalletTx>& vWtx) { pwallet->vchDefaultKey = CPubKey(); - CWalletScanState wss; bool fNoncriticalErrors = false; DBErrors result = DB_LOAD_OK; @@ -759,7 +757,7 @@ DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, vector<uint256>& vTxHash, vec } pcursor->close(); } - catch (boost::thread_interrupted) { + catch (const boost::thread_interrupted&) { throw; } catch (...) { @@ -880,7 +878,7 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) #endif LogPrintf("copied wallet.dat to %s\n", pathDest.string()); return true; - } catch(const filesystem::filesystem_error &e) { + } catch (const filesystem::filesystem_error& e) { LogPrintf("error copying wallet.dat to %s - %s\n", pathDest.string(), e.what()); return false; } @@ -926,7 +924,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size()); bool fSuccess = allOK; - Db* pdbCopy = new Db(&dbenv.dbenv, 0); + boost::scoped_ptr<Db> pdbCopy(new Db(&dbenv.dbenv, 0)); int ret = pdbCopy->open(NULL, // Txn pointer filename.c_str(), // Filename "main", // Logical db name @@ -967,7 +965,6 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) } ptxn->commit(0); pdbCopy->close(0); - delete pdbCopy; return fSuccess; } @@ -980,11 +977,11 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename) bool CWalletDB::WriteDestData(const std::string &address, const std::string &key, const std::string &value) { nWalletDBUpdated++; - return Write(boost::make_tuple(std::string("destdata"), address, key), value); + return Write(std::make_pair(std::string("destdata"), std::make_pair(address, key)), value); } bool CWalletDB::EraseDestData(const std::string &address, const std::string &key) { nWalletDBUpdated++; - return Erase(boost::make_tuple(string("destdata"), address, key)); + return Erase(std::make_pair(std::string("destdata"), std::make_pair(address, key))); } diff --git a/src/walletdb.h b/src/walletdb.h index 2c5b608f3d..45c00328a4 100644 --- a/src/walletdb.h +++ b/src/walletdb.h @@ -1,11 +1,12 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-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_WALLETDB_H #define BITCOIN_WALLETDB_H +#include "amount.h" #include "db.h" #include "key.h" #include "keystore.h" @@ -95,6 +96,7 @@ public: bool WriteCScript(const uint160& hash, const CScript& redeemScript); bool WriteWatchOnly(const CScript &script); + bool EraseWatchOnly(const CScript &script); bool WriteBestBlock(const CBlockLocator& locator); bool ReadBestBlock(CBlockLocator& locator); @@ -118,7 +120,7 @@ public: bool EraseDestData(const std::string &address, const std::string &key); bool WriteAccountingEntry(const CAccountingEntry& acentry); - int64_t GetAccountCreditDebit(const std::string& strAccount); + CAmount GetAccountCreditDebit(const std::string& strAccount); void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries); DBErrors ReorderTransactions(CWallet* pwallet); |