diff options
Diffstat (limited to 'src')
478 files changed, 35429 insertions, 12350 deletions
diff --git a/src/.clang-format b/src/.clang-format index 226a15d185..129f062ef8 100644 --- a/src/.clang-format +++ b/src/.clang-format @@ -1,4 +1,6 @@ +Language: Cpp AccessModifierOffset: -4 +AlignAfterOpenBracket: false AlignEscapedNewlinesLeft: true AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: false @@ -26,7 +28,6 @@ IndentCaseLabels: false IndentFunctionDeclarationAfterType: false IndentWidth: 4 KeepEmptyLinesAtTheStartOfBlocks: false -Language: Cpp MaxEmptyLinesToKeep: 2 NamespaceIndentation: None ObjCSpaceAfterProperty: false diff --git a/src/Makefile.am b/src/Makefile.am index 462774389a..5da1a873de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,8 @@ DIST_SUBDIRS = secp256k1 univalue -AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) +AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) +AM_CXXFLAGS = $(HARDENED_CXXFLAGS) +AM_CPPFLAGS = $(HARDENED_CPPFLAGS) if EMBEDDED_LEVELDB LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include @@ -14,7 +16,7 @@ $(LIBLEVELDB): $(LIBMEMENV) $(LIBLEVELDB) $(LIBMEMENV): @echo "Building LevelDB ..." && $(MAKE) -C $(@D) $(@F) CXX="$(CXX)" \ CC="$(CC)" PLATFORM=$(TARGET_OS) AR="$(AR)" $(LEVELDB_TARGET_FLAGS) \ - OPT="$(CXXFLAGS) $(CPPFLAGS) -D__STDC_LIMIT_MACROS" + OPT="$(AM_CXXFLAGS) $(PIE_FLAGS) $(CXXFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -D__STDC_LIMIT_MACROS" endif BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config @@ -31,13 +33,13 @@ LIBBITCOIN_UTIL=libbitcoin_util.a LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a LIBBITCOINQT=qt/libbitcoinqt.a LIBSECP256K1=secp256k1/libsecp256k1.la -LIBUNIVALUE=univalue/lib/libunivalue.la +LIBUNIVALUE=univalue/libunivalue.la $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) -$(LIBUNIVALUE): $(wildcard univalue/lib/*) - $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue/ +$(LIBUNIVALUE): $(wildcard univalue/lib/*) $(wildcard univalue/include/*) + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) # Make is not made aware of per-object dependencies to avoid limiting building parallelization # But to build the less dependent modules first, we manually select their order here: @@ -64,6 +66,7 @@ endif bin_PROGRAMS = TESTS = +BENCHMARKS = if BUILD_BITCOIND bin_PROGRAMS += bitcoind @@ -97,31 +100,30 @@ BITCOIN_CORE_H = \ compat/sanity.h \ compressor.h \ consensus/consensus.h \ + consensus/merkle.h \ consensus/params.h \ consensus/validation.h \ core_io.h \ core_memusage.h \ - eccryptoverify.h \ - ecwrapper.h \ hash.h \ httprpc.h \ httpserver.h \ init.h \ key.h \ keystore.h \ - leveldbwrapper.h \ + dbwrapper.h \ limitedmap.h \ main.h \ memusage.h \ merkleblock.h \ miner.h \ - mruset.h \ net.h \ netbase.h \ noui.h \ policy/fees.h \ policy/policy.h \ pow.h \ + prevector.h \ primitives/block.h \ primitives/transaction.h \ protocol.h \ @@ -148,6 +150,7 @@ BITCOIN_CORE_H = \ threadsafety.h \ timedata.h \ tinyformat.h \ + torcontrol.h \ txdb.h \ txmempool.h \ ui_interface.h \ @@ -177,7 +180,8 @@ obj/build.h: FORCE libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h # server: shared between bitcoind and bitcoin-qt -libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) +libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) +libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_server_a_SOURCES = \ addrman.cpp \ alert.cpp \ @@ -187,7 +191,7 @@ libbitcoin_server_a_SOURCES = \ httprpc.cpp \ httpserver.cpp \ init.cpp \ - leveldbwrapper.cpp \ + dbwrapper.cpp \ main.cpp \ merkleblock.cpp \ miner.cpp \ @@ -205,6 +209,7 @@ libbitcoin_server_a_SOURCES = \ rpcserver.cpp \ script/sigcache.cpp \ timedata.cpp \ + torcontrol.cpp \ txdb.cpp \ txmempool.cpp \ validationinterface.cpp \ @@ -213,7 +218,8 @@ libbitcoin_server_a_SOURCES = \ if ENABLE_ZMQ LIBBITCOIN_ZMQ=libbitcoin_zmq.a -libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS) +libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_zmq_a_SOURCES = \ zmq/zmqabstractnotifier.cpp \ zmq/zmqnotificationinterface.cpp \ @@ -223,7 +229,8 @@ endif # wallet: shared between bitcoind and bitcoin-qt, but only linked # when wallet enabled -libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_wallet_a_SOURCES = \ wallet/crypter.cpp \ wallet/db.cpp \ @@ -235,7 +242,8 @@ libbitcoin_wallet_a_SOURCES = \ $(BITCOIN_CORE_H) # crypto primitives library -crypto_libbitcoin_crypto_a_CPPFLAGS = $(BITCOIN_CONFIG_INCLUDES) +crypto_libbitcoin_crypto_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_CONFIG_INCLUDES) +crypto_libbitcoin_crypto_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) crypto_libbitcoin_crypto_a_SOURCES = \ crypto/common.h \ crypto/hmac_sha256.cpp \ @@ -252,7 +260,8 @@ crypto_libbitcoin_crypto_a_SOURCES = \ crypto/sha512.h # common: shared between bitcoind, and bitcoin-qt and non-server tools -libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_common_a_SOURCES = \ amount.cpp \ arith_uint256.cpp \ @@ -260,10 +269,9 @@ libbitcoin_common_a_SOURCES = \ chainparams.cpp \ coins.cpp \ compressor.cpp \ + consensus/merkle.cpp \ core_read.cpp \ core_write.cpp \ - eccryptoverify.cpp \ - ecwrapper.cpp \ hash.cpp \ key.cpp \ keystore.cpp \ @@ -283,7 +291,8 @@ libbitcoin_common_a_SOURCES = \ # util: shared between all executables. # This library *must* be included to make sure that the glibc # backward-compatibility objects and their sanity checks are linked. -libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_util_a_SOURCES = \ support/pagelocker.cpp \ chainparamsbase.cpp \ @@ -307,7 +316,8 @@ libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp endif # cli: shared between bitcoin-cli and bitcoin-qt -libbitcoin_cli_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_cli_a_SOURCES = \ rpcclient.cpp \ $(BITCOIN_CORE_H) @@ -317,7 +327,8 @@ nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h # bitcoind binary # bitcoind_SOURCES = bitcoind.cpp -bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES) +bitcoind_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +bitcoind_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS @@ -346,7 +357,8 @@ bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPN # bitcoin-cli binary # bitcoin_cli_SOURCES = bitcoin-cli.cpp -bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) +bitcoin_cli_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) +bitcoin_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS @@ -363,7 +375,8 @@ bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) # bitcoin-tx binary # bitcoin_tx_SOURCES = bitcoin-tx.cpp -bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES) +bitcoin_tx_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +bitcoin_tx_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS @@ -389,8 +402,6 @@ libbitcoinconsensus_la_SOURCES = \ crypto/sha1.cpp \ crypto/sha256.cpp \ crypto/sha512.cpp \ - eccryptoverify.cpp \ - ecwrapper.cpp \ hash.cpp \ primitives/transaction.cpp \ pubkey.cpp \ @@ -404,14 +415,27 @@ if GLIBC_BACK_COMPAT libbitcoinconsensus_la_SOURCES += compat/glibc_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 +libbitcoinconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS) +libbitcoinconsensus_la_LIBADD = $(LIBSECP256K1) +libbitcoinconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -DBUILD_BITCOIN_INTERNAL +libbitcoinconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) endif # -CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno +CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a +CLEANFILES += *.gcda *.gcno +CLEANFILES += compat/*.gcda compat/*.gcno +CLEANFILES += consensus/*.gcda consensus/*.gcno +CLEANFILES += crypto/*.gcda crypto/*.gcno +CLEANFILES += policy/*.gcda policy/*.gcno +CLEANFILES += primitives/*.gcda primitives/*.gcno +CLEANFILES += script/*.gcda script/*.gcno +CLEANFILES += support/*.gcda support/*.gcno +CLEANFILES += univalue/*.gcda univalue/*.gcno +CLEANFILES += wallet/*.gcda wallet/*.gcno +CLEANFILES += wallet/test/*.gcda wallet/test/*.gcno +CLEANFILES += zmq/*.gcda zmq/*.gcno DISTCLEANFILES = obj/build.h @@ -420,7 +444,8 @@ EXTRA_DIST = leveldb clean-local: -$(MAKE) -C leveldb clean -$(MAKE) -C secp256k1 clean - rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno + -$(MAKE) -C univalue clean + -rm -f leveldb/*/*.gcda leveldb/*/*.gcno leveldb/helpers/memenv/*.gcda leveldb/helpers/memenv/*.gcno -rm -f config.h .rc.o: @@ -429,7 +454,7 @@ clean-local: .mm.o: $(AM_V_CXX) $(OBJCXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CXXFLAGS) $(QT_INCLUDES) $(CXXFLAGS) -c -o $@ $< + $(CPPFLAGS) $(AM_CXXFLAGS) $(QT_INCLUDES) $(AM_CXXFLAGS) $(PIE_FLAGS) $(CXXFLAGS) -c -o $@ $< %.pb.cc %.pb.h: %.proto @test -f $(PROTOC) @@ -439,6 +464,10 @@ if ENABLE_TESTS include Makefile.test.include endif +if ENABLE_BENCH +include Makefile.bench.include +endif + if ENABLE_QT include Makefile.qt.include endif diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include new file mode 100644 index 0000000000..d660a3a747 --- /dev/null +++ b/src/Makefile.bench.include @@ -0,0 +1,45 @@ +bin_PROGRAMS += bench/bench_bitcoin +BENCH_SRCDIR = bench +BENCH_BINARY = bench/bench_bitcoin$(EXEEXT) + + +bench_bench_bitcoin_SOURCES = \ + bench/bench_bitcoin.cpp \ + bench/bench.cpp \ + bench/bench.h \ + bench/Examples.cpp + +bench_bench_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CLFAGS) $(EVENT_PTHREADS_CFLAGS) -I$(builddir)/bench/ +bench_bench_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +bench_bench_bitcoin_LDADD = \ + $(LIBBITCOIN_SERVER) \ + $(LIBBITCOIN_COMMON) \ + $(LIBBITCOIN_UNIVALUE) \ + $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_CRYPTO) \ + $(LIBLEVELDB) \ + $(LIBMEMENV) \ + $(LIBSECP256K1) + +if ENABLE_ZMQ +bench_bench_bitcoin_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) +endif + +if ENABLE_WALLET +bench_bench_bitcoin_LDADD += $(LIBBITCOIN_WALLET) +endif + +bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) +bench_bench_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) + +CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno + +CLEANFILES += $(CLEAN_BITCOIN_BENCH) + +bitcoin_bench: $(BENCH_BINARY) + +bench: $(BENCH_BINARY) FORCE + $(BENCH_BINARY) + +bitcoin_bench_clean : FORCE + rm -f $(CLEAN_BITCOIN_BENCH) $(bench_bench_bitcoin_OBJECTS) $(BENCH_BINARY) diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 67fd7c1076..a390d96a9f 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -3,37 +3,41 @@ EXTRA_LIBRARIES += qt/libbitcoinqt.a # bitcoin qt core # QT_TS = \ - qt/locale/bitcoin_ach.ts \ qt/locale/bitcoin_af_ZA.ts \ qt/locale/bitcoin_ar.ts \ qt/locale/bitcoin_be_BY.ts \ + qt/locale/bitcoin_bg_BG.ts \ qt/locale/bitcoin_bg.ts \ qt/locale/bitcoin_bs.ts \ qt/locale/bitcoin_ca_ES.ts \ qt/locale/bitcoin_ca.ts \ qt/locale/bitcoin_ca@valencia.ts \ - qt/locale/bitcoin_cmn.ts \ + qt/locale/bitcoin_cs_CZ.ts \ qt/locale/bitcoin_cs.ts \ qt/locale/bitcoin_cy.ts \ qt/locale/bitcoin_da.ts \ qt/locale/bitcoin_de.ts \ qt/locale/bitcoin_el_GR.ts \ + qt/locale/bitcoin_el.ts \ + qt/locale/bitcoin_en_GB.ts \ qt/locale/bitcoin_en.ts \ qt/locale/bitcoin_eo.ts \ qt/locale/bitcoin_es_CL.ts \ qt/locale/bitcoin_es_DO.ts \ + qt/locale/bitcoin_es_ES.ts \ qt/locale/bitcoin_es_MX.ts \ qt/locale/bitcoin_es.ts \ qt/locale/bitcoin_es_UY.ts \ + qt/locale/bitcoin_es_VE.ts \ qt/locale/bitcoin_et.ts \ qt/locale/bitcoin_eu_ES.ts \ qt/locale/bitcoin_fa_IR.ts \ qt/locale/bitcoin_fa.ts \ qt/locale/bitcoin_fi.ts \ qt/locale/bitcoin_fr_CA.ts \ + qt/locale/bitcoin_fr_FR.ts \ qt/locale/bitcoin_fr.ts \ qt/locale/bitcoin_gl.ts \ - qt/locale/bitcoin_gu_IN.ts \ qt/locale/bitcoin_he.ts \ qt/locale/bitcoin_hi_IN.ts \ qt/locale/bitcoin_hr.ts \ @@ -48,6 +52,7 @@ QT_TS = \ qt/locale/bitcoin_la.ts \ qt/locale/bitcoin_lt.ts \ qt/locale/bitcoin_lv_LV.ts \ + qt/locale/bitcoin_mk_MK.ts \ qt/locale/bitcoin_mn.ts \ qt/locale/bitcoin_ms_MY.ts \ qt/locale/bitcoin_nb.ts \ @@ -57,14 +62,15 @@ QT_TS = \ qt/locale/bitcoin_pt_BR.ts \ qt/locale/bitcoin_pt_PT.ts \ qt/locale/bitcoin_ro_RO.ts \ + qt/locale/bitcoin_ru_RU.ts \ qt/locale/bitcoin_ru.ts \ - qt/locale/bitcoin_sah.ts \ qt/locale/bitcoin_sk.ts \ qt/locale/bitcoin_sl_SI.ts \ qt/locale/bitcoin_sq.ts \ qt/locale/bitcoin_sr.ts \ qt/locale/bitcoin_sv.ts \ qt/locale/bitcoin_th_TH.ts \ + qt/locale/bitcoin_tr_TR.ts \ qt/locale/bitcoin_tr.ts \ qt/locale/bitcoin_uk.ts \ qt/locale/bitcoin_ur_PK.ts \ @@ -72,7 +78,7 @@ QT_TS = \ qt/locale/bitcoin_vi.ts \ qt/locale/bitcoin_vi_VN.ts \ qt/locale/bitcoin_zh_CN.ts \ - qt/locale/bitcoin_zh_HK.ts \ + qt/locale/bitcoin_zh.ts \ qt/locale/bitcoin_zh_TW.ts QT_FORMS_UI = \ @@ -327,8 +333,9 @@ BITCOIN_RC = qt/res/bitcoin-qt-res.rc BITCOIN_QT_INCLUDES = -I$(builddir)/qt -I$(srcdir)/qt -I$(srcdir)/qt/forms \ -I$(builddir)/qt/forms -DQT_NO_KEYWORDS -qt_libbitcoinqt_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ +qt_libbitcoinqt_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ $(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS) +qt_libbitcoinqt_a_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) qt_libbitcoinqt_a_SOURCES = $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(QT_FORMS_UI) \ $(QT_QRC) $(QT_QRC_LOCALE) $(QT_TS) $(PROTOBUF_PROTO) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) @@ -350,8 +357,9 @@ $(QT_MOC): $(PROTOBUF_H) $(QT_MOC_CPP): $(PROTOBUF_H) # bitcoin-qt binary # -qt_bitcoin_qt_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ +qt_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ $(QT_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS) +qt_bitcoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) qt_bitcoin_qt_SOURCES = qt/bitcoin.cpp if TARGET_DARWIN diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index b8725c872d..ede3fac4c3 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -12,7 +12,7 @@ TEST_QT_H = \ qt/test/paymentrequestdata.h \ qt/test/paymentservertests.h -qt_test_test_bitcoin_qt_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ +qt_test_test_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ $(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS) qt_test_test_bitcoin_qt_SOURCES = \ @@ -38,6 +38,7 @@ qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBIT $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +qt_test_test_bitcoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) 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 9a6e43631b..d89132f806 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -35,7 +35,8 @@ GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.r BITCOIN_TESTS =\ test/arith_uint256_tests.cpp \ - test/bignum.h \ + test/scriptnum10.h \ + test/addrman_tests.cpp \ test/alert_tests.cpp \ test/allocator_tests.cpp \ test/base32_tests.cpp \ @@ -53,15 +54,17 @@ BITCOIN_TESTS =\ test/hash_tests.cpp \ test/key_tests.cpp \ test/limitedmap_tests.cpp \ + test/dbwrapper_tests.cpp \ test/main_tests.cpp \ test/mempool_tests.cpp \ + test/merkle_tests.cpp \ test/miner_tests.cpp \ - test/mruset_tests.cpp \ test/multisig_tests.cpp \ test/netbase_tests.cpp \ test/pmt_tests.cpp \ test/policyestimator_tests.cpp \ test/pow_tests.cpp \ + test/prevector_tests.cpp \ test/reverselock_tests.cpp \ test/rpc_tests.cpp \ test/sanity_tests.cpp \ @@ -73,6 +76,7 @@ BITCOIN_TESTS =\ test/sighash_tests.cpp \ test/sigopcount_tests.cpp \ test/skiplist_tests.cpp \ + test/streams_tests.cpp \ test/test_bitcoin.cpp \ test/test_bitcoin.h \ test/timedata_tests.cpp \ @@ -90,9 +94,10 @@ BITCOIN_TESTS += \ 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_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) +test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) if ENABLE_WALLET test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET) endif diff --git a/src/addrman.cpp b/src/addrman.cpp index ff1f7e9187..078b9e1681 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -329,13 +329,17 @@ void CAddrMan::Attempt_(const CService& addr, int64_t nTime) info.nAttempts++; } -CAddrInfo CAddrMan::Select_() +CAddrInfo CAddrMan::Select_(bool newOnly) { if (size() == 0) return CAddrInfo(); + if (newOnly && nNew == 0) + return CAddrInfo(); + // Use a 50% chance for choosing between tried and new table entries. - if (nTried > 0 && (nNew == 0 || GetRandInt(2) == 0)) { + if (!newOnly && + (nTried > 0 && (nNew == 0 || GetRandInt(2) == 0))) { // use a tried node double fChanceFactor = 1.0; while (1) { diff --git a/src/addrman.h b/src/addrman.h index 384b6cfdb9..1123caabfa 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -22,6 +22,8 @@ */ class CAddrInfo : public CAddress { + + public: //! last try whatsoever by us (memory only) int64_t nLastTry; @@ -230,8 +232,8 @@ protected: //! Mark an entry as attempted to connect. void Attempt_(const CService &addr, int64_t nTime); - //! Select an address to connect to. - CAddrInfo Select_(); + //! Select an address to connect to, if newOnly is set to true, only the new table is selected from. + CAddrInfo Select_(bool newOnly); #ifdef DEBUG_ADDRMAN //! Perform consistency check. Returns an error code or zero. @@ -532,13 +534,13 @@ public: /** * Choose an address to connect to. */ - CAddrInfo Select() + CAddrInfo Select(bool newOnly = false) { CAddrInfo addrRet; { LOCK(cs); Check(); - addrRet = Select_(); + addrRet = Select_(newOnly); Check(); } return addrRet; @@ -567,6 +569,12 @@ public: Check(); } } + + //! Ensure that bucket placement is always the same for testing purposes. + void MakeDeterministic(){ + nKey.SetNull(); //Do not use outside of tests. + } + }; #endif // BITCOIN_ADDRMAN_H diff --git a/src/alert.cpp b/src/alert.cpp index 91e54a9178..eb1cd5e7f6 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -138,7 +138,7 @@ bool CAlert::RelayTo(CNode* pnode) const AppliesToMe() || GetAdjustedTime() < nRelayUntil) { - pnode->PushMessage("alert", *this); + pnode->PushMessage(NetMsgType::ALERT, *this); return true; } } diff --git a/src/alert.h b/src/alert.h index 4f9fff9181..8cb86e338c 100644 --- a/src/alert.h +++ b/src/alert.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/amount.cpp b/src/amount.cpp index b469181984..a3abd8cd83 100644 --- a/src/amount.cpp +++ b/src/amount.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/amount.h b/src/amount.h index 90e6b5aa8e..a48b17d514 100644 --- a/src/amount.h +++ b/src/amount.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -30,7 +30,7 @@ extern const std::string CURRENCY_UNIT; static const CAmount MAX_MONEY = 21000000 * COIN; inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } -/** Type-safe wrapper class to for fee rates +/** Type-safe wrapper class for fee rates * (how much to pay based on transaction size) */ class CFeeRate @@ -51,6 +51,7 @@ public: 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; } + CFeeRate& operator+=(const CFeeRate& a) { nSatoshisPerK += a.nSatoshisPerK; return *this; } std::string ToString() const; ADD_SERIALIZE_METHODS; diff --git a/src/arith_uint256.h b/src/arith_uint256.h index 103c78bb8e..ba3d620158 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/base58.cpp b/src/base58.cpp index c809185056..5e26cf8d47 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/base58.h b/src/base58.h index 90014b9496..a3980118aa 100644 --- a/src/base58.h +++ b/src/base58.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/bench/.gitignore b/src/bench/.gitignore new file mode 100644 index 0000000000..e231fe4cab --- /dev/null +++ b/src/bench/.gitignore @@ -0,0 +1 @@ +bench_bitcoin diff --git a/src/bench/Examples.cpp b/src/bench/Examples.cpp new file mode 100644 index 0000000000..b6b020a971 --- /dev/null +++ b/src/bench/Examples.cpp @@ -0,0 +1,34 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "bench.h" +#include "main.h" +#include "utiltime.h" + +// Sanity test: this should loop ten times, and +// min/max/average should be close to 100ms. +static void Sleep100ms(benchmark::State& state) +{ + while (state.KeepRunning()) { + MilliSleep(100); + } +} + +BENCHMARK(Sleep100ms); + +// Extremely fast-running benchmark: +#include <math.h> + +volatile double sum = 0.0; // volatile, global so not optimized away + +static void Trig(benchmark::State& state) +{ + double d = 0.01; + while (state.KeepRunning()) { + sum += sin(d); + d += 0.000001; + } +} + +BENCHMARK(Trig); diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp new file mode 100644 index 0000000000..6ee3cdc27a --- /dev/null +++ b/src/bench/bench.cpp @@ -0,0 +1,70 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "bench.h" + +#include <iostream> +#include <sys/time.h> + +using namespace benchmark; + +std::map<std::string, BenchFunction> BenchRunner::benchmarks; + +static double gettimedouble(void) { + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_usec * 0.000001 + tv.tv_sec; +} + +BenchRunner::BenchRunner(std::string name, BenchFunction func) +{ + benchmarks.insert(std::make_pair(name, func)); +} + +void +BenchRunner::RunAll(double elapsedTimeForOne) +{ + std::cout << "Benchmark" << "," << "count" << "," << "min" << "," << "max" << "," << "average" << "\n"; + + for (std::map<std::string,BenchFunction>::iterator it = benchmarks.begin(); + it != benchmarks.end(); ++it) { + + State state(it->first, elapsedTimeForOne); + BenchFunction& func = it->second; + func(state); + } +} + +bool State::KeepRunning() +{ + double now; + if (count == 0) { + beginTime = now = gettimedouble(); + } + else { + // timeCheckCount is used to avoid calling gettime most of the time, + // so benchmarks that run very quickly get consistent results. + if ((count+1)%timeCheckCount != 0) { + ++count; + return true; // keep going + } + now = gettimedouble(); + double elapsedOne = (now - lastTime)/timeCheckCount; + if (elapsedOne < minTime) minTime = elapsedOne; + if (elapsedOne > maxTime) maxTime = elapsedOne; + if (elapsedOne*timeCheckCount < maxElapsed/16) timeCheckCount *= 2; + } + lastTime = now; + ++count; + + if (now - beginTime < maxElapsed) return true; // Keep going + + --count; + + // Output results + double average = (now-beginTime)/count; + std::cout << name << "," << count << "," << minTime << "," << maxTime << "," << average << "\n"; + + return false; +} diff --git a/src/bench/bench.h b/src/bench/bench.h new file mode 100644 index 0000000000..5ce13c642b --- /dev/null +++ b/src/bench/bench.h @@ -0,0 +1,72 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_BENCH_BENCH_H +#define BITCOIN_BENCH_BENCH_H + +#include <map> +#include <string> + +#include <boost/function.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/stringize.hpp> + +// Simple micro-benchmarking framework; API mostly matches a subset of the Google Benchmark +// framework (see https://github.com/google/benchmark) +// Wny not use the Google Benchmark framework? Because adding Yet Another Dependency +// (that uses cmake as its build system and has lots of features we don't need) isn't +// worth it. + +/* + * Usage: + +static void CODE_TO_TIME(benchmark::State& state) +{ + ... do any setup needed... + while (state.KeepRunning()) { + ... do stuff you want to time... + } + ... do any cleanup needed... +} + +BENCHMARK(CODE_TO_TIME); + + */ + +namespace benchmark { + + class State { + std::string name; + double maxElapsed; + double beginTime; + double lastTime, minTime, maxTime; + int64_t count; + int64_t timeCheckCount; + public: + State(std::string _name, double _maxElapsed) : name(_name), maxElapsed(_maxElapsed), count(0) { + minTime = std::numeric_limits<double>::max(); + maxTime = std::numeric_limits<double>::min(); + timeCheckCount = 1; + } + bool KeepRunning(); + }; + + typedef boost::function<void(State&)> BenchFunction; + + class BenchRunner + { + static std::map<std::string, BenchFunction> benchmarks; + + public: + BenchRunner(std::string name, BenchFunction func); + + static void RunAll(double elapsedTimeForOne=1.0); + }; +} + +// BENCHMARK(foo) expands to: benchmark::BenchRunner bench_11foo("foo", foo); +#define BENCHMARK(n) \ + benchmark::BenchRunner BOOST_PP_CAT(bench_, BOOST_PP_CAT(__LINE__, n))(BOOST_PP_STRINGIZE(n), n); + +#endif // BITCOIN_BENCH_BENCH_H diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp new file mode 100644 index 0000000000..db1402216d --- /dev/null +++ b/src/bench/bench_bitcoin.cpp @@ -0,0 +1,21 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "bench.h" + +#include "key.h" +#include "main.h" +#include "util.h" + +int +main(int argc, char** argv) +{ + ECC_Start(); + SetupEnvironment(); + fPrintToDebugLog = false; // don't want to write to debug.log file + + benchmark::BenchRunner::RunAll(); + + ECC_Stop(); +} diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index e0fe6aa5bf..fb20521085 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -22,6 +22,7 @@ using namespace std; +static const char DEFAULT_RPCCONNECT[] = "127.0.0.1"; static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900; std::string HelpMessageCli() @@ -29,13 +30,11 @@ std::string HelpMessageCli() string strUsage; strUsage += HelpMessageGroup(_("Options:")); strUsage += HelpMessageOpt("-?", _("This help message")); - strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf")); + strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME)); strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory")); - strUsage += HelpMessageOpt("-testnet", _("Use the test network")); - strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be " - "solved instantly. This is intended for regression testing tools and app development.")); - strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1")); - strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8332, 18332)); + AppendParamsHelpMessages(strUsage); + strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), DEFAULT_RPCCONNECT)); + strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), BaseParams(CBaseChainParams::MAIN).RPCPort(), BaseParams(CBaseChainParams::TESTNET).RPCPort())); strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start")); strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections")); @@ -69,7 +68,7 @@ static bool AppInitRPC(int argc, char* argv[]) // Parameters // ParseParameters(argc, argv); - if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version")) { + if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) { std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n"; if (!mapArgs.count("-version")) { strUsage += "\n" + _("Usage:") + "\n" + @@ -94,8 +93,10 @@ static bool AppInitRPC(int argc, char* argv[]) 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"); + try { + SelectBaseParams(ChainNameFromCommandLine()); + } catch (const std::exception& e) { + fprintf(stderr, "Error: %s\n", e.what()); return false; } if (GetBoolArg("-rpcssl", false)) @@ -141,7 +142,7 @@ static void http_request_done(struct evhttp_request *req, void *ctx) UniValue CallRPC(const string& strMethod, const UniValue& params) { - std::string host = GetArg("-rpcconnect", "127.0.0.1"); + std::string host = GetArg("-rpcconnect", DEFAULT_RPCCONNECT); int port = GetArg("-rpcport", BaseParams().RPCPort()); // Create event base diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index f7518fab5d..2c502ead31 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -35,14 +35,16 @@ static bool AppInitRawTx(int argc, char* argv[]) ParseParameters(argc, argv); // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause) - if (!SelectParamsFromCommandLine()) { - fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n"); + try { + SelectParams(ChainNameFromCommandLine()); + } catch (const std::exception& e) { + fprintf(stderr, "Error: %s\n", e.what()); return false; } fCreateBlank = GetBoolArg("-create", false); - if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help")) + if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help")) { // First part of help message is specific to this utility std::string strUsage = _("Bitcoin Core bitcoin-tx utility version") + " " + FormatFullVersion() + "\n\n" + @@ -58,8 +60,7 @@ static bool AppInitRawTx(int argc, char* argv[]) strUsage += HelpMessageOpt("-create", _("Create new, empty TX.")); strUsage += HelpMessageOpt("-json", _("Select JSON output")); strUsage += HelpMessageOpt("-txid", _("Output only the hex-encoded transaction id of the resultant transaction.")); - strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.")); - strUsage += HelpMessageOpt("-testnet", _("Use the test network")); + AppendParamsHelpMessages(strUsage); fprintf(stdout, "%s", strUsage.c_str()); @@ -476,9 +477,15 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) class Secp256k1Init { + ECCVerifyHandle globalVerifyHandle; + public: - Secp256k1Init() { ECC_Start(); } - ~Secp256k1Init() { ECC_Stop(); } + Secp256k1Init() { + ECC_Start(); + } + ~Secp256k1Init() { + ECC_Stop(); + } }; static void MutateTx(CMutableTransaction& tx, const string& command, diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index b512f74c22..3b6608c95a 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -72,7 +72,7 @@ bool AppInit(int argc, char* argv[]) ParseParameters(argc, argv); // Process help and version before taking care about datadir - if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version")) + if (mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) { std::string strUsage = _("Bitcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n"; @@ -107,8 +107,10 @@ bool AppInit(int argc, char* argv[]) return false; } // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause) - if (!SelectParamsFromCommandLine()) { - fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n"); + try { + SelectParams(ChainNameFromCommandLine()); + } catch (const std::exception& e) { + fprintf(stderr, "Error: %s\n", e.what()); return false; } @@ -149,6 +151,9 @@ bool AppInit(int argc, char* argv[]) #endif SoftSetBoolArg("-server", true); + // Set this early so that parameter interactions go to console + InitLogging(); + InitParameterInteraction(); fRet = AppInit2(threadGroup, scheduler); } catch (const std::exception& e) { diff --git a/src/bloom.cpp b/src/bloom.cpp index de87206592..4e6f0e5d2d 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -216,30 +216,54 @@ void CBloomFilter::UpdateEmptyFull() isEmpty = empty; } -CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate) : - b1(nElements * 2, fpRate, 0), b2(nElements * 2, fpRate, 0) +CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate) { - // Implemented using two bloom filters of 2 * nElements each. - // We fill them up, and clear them, staggered, every nElements - // inserted, so at least one always contains the last nElements - // inserted. - nInsertions = 0; - nBloomSize = nElements * 2; - + double logFpRate = log(fpRate); + /* The optimal number of hash functions is log(fpRate) / log(0.5), but + * restrict it to the range 1-50. */ + nHashFuncs = std::max(1, std::min((int)round(logFpRate / log(0.5)), 50)); + /* In this rolling bloom filter, we'll store between 2 and 3 generations of nElements / 2 entries. */ + nEntriesPerGeneration = (nElements + 1) / 2; + uint32_t nMaxElements = nEntriesPerGeneration * 3; + /* The maximum fpRate = pow(1.0 - exp(-nHashFuncs * nMaxElements / nFilterBits), nHashFuncs) + * => pow(fpRate, 1.0 / nHashFuncs) = 1.0 - exp(-nHashFuncs * nMaxElements / nFilterBits) + * => 1.0 - pow(fpRate, 1.0 / nHashFuncs) = exp(-nHashFuncs * nMaxElements / nFilterBits) + * => log(1.0 - pow(fpRate, 1.0 / nHashFuncs)) = -nHashFuncs * nMaxElements / nFilterBits + * => nFilterBits = -nHashFuncs * nMaxElements / log(1.0 - pow(fpRate, 1.0 / nHashFuncs)) + * => nFilterBits = -nHashFuncs * nMaxElements / log(1.0 - exp(logFpRate / nHashFuncs)) + */ + uint32_t nFilterBits = (uint32_t)ceil(-1.0 * nHashFuncs * nMaxElements / log(1.0 - exp(logFpRate / nHashFuncs))); + data.clear(); + /* We store up to 16 'bits' per data element. */ + data.resize((nFilterBits + 15) / 16); reset(); } +/* Similar to CBloomFilter::Hash */ +inline unsigned int CRollingBloomFilter::Hash(unsigned int nHashNum, const std::vector<unsigned char>& vDataToHash) const { + return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (data.size() * 16); +} + void CRollingBloomFilter::insert(const std::vector<unsigned char>& vKey) { - if (nInsertions == 0) { - b1.clear(); - } else if (nInsertions == nBloomSize / 2) { - b2.clear(); + if (nEntriesThisGeneration == nEntriesPerGeneration) { + nEntriesThisGeneration = 0; + nGeneration++; + if (nGeneration == 4) { + nGeneration = 1; + } + /* Wipe old entries that used this generation number. */ + for (uint32_t p = 0; p < data.size() * 16; p++) { + if (get(p) == nGeneration) { + put(p, 0); + } + } } - b1.insert(vKey); - b2.insert(vKey); - if (++nInsertions == nBloomSize) { - nInsertions = 0; + nEntriesThisGeneration++; + + for (int n = 0; n < nHashFuncs; n++) { + uint32_t h = Hash(n, vKey); + put(h, nGeneration); } } @@ -251,10 +275,13 @@ void CRollingBloomFilter::insert(const uint256& hash) bool CRollingBloomFilter::contains(const std::vector<unsigned char>& vKey) const { - if (nInsertions < nBloomSize / 2) { - return b2.contains(vKey); + for (int n = 0; n < nHashFuncs; n++) { + uint32_t h = Hash(n, vKey); + if (get(h) == 0) { + return false; + } } - return b1.contains(vKey); + return true; } bool CRollingBloomFilter::contains(const uint256& hash) const @@ -265,8 +292,10 @@ bool CRollingBloomFilter::contains(const uint256& hash) const void CRollingBloomFilter::reset() { - unsigned int nNewTweak = GetRand(std::numeric_limits<unsigned int>::max()); - b1.reset(nNewTweak); - b2.reset(nNewTweak); - nInsertions = 0; + nTweak = GetRand(std::numeric_limits<unsigned int>::max()); + nEntriesThisGeneration = 0; + nGeneration = 1; + for (std::vector<uint32_t>::iterator it = data.begin(); it != data.end(); it++) { + *it = 0; + } } diff --git a/src/bloom.h b/src/bloom.h index a4dba8cb4f..b0ad8b875d 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -110,8 +110,11 @@ public: * reset() is provided, which also changes nTweak to decrease the impact of * false-positives. * - * contains(item) will always return true if item was one of the last N things + * contains(item) will always return true if item was one of the last N to 1.5*N * insert()'ed ... but may also return true for items that were not inserted. + * + * It needs around 1.8 bytes per element per factor 0.1 of false positive rate. + * (More accurately: 3/(log(256)*log(2)) * log(1/fpRate) * nElements bytes) */ class CRollingBloomFilter { @@ -129,10 +132,23 @@ public: void reset(); private: - unsigned int nBloomSize; - unsigned int nInsertions; - CBloomFilter b1, b2; -}; + int nEntriesPerGeneration; + int nEntriesThisGeneration; + int nGeneration; + std::vector<uint32_t> data; + unsigned int nTweak; + int nHashFuncs; + + unsigned int Hash(unsigned int nHashNum, const std::vector<unsigned char>& vDataToHash) const; + inline int get(uint32_t position) const { + return (data[(position >> 4) % data.size()] >> (2 * (position & 0xF))) & 0x3; + } + + inline void put(uint32_t position, uint32_t val) { + uint32_t& cell = data[(position >> 4) % data.size()]; + cell = (cell & ~(((uint32_t)3) << (2 * (position & 0xF)))) | (val << (2 * (position & 0xF))); + } +}; #endif // BITCOIN_BLOOM_H diff --git a/src/chain.cpp b/src/chain.cpp index 5b8ce076c4..3450ed6c3f 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -51,6 +51,9 @@ CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { } const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { + if (pindex == NULL) { + return NULL; + } if (pindex->nHeight > Height()) pindex = pindex->GetAncestor(Height()); while (pindex && !Contains(pindex)) diff --git a/src/chain.h b/src/chain.h index 01be2d6e5c..b9b1b9306f 100644 --- a/src/chain.h +++ b/src/chain.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 430b75683b..9cf99492c9 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -1,10 +1,12 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "chainparams.h" +#include "consensus/merkle.h" +#include "tinyformat.h" #include "util.h" #include "utilstrencodings.h" @@ -31,7 +33,7 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi genesis.nVersion = nVersion; genesis.vtx.push_back(txNew); genesis.hashPrevBlock.SetNull(); - genesis.hashMerkleRoot = genesis.ComputeMerkleRoot(); + genesis.hashMerkleRoot = BlockMerkleRoot(genesis); return genesis; } @@ -72,10 +74,13 @@ public: consensus.nMajorityEnforceBlockUpgrade = 750; consensus.nMajorityRejectBlockOutdated = 950; consensus.nMajorityWindow = 1000; + consensus.BIP34Height = 227931; + consensus.BIP34Hash = uint256S("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8"); consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = false; + consensus.fPowNoRetargeting = false; /** * 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 @@ -151,10 +156,13 @@ public: consensus.nMajorityEnforceBlockUpgrade = 51; consensus.nMajorityRejectBlockOutdated = 75; consensus.nMajorityWindow = 100; + consensus.BIP34Height = 21111; + consensus.BIP34Hash = uint256S("0x0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8"); consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = true; + consensus.fPowNoRetargeting = false; pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; @@ -171,7 +179,6 @@ public: vFixedSeeds.clear(); vSeeds.clear(); - vSeeds.push_back(CDNSSeedData("alexykot.me", "testnet-seed.alexykot.me")); vSeeds.push_back(CDNSSeedData("bitcoin.petertodd.org", "testnet-seed.bitcoin.petertodd.org")); vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me")); vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de")); @@ -213,10 +220,13 @@ public: consensus.nMajorityEnforceBlockUpgrade = 750; consensus.nMajorityRejectBlockOutdated = 950; consensus.nMajorityWindow = 1000; + consensus.BIP34Height = -1; // BIP34 has not necessarily activated on regtest + consensus.BIP34Hash = uint256(); consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks consensus.nPowTargetSpacing = 10 * 60; consensus.fPowAllowMinDifficultyBlocks = true; + consensus.fPowNoRetargeting = true; pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; @@ -263,31 +273,20 @@ const CChainParams &Params() { return *pCurrentParams; } -CChainParams &Params(CBaseChainParams::Network network) { - switch (network) { - case CBaseChainParams::MAIN: +CChainParams& Params(const std::string& chain) +{ + if (chain == CBaseChainParams::MAIN) return mainParams; - case CBaseChainParams::TESTNET: + else if (chain == CBaseChainParams::TESTNET) return testNetParams; - case CBaseChainParams::REGTEST: + else if (chain == CBaseChainParams::REGTEST) return regTestParams; - default: - assert(false && "Unimplemented network"); - return mainParams; - } + else + throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); } -void SelectParams(CBaseChainParams::Network network) { +void SelectParams(const std::string& network) +{ SelectBaseParams(network); pCurrentParams = &Params(network); } - -bool SelectParamsFromCommandLine() -{ - CBaseChainParams::Network network = NetworkIdFromCommandLine(); - if (network == CBaseChainParams::MAX_NETWORK_TYPES) - return false; - - SelectParams(network); - return true; -} diff --git a/src/chainparams.h b/src/chainparams.h index 342bccb12f..fdf5c17a0e 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -65,7 +65,7 @@ public: /** Policy: Filter transactions that do not match well-defined patterns */ bool RequireStandard() const { return fRequireStandard; } int64_t MaxTipAge() const { return nMaxTipAge; } - int64_t PruneAfterHeight() const { return nPruneAfterHeight; } + uint64_t PruneAfterHeight() const { return nPruneAfterHeight; } /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } /** In the future use NetworkIDString() for RPC fields */ @@ -105,16 +105,15 @@ protected: */ const CChainParams &Params(); -/** Return parameters for the given network. */ -CChainParams &Params(CBaseChainParams::Network network); - -/** Sets the params returned by Params() to those for the given network. */ -void SelectParams(CBaseChainParams::Network network); +/** + * @returns CChainParams for the given BIP70 chain name. + */ +CChainParams& Params(const std::string& chain); /** - * Looks for -regtest or -testnet and then calls SelectParams as appropriate. - * Returns false if an invalid combination is given. + * Sets the params returned by Params() to those for the given BIP70 chain name. + * @throws std::runtime_error when the chain is not supported. */ -bool SelectParamsFromCommandLine(); +void SelectParams(const std::string& chain); #endif // BITCOIN_CHAINPARAMS_H diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 9c87bf2154..cb71a8b550 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -1,14 +1,29 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "chainparamsbase.h" +#include "tinyformat.h" #include "util.h" #include <assert.h> +const std::string CBaseChainParams::MAIN = "main"; +const std::string CBaseChainParams::TESTNET = "test"; +const std::string CBaseChainParams::REGTEST = "regtest"; + +void AppendParamsHelpMessages(std::string& strUsage, bool debugHelp) +{ + strUsage += HelpMessageGroup(_("Chain selection options:")); + strUsage += HelpMessageOpt("-testnet", _("Use the test chain")); + if (debugHelp) { + strUsage += HelpMessageOpt("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. " + "This is intended for regression testing tools and app development."); + } +} + /** * Main network */ @@ -50,19 +65,6 @@ public: }; static CBaseRegTestParams regTestParams; -/* - * Unit test - */ -class CBaseUnitTestParams : public CBaseMainParams -{ -public: - CBaseUnitTestParams() - { - strDataDir = "unittest"; - } -}; -static CBaseUnitTestParams unitTestParams; - static CBaseChainParams* pCurrentBaseParams = 0; const CBaseChainParams& BaseParams() @@ -71,31 +73,30 @@ const CBaseChainParams& BaseParams() return *pCurrentBaseParams; } -void SelectBaseParams(CBaseChainParams::Network network) +CBaseChainParams& BaseParams(const std::string& chain) { - switch (network) { - case CBaseChainParams::MAIN: - pCurrentBaseParams = &mainParams; - break; - case CBaseChainParams::TESTNET: - pCurrentBaseParams = &testNetParams; - break; - case CBaseChainParams::REGTEST: - pCurrentBaseParams = ®TestParams; - break; - default: - assert(false && "Unimplemented network"); - return; - } + if (chain == CBaseChainParams::MAIN) + return mainParams; + else if (chain == CBaseChainParams::TESTNET) + return testNetParams; + else if (chain == CBaseChainParams::REGTEST) + return regTestParams; + else + throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); +} + +void SelectBaseParams(const std::string& chain) +{ + pCurrentBaseParams = &BaseParams(chain); } -CBaseChainParams::Network NetworkIdFromCommandLine() +std::string ChainNameFromCommandLine() { bool fRegTest = GetBoolArg("-regtest", false); bool fTestNet = GetBoolArg("-testnet", false); if (fTestNet && fRegTest) - return CBaseChainParams::MAX_NETWORK_TYPES; + throw std::runtime_error("Invalid combination of -regtest and -testnet."); if (fRegTest) return CBaseChainParams::REGTEST; if (fTestNet) @@ -103,16 +104,6 @@ CBaseChainParams::Network NetworkIdFromCommandLine() return CBaseChainParams::MAIN; } -bool SelectBaseParamsFromCommandLine() -{ - CBaseChainParams::Network network = NetworkIdFromCommandLine(); - if (network == CBaseChainParams::MAX_NETWORK_TYPES) - return false; - - SelectBaseParams(network); - return true; -} - bool AreBaseParamsConfigured() { return pCurrentBaseParams != NULL; diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index 4369d0aef7..59493afb9b 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,13 +15,10 @@ class CBaseChainParams { public: - enum Network { - MAIN, - TESTNET, - REGTEST, - - MAX_NETWORK_TYPES - }; + /** BIP70 chain name strings (main, test or regtest) */ + static const std::string MAIN; + static const std::string TESTNET; + static const std::string REGTEST; const std::string& DataDir() const { return strDataDir; } int RPCPort() const { return nRPCPort; } @@ -34,25 +31,27 @@ protected: }; /** + * Append the help messages for the chainparams options to the + * parameter string. + */ +void AppendParamsHelpMessages(std::string& strUsage, bool debugHelp=true); + +/** * Return the currently selected parameters. This won't change after app * startup, except for unit tests. */ const CBaseChainParams& BaseParams(); -/** Sets the params returned by Params() to those for the given network. */ -void SelectBaseParams(CBaseChainParams::Network network); +CBaseChainParams& BaseParams(const std::string& chain); -/** - * Looks for -regtest or -testnet and returns the appropriate Network ID. - * Returns MAX_NETWORK_TYPES if an invalid combination is given. - */ -CBaseChainParams::Network NetworkIdFromCommandLine(); +/** Sets the params returned by Params() to those for the given network. */ +void SelectBaseParams(const std::string& chain); /** - * Calls NetworkIdFromCommandLine() and then calls SelectParams as appropriate. - * Returns false if an invalid combination is given. + * Looks for -regtest, -testnet and returns the appropriate BIP70 chain name. + * @return CBaseChainParams::MAX_NETWORK_TYPES if an invalid combination is given. CBaseChainParams::MAIN by default. */ -bool SelectBaseParamsFromCommandLine(); +std::string ChainNameFromCommandLine(); /** * Return true if SelectBaseParamsFromCommandLine() has been called to select diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index a9822eed89..aefddce464 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/checkpoints.h b/src/checkpoints.h index 5fce6fa81e..cd25ea5379 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/checkqueue.h b/src/checkqueue.h index 20ba25bb41..32e25d5c8c 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/clientversion.h b/src/clientversion.h index 5a06b310a3..c832663a76 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,7 +15,7 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 0 -#define CLIENT_VERSION_MINOR 11 +#define CLIENT_VERSION_MINOR 12 #define CLIENT_VERSION_REVISION 99 #define CLIENT_VERSION_BUILD 0 diff --git a/src/coincontrol.h b/src/coincontrol.h index bc965f9e19..9626ad2c5b 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -16,6 +16,8 @@ public: bool fAllowOtherInputs; //! Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria bool fAllowWatchOnly; + //! Minimum absolute fee (not per kilobyte) + CAmount nMinimumTotalFee; CCoinControl() { @@ -28,6 +30,7 @@ public: fAllowOtherInputs = false; fAllowWatchOnly = false; setSelected.clear(); + nMinimumTotalFee = 0; } bool HasSelected() const diff --git a/src/coins.cpp b/src/coins.cpp index f02949de53..4d1dbdea4e 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -117,6 +117,15 @@ CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) { return CCoinsModifier(*this, ret.first, cachedCoinUsage); } +CCoinsModifier CCoinsViewCache::ModifyNewCoins(const uint256 &txid) { + assert(!hasModifier); + std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())); + ret.first->second.coins.Clear(); + ret.first->second.flags = CCoinsCacheEntry::FRESH; + ret.first->second.flags |= CCoinsCacheEntry::DIRTY; + return CCoinsModifier(*this, ret.first, 0); +} + const CCoins* CCoinsViewCache::AccessCoins(const uint256 &txid) const { CCoinsMap::const_iterator it = FetchCoins(txid); if (it == cacheCoins.end()) { @@ -135,6 +144,11 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) const { return (it != cacheCoins.end() && !it->second.coins.vout.empty()); } +bool CCoinsViewCache::HaveCoinsInCache(const uint256 &txid) const { + CCoinsMap::const_iterator it = cacheCoins.find(txid); + return it != cacheCoins.end(); +} + uint256 CCoinsViewCache::GetBestBlock() const { if (hashBlock.IsNull()) hashBlock = base->GetBestBlock(); @@ -151,18 +165,23 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn 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); + // The parent cache does not have an entry, while the child does + // We can ignore it if it's both FRESH and pruned in the child + if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coins.IsPruned())) { + // Otherwise we will need to create it in the parent + // and move the data up and mark it as dirty CCoinsCacheEntry& entry = cacheCoins[it->first]; entry.coins.swap(it->second.coins); cachedCoinsUsage += entry.coins.DynamicMemoryUsage(); - entry.flags = CCoinsCacheEntry::DIRTY | CCoinsCacheEntry::FRESH; + entry.flags = CCoinsCacheEntry::DIRTY; + // We can mark it FRESH in the parent if it was FRESH in the child + // Otherwise it might have just been flushed from the parent's cache + // and already exist in the grandparent + if (it->second.flags & CCoinsCacheEntry::FRESH) + entry.flags |= CCoinsCacheEntry::FRESH; } } else { + // Found the entry in the parent cache 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 @@ -192,6 +211,15 @@ bool CCoinsViewCache::Flush() { return fOk; } +void CCoinsViewCache::Uncache(const uint256& hash) +{ + CCoinsMap::iterator it = cacheCoins.find(hash); + if (it != cacheCoins.end() && it->second.flags == 0) { + cachedCoinsUsage -= it->second.coins.DynamicMemoryUsage(); + cacheCoins.erase(it); + } +} + unsigned int CCoinsViewCache::GetCacheSize() const { return cacheCoins.size(); } @@ -229,8 +257,9 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const return true; } -double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const +double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight, CAmount &inChainInputValue) const { + inChainInputValue = 0; if (tx.IsCoinBase()) return 0.0; double dResult = 0.0; @@ -239,8 +268,9 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const const CCoins* coins = AccessCoins(txin.prevout.hash); assert(coins); if (!coins->IsAvailable(txin.prevout.n)) continue; - if (coins->nHeight < nHeight) { + if (coins->nHeight <= nHeight) { dResult += coins->vout[txin.prevout.n].nValue * (nHeight-coins->nHeight); + inChainInputValue += coins->vout[txin.prevout.n].nValue; } } return tx.ComputePriority(dResult); diff --git a/src/coins.h b/src/coins.h index bf4a777b8a..eab94ec1b4 100644 --- a/src/coins.h +++ b/src/coins.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -29,11 +29,11 @@ * - VARINT(nHeight) * * The nCode value consists of: - * - bit 1: IsCoinBase() - * - bit 2: vout[0] is not spent - * - bit 4: vout[1] is not spent + * - bit 0: IsCoinBase() + * - bit 1: vout[0] is not spent + * - bit 2: vout[1] is not spent * - The higher bits encode N, the number of non-zero bytes in the following bitvector. - * - In case both bit 2 and bit 4 are unset, they encode N-1, as there must be at + * - In case both bit 1 and bit 2 are unset, they encode N-1, as there must be at * least one non-spent output). * * Example: 0104835800816115944e077fe7c803cfa57f29b36bf87c1d358bb85e @@ -58,7 +58,7 @@ * * - version = 1 * - code = 9 (coinbase, neither vout[0] or vout[1] are unspent, - * 2 (1, +1 because both bit 2 and bit 4 are unset) non-zero bitvector bytes follow) + * 2 (1, +1 because both bit 1 and bit 2 are unset) non-zero bitvector bytes follow) * - unspentness bitvector: bits 2 (0x04) and 14 (0x4000) are set, so vout[2+2] and vout[14+2] are unspent * - vout[4]: 86ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4ee * * 86ef97d579: compact amount representation for 234925952 (2.35 BTC) @@ -406,6 +406,13 @@ public: bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); /** + * Check if we have the given tx already loaded in this cache. + * The semantics are the same as HaveCoins(), but no calls to + * the backing CCoinsView are made. + */ + bool HaveCoinsInCache(const uint256 &txid) const; + + /** * 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. @@ -420,12 +427,29 @@ public: CCoinsModifier ModifyCoins(const uint256 &txid); /** + * Return a modifiable reference to a CCoins. Assumes that no entry with the given + * txid exists and creates a new one. This saves a database access in the case where + * the coins were to be wiped out by FromTx anyway. This should not be called with + * the 2 historical coinbase duplicate pairs because the new coins are marked fresh, and + * in the event the duplicate coinbase was spent before a flush, the now pruned coins + * would not properly overwrite the first coinbase of the pair. Simultaneous modifications + * are not allowed. + */ + CCoinsModifier ModifyNewCoins(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. */ bool Flush(); + /** + * Removes the transaction with the given hash from the cache, if it is + * not modified. + */ + void Uncache(const uint256 &txid); + //! Calculate the size of the cache (in number of transactions) unsigned int GetCacheSize() const; @@ -445,8 +469,12 @@ public: //! 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 - double GetPriority(const CTransaction &tx, int nHeight) const; + /** + * Return priority of tx at height nHeight. Also calculate the sum of the values of the inputs + * that are already in the chain. These are the inputs that will age and increase priority as + * new blocks are added to the chain. + */ + double GetPriority(const CTransaction &tx, int nHeight, CAmount &inChainInputValue) const; const CTxOut &GetOutputFor(const CTxIn& input) const; diff --git a/src/compat.h b/src/compat.h index 5378c2c761..1225ea18ed 100644 --- a/src/compat.h +++ b/src/compat.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -38,6 +38,7 @@ #include <sys/types.h> #include <net/if.h> #include <netinet/in.h> +#include <netinet/tcp.h> #include <arpa/inet.h> #include <ifaddrs.h> #include <limits.h> diff --git a/src/compat/endian.h b/src/compat/endian.h index 9fec2a07fa..6bfae42c77 100644 --- a/src/compat/endian.h +++ b/src/compat/endian.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index f937844e9f..5a099cf53c 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -13,4 +13,10 @@ static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; /** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ static const int COINBASE_MATURITY = 100; +/** Flags for LockTime() */ +enum { + /* Use GetMedianTimePast() instead of nTime for end point timestamp. */ + LOCKTIME_MEDIAN_TIME_PAST = (1 << 1), +}; + #endif // BITCOIN_CONSENSUS_CONSENSUS_H diff --git a/src/consensus/merkle.cpp b/src/consensus/merkle.cpp new file mode 100644 index 0000000000..9a8afa8a33 --- /dev/null +++ b/src/consensus/merkle.cpp @@ -0,0 +1,172 @@ +#include "merkle.h" +#include "hash.h" +#include "utilstrencodings.h" + +/* 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. +*/ + +/* This implements a constant-space merkle root/path calculator, limited to 2^32 leaves. */ +static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot, bool* pmutated, uint32_t branchpos, std::vector<uint256>* pbranch) { + if (pbranch) pbranch->clear(); + if (leaves.size() == 0) { + if (pmutated) *pmutated = false; + if (proot) *proot = uint256(); + return; + } + bool mutated = false; + // count is the number of leaves processed so far. + uint32_t count = 0; + // inner is an array of eagerly computed subtree hashes, indexed by tree + // level (0 being the leaves). + // For example, when count is 25 (11001 in binary), inner[4] is the hash of + // the first 16 leaves, inner[3] of the next 8 leaves, and inner[0] equal to + // the last leaf. The other inner entries are undefined. + uint256 inner[32]; + // Which position in inner is a hash that depends on the matching leaf. + int matchlevel = -1; + // First process all leaves into 'inner' values. + while (count < leaves.size()) { + uint256 h = leaves[count]; + bool matchh = count == branchpos; + count++; + int level; + // For each of the lower bits in count that are 0, do 1 step. Each + // corresponds to an inner value that existed before processing the + // current leaf, and each needs a hash to combine it. + for (level = 0; !(count & (((uint32_t)1) << level)); level++) { + if (pbranch) { + if (matchh) { + pbranch->push_back(inner[level]); + } else if (matchlevel == level) { + pbranch->push_back(h); + matchh = true; + } + } + mutated |= (inner[level] == h); + CHash256().Write(inner[level].begin(), 32).Write(h.begin(), 32).Finalize(h.begin()); + } + // Store the resulting hash at inner position level. + inner[level] = h; + if (matchh) { + matchlevel = level; + } + } + // Do a final 'sweep' over the rightmost branch of the tree to process + // odd levels, and reduce everything to a single top value. + // Level is the level (counted from the bottom) up to which we've sweeped. + int level = 0; + // As long as bit number level in count is zero, skip it. It means there + // is nothing left at this level. + while (!(count & (((uint32_t)1) << level))) { + level++; + } + uint256 h = inner[level]; + bool matchh = matchlevel == level; + while (count != (((uint32_t)1) << level)) { + // If we reach this point, h is an inner value that is not the top. + // We combine it with itself (Bitcoin's special rule for odd levels in + // the tree) to produce a higher level one. + if (pbranch && matchh) { + pbranch->push_back(h); + } + CHash256().Write(h.begin(), 32).Write(h.begin(), 32).Finalize(h.begin()); + // Increment count to the value it would have if two entries at this + // level had existed. + count += (((uint32_t)1) << level); + level++; + // And propagate the result upwards accordingly. + while (!(count & (((uint32_t)1) << level))) { + if (pbranch) { + if (matchh) { + pbranch->push_back(inner[level]); + } else if (matchlevel == level) { + pbranch->push_back(h); + matchh = true; + } + } + CHash256().Write(inner[level].begin(), 32).Write(h.begin(), 32).Finalize(h.begin()); + level++; + } + } + // Return result. + if (pmutated) *pmutated = mutated; + if (proot) *proot = h; +} + +uint256 ComputeMerkleRoot(const std::vector<uint256>& leaves, bool* mutated) { + uint256 hash; + MerkleComputation(leaves, &hash, mutated, -1, NULL); + return hash; +} + +std::vector<uint256> ComputeMerkleBranch(const std::vector<uint256>& leaves, uint32_t position) { + std::vector<uint256> ret; + MerkleComputation(leaves, NULL, NULL, position, &ret); + return ret; +} + +uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector<uint256>& vMerkleBranch, uint32_t nIndex) { + uint256 hash = leaf; + 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; +} + +uint256 BlockMerkleRoot(const CBlock& block, bool* mutated) +{ + std::vector<uint256> leaves; + leaves.resize(block.vtx.size()); + for (size_t s = 0; s < block.vtx.size(); s++) { + leaves[s] = block.vtx[s].GetHash(); + } + return ComputeMerkleRoot(leaves, mutated); +} + +std::vector<uint256> BlockMerkleBranch(const CBlock& block, uint32_t position) +{ + std::vector<uint256> leaves; + leaves.resize(block.vtx.size()); + for (size_t s = 0; s < block.vtx.size(); s++) { + leaves[s] = block.vtx[s].GetHash(); + } + return ComputeMerkleBranch(leaves, position); +} diff --git a/src/consensus/merkle.h b/src/consensus/merkle.h new file mode 100644 index 0000000000..6ef59745ac --- /dev/null +++ b/src/consensus/merkle.h @@ -0,0 +1,32 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_MERKLE +#define BITCOIN_MERKLE + +#include <stdint.h> +#include <vector> + +#include "primitives/transaction.h" +#include "primitives/block.h" +#include "uint256.h" + +uint256 ComputeMerkleRoot(const std::vector<uint256>& leaves, bool* mutated = NULL); +std::vector<uint256> ComputeMerkleBranch(const std::vector<uint256>& leaves, uint32_t position); +uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector<uint256>& branch, uint32_t position); + +/* + * Compute the Merkle root of the transactions in a block. + * *mutated is set to true if a duplicated subtree was found. + */ +uint256 BlockMerkleRoot(const CBlock& block, bool* mutated = NULL); + +/* + * Compute the Merkle branch for the tree of transactions in a block, for a + * given position. + * This can be verified using ComputeMerkleRootFromBranch. + */ +std::vector<uint256> BlockMerkleBranch(const CBlock& block, uint32_t position); + +#endif diff --git a/src/consensus/params.h b/src/consensus/params.h index c480a1cce1..335750fe80 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -19,9 +19,13 @@ struct Params { int nMajorityEnforceBlockUpgrade; int nMajorityRejectBlockOutdated; int nMajorityWindow; + /** Block height and hash at which BIP34 becomes active */ + int BIP34Height; + uint256 BIP34Hash; /** Proof of work parameters */ uint256 powLimit; bool fPowAllowMinDifficultyBlocks; + bool fPowNoRetargeting; int64_t nPowTargetSpacing; int64_t nPowTargetTimespan; int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; } diff --git a/src/consensus/validation.h b/src/consensus/validation.h index d6051edc38..d7e57f5b5e 100644 --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/core_io.h b/src/core_io.h index ba5b4e6487..e8c0c49e84 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/core_memusage.h b/src/core_memusage.h index a05f59ee0c..450537d059 100644 --- a/src/core_memusage.h +++ b/src/core_memusage.h @@ -10,7 +10,7 @@ #include "memusage.h" static inline size_t RecursiveDynamicUsage(const CScript& script) { - return memusage::DynamicUsage(*static_cast<const std::vector<unsigned char>*>(&script)); + return memusage::DynamicUsage(*static_cast<const CScriptBase*>(&script)); } static inline size_t RecursiveDynamicUsage(const COutPoint& out) { diff --git a/src/core_read.cpp b/src/core_read.cpp index 4be24f8e09..444a4c7eba 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/core_write.cpp b/src/core_write.cpp index 533fedfe7a..b660e86c30 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp new file mode 100644 index 0000000000..1907e2fa78 --- /dev/null +++ b/src/dbwrapper.cpp @@ -0,0 +1,152 @@ +// Copyright (c) 2012-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "dbwrapper.h" + +#include "util.h" +#include "random.h" + +#include <boost/filesystem.hpp> + +#include <leveldb/cache.h> +#include <leveldb/env.h> +#include <leveldb/filter_policy.h> +#include <memenv.h> +#include <stdint.h> + +void HandleError(const leveldb::Status& status) throw(dbwrapper_error) +{ + if (status.ok()) + return; + LogPrintf("%s\n", status.ToString()); + if (status.IsCorruption()) + throw dbwrapper_error("Database corrupted"); + if (status.IsIOError()) + throw dbwrapper_error("Database I/O error"); + if (status.IsNotFound()) + throw dbwrapper_error("Database entry missing"); + throw dbwrapper_error("Unknown database error"); +} + +static leveldb::Options GetOptions(size_t nCacheSize) +{ + leveldb::Options options; + options.block_cache = leveldb::NewLRUCache(nCacheSize / 2); + options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously + options.filter_policy = leveldb::NewBloomFilterPolicy(10); + options.compression = leveldb::kNoCompression; + options.max_open_files = 64; + if (leveldb::kMajorVersion > 1 || (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) { + // LevelDB versions before 1.16 consider short writes to be corruption. Only trigger error + // on corruption in later versions. + options.paranoid_checks = true; + } + return options; +} + +CDBWrapper::CDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory, bool fWipe, bool obfuscate) +{ + penv = NULL; + readoptions.verify_checksums = true; + iteroptions.verify_checksums = true; + iteroptions.fill_cache = false; + syncoptions.sync = true; + options = GetOptions(nCacheSize); + options.create_if_missing = true; + if (fMemory) { + penv = leveldb::NewMemEnv(leveldb::Env::Default()); + options.env = penv; + } else { + if (fWipe) { + LogPrintf("Wiping LevelDB in %s\n", path.string()); + leveldb::Status result = leveldb::DestroyDB(path.string(), options); + HandleError(result); + } + TryCreateDirectory(path); + LogPrintf("Opening LevelDB in %s\n", path.string()); + } + leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb); + HandleError(status); + LogPrintf("Opened LevelDB successfully\n"); + + // The base-case obfuscation key, which is a noop. + obfuscate_key = std::vector<unsigned char>(OBFUSCATE_KEY_NUM_BYTES, '\000'); + + bool key_exists = Read(OBFUSCATE_KEY_KEY, obfuscate_key); + + if (!key_exists && obfuscate && IsEmpty()) { + // Initialize non-degenerate obfuscation if it won't upset + // existing, non-obfuscated data. + std::vector<unsigned char> new_key = CreateObfuscateKey(); + + // Write `new_key` so we don't obfuscate the key with itself + Write(OBFUSCATE_KEY_KEY, new_key); + obfuscate_key = new_key; + + LogPrintf("Wrote new obfuscate key for %s: %s\n", path.string(), GetObfuscateKeyHex()); + } + + LogPrintf("Using obfuscation key for %s: %s\n", path.string(), GetObfuscateKeyHex()); +} + +CDBWrapper::~CDBWrapper() +{ + delete pdb; + pdb = NULL; + delete options.filter_policy; + options.filter_policy = NULL; + delete options.block_cache; + options.block_cache = NULL; + delete penv; + options.env = NULL; +} + +bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync) throw(dbwrapper_error) +{ + leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch); + HandleError(status); + return true; +} + +// Prefixed with null character to avoid collisions with other keys +// +// We must use a string constructor which specifies length so that we copy +// past the null-terminator. +const std::string CDBWrapper::OBFUSCATE_KEY_KEY("\000obfuscate_key", 14); + +const unsigned int CDBWrapper::OBFUSCATE_KEY_NUM_BYTES = 8; + +/** + * Returns a string (consisting of 8 random bytes) suitable for use as an + * obfuscating XOR key. + */ +std::vector<unsigned char> CDBWrapper::CreateObfuscateKey() const +{ + unsigned char buff[OBFUSCATE_KEY_NUM_BYTES]; + GetRandBytes(buff, OBFUSCATE_KEY_NUM_BYTES); + return std::vector<unsigned char>(&buff[0], &buff[OBFUSCATE_KEY_NUM_BYTES]); + +} + +bool CDBWrapper::IsEmpty() +{ + boost::scoped_ptr<CDBIterator> it(NewIterator()); + it->SeekToFirst(); + return !(it->Valid()); +} + +const std::vector<unsigned char>& CDBWrapper::GetObfuscateKey() const +{ + return obfuscate_key; +} + +std::string CDBWrapper::GetObfuscateKeyHex() const +{ + return HexStr(obfuscate_key); +} + +CDBIterator::~CDBIterator() { delete piter; } +bool CDBIterator::Valid() { return piter->Valid(); } +void CDBIterator::SeekToFirst() { piter->SeekToFirst(); } +void CDBIterator::Next() { piter->Next(); } diff --git a/src/dbwrapper.h b/src/dbwrapper.h new file mode 100644 index 0000000000..5e7313f7eb --- /dev/null +++ b/src/dbwrapper.h @@ -0,0 +1,280 @@ +// Copyright (c) 2012-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_DBWRAPPER_H +#define BITCOIN_DBWRAPPER_H + +#include "clientversion.h" +#include "serialize.h" +#include "streams.h" +#include "util.h" +#include "utilstrencodings.h" +#include "version.h" + +#include <boost/filesystem/path.hpp> + +#include <leveldb/db.h> +#include <leveldb/write_batch.h> + +class dbwrapper_error : public std::runtime_error +{ +public: + dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {} +}; + +void HandleError(const leveldb::Status& status) throw(dbwrapper_error); + +/** Batch of changes queued to be written to a CDBWrapper */ +class CDBBatch +{ + friend class CDBWrapper; + +private: + leveldb::WriteBatch batch; + const std::vector<unsigned char> *obfuscate_key; + +public: + /** + * @param[in] obfuscate_key If passed, XOR data with this key. + */ + CDBBatch(const std::vector<unsigned char> *obfuscate_key) : obfuscate_key(obfuscate_key) { }; + + template <typename K, typename V> + void Write(const K& key, const V& value) + { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(ssKey.GetSerializeSize(key)); + ssKey << key; + leveldb::Slice slKey(&ssKey[0], ssKey.size()); + + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + ssValue.reserve(ssValue.GetSerializeSize(value)); + ssValue << value; + ssValue.Xor(*obfuscate_key); + leveldb::Slice slValue(&ssValue[0], ssValue.size()); + + batch.Put(slKey, slValue); + } + + template <typename K> + void Erase(const K& key) + { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(ssKey.GetSerializeSize(key)); + ssKey << key; + leveldb::Slice slKey(&ssKey[0], ssKey.size()); + + batch.Delete(slKey); + } +}; + +class CDBIterator +{ +private: + leveldb::Iterator *piter; + const std::vector<unsigned char> *obfuscate_key; + +public: + + /** + * @param[in] piterIn The original leveldb iterator. + * @param[in] obfuscate_key If passed, XOR data with this key. + */ + CDBIterator(leveldb::Iterator *piterIn, const std::vector<unsigned char>* obfuscate_key) : + piter(piterIn), obfuscate_key(obfuscate_key) { }; + ~CDBIterator(); + + bool Valid(); + + void SeekToFirst(); + + template<typename K> void Seek(const K& key) { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(ssKey.GetSerializeSize(key)); + ssKey << key; + leveldb::Slice slKey(&ssKey[0], ssKey.size()); + piter->Seek(slKey); + } + + void Next(); + + template<typename K> bool GetKey(K& key) { + leveldb::Slice slKey = piter->key(); + try { + CDataStream ssKey(slKey.data(), slKey.data() + slKey.size(), SER_DISK, CLIENT_VERSION); + ssKey >> key; + } catch (const std::exception&) { + return false; + } + return true; + } + + unsigned int GetKeySize() { + return piter->key().size(); + } + + template<typename V> bool GetValue(V& value) { + leveldb::Slice slValue = piter->value(); + try { + CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION); + ssValue.Xor(*obfuscate_key); + ssValue >> value; + } catch (const std::exception&) { + return false; + } + return true; + } + + unsigned int GetValueSize() { + return piter->value().size(); + } + +}; + +class CDBWrapper +{ +private: + //! custom environment this database is using (may be NULL in case of default environment) + leveldb::Env* penv; + + //! database options used + leveldb::Options options; + + //! options used when reading from the database + leveldb::ReadOptions readoptions; + + //! options used when iterating over values of the database + leveldb::ReadOptions iteroptions; + + //! options used when writing to the database + leveldb::WriteOptions writeoptions; + + //! options used when sync writing to the database + leveldb::WriteOptions syncoptions; + + //! the database itself + leveldb::DB* pdb; + + //! a key used for optional XOR-obfuscation of the database + std::vector<unsigned char> obfuscate_key; + + //! the key under which the obfuscation key is stored + static const std::string OBFUSCATE_KEY_KEY; + + //! the length of the obfuscate key in number of bytes + static const unsigned int OBFUSCATE_KEY_NUM_BYTES; + + std::vector<unsigned char> CreateObfuscateKey() const; + +public: + /** + * @param[in] path Location in the filesystem where leveldb data will be stored. + * @param[in] nCacheSize Configures various leveldb cache settings. + * @param[in] fMemory If true, use leveldb's memory environment. + * @param[in] fWipe If true, remove all existing data. + * @param[in] obfuscate If true, store data obfuscated via simple XOR. If false, XOR + * with a zero'd byte array. + */ + CDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false, bool obfuscate = false); + ~CDBWrapper(); + + template <typename K, typename V> + bool Read(const K& key, V& value) const throw(dbwrapper_error) + { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(ssKey.GetSerializeSize(key)); + ssKey << key; + leveldb::Slice slKey(&ssKey[0], ssKey.size()); + + std::string strValue; + leveldb::Status status = pdb->Get(readoptions, slKey, &strValue); + if (!status.ok()) { + if (status.IsNotFound()) + return false; + LogPrintf("LevelDB read failure: %s\n", status.ToString()); + HandleError(status); + } + try { + CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); + ssValue.Xor(obfuscate_key); + ssValue >> value; + } catch (const std::exception&) { + return false; + } + return true; + } + + template <typename K, typename V> + bool Write(const K& key, const V& value, bool fSync = false) throw(dbwrapper_error) + { + CDBBatch batch(&obfuscate_key); + batch.Write(key, value); + return WriteBatch(batch, fSync); + } + + template <typename K> + bool Exists(const K& key) const throw(dbwrapper_error) + { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(ssKey.GetSerializeSize(key)); + ssKey << key; + leveldb::Slice slKey(&ssKey[0], ssKey.size()); + + std::string strValue; + leveldb::Status status = pdb->Get(readoptions, slKey, &strValue); + if (!status.ok()) { + if (status.IsNotFound()) + return false; + LogPrintf("LevelDB read failure: %s\n", status.ToString()); + HandleError(status); + } + return true; + } + + template <typename K> + bool Erase(const K& key, bool fSync = false) throw(dbwrapper_error) + { + CDBBatch batch(&obfuscate_key); + batch.Erase(key); + return WriteBatch(batch, fSync); + } + + bool WriteBatch(CDBBatch& batch, bool fSync = false) throw(dbwrapper_error); + + // not available for LevelDB; provide for compatibility with BDB + bool Flush() + { + return true; + } + + bool Sync() throw(dbwrapper_error) + { + CDBBatch batch(&obfuscate_key); + return WriteBatch(batch, true); + } + + CDBIterator *NewIterator() + { + return new CDBIterator(pdb->NewIterator(iteroptions), &obfuscate_key); + } + + /** + * Return true if the database managed by this class contains no entries. + */ + bool IsEmpty(); + + /** + * Accessor for obfuscate_key. + */ + const std::vector<unsigned char>& GetObfuscateKey() const; + + /** + * Return the obfuscate_key as a hex-formatted string. + */ + std::string GetObfuscateKeyHex() const; + +}; + +#endif // BITCOIN_DBWRAPPER_H + diff --git a/src/eccryptoverify.cpp b/src/eccryptoverify.cpp deleted file mode 100644 index e894e1122c..0000000000 --- a/src/eccryptoverify.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// 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 deleted file mode 100644 index c67c1e44fc..0000000000 --- a/src/eccryptoverify.h +++ /dev/null @@ -1,21 +0,0 @@ -// 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 deleted file mode 100644 index f94bc954fd..0000000000 --- a/src/ecwrapper.cpp +++ /dev/null @@ -1,218 +0,0 @@ -// 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 { - -class ecgroup_order -{ -public: - static const EC_GROUP* get() - { - static const ecgroup_order wrapper; - return wrapper.pgroup; - } - -private: - ecgroup_order() - : pgroup(EC_GROUP_new_by_curve_name(NID_secp256k1)) - { - } - - ~ecgroup_order() - { - EC_GROUP_free(pgroup); - } - - EC_GROUP* pgroup; -}; - -/** - * Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields - * recid selects which key is recovered - * 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(); - assert(pkey != NULL); - int result = EC_KEY_set_group(pkey, ecgroup_order::get()); - assert(result); -} - -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) { - if (vchSig.empty()) - return false; - - // New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first. - unsigned char *norm_der = NULL; - ECDSA_SIG *norm_sig = ECDSA_SIG_new(); - const unsigned char* sigptr = &vchSig[0]; - assert(norm_sig); - if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL) - { - /* As of OpenSSL 1.0.0p d2i_ECDSA_SIG frees and nulls the pointer on - * error. But OpenSSL's own use of this function redundantly frees the - * result. As ECDSA_SIG_free(NULL) is a no-op, and in the absence of a - * clear contract for the function behaving the same way is more - * conservative. - */ - ECDSA_SIG_free(norm_sig); - return false; - } - int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der); - ECDSA_SIG_free(norm_sig); - if (derlen <= 0) - return false; - - // -1 = error, 0 = bad sig, 1 = good - bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1; - OPENSSL_free(norm_der); - return ret; -} - -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() -{ - const EC_GROUP *pgroup = ecgroup_order::get(); - if(pgroup == NULL) - return false; - // TODO Is there more EC functionality that could be missing? - return true; -} diff --git a/src/ecwrapper.h b/src/ecwrapper.h deleted file mode 100644 index efb6cd18a7..0000000000 --- a/src/ecwrapper.h +++ /dev/null @@ -1,40 +0,0 @@ -// 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 9711293e38..7f3cf1a1fa 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2014 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/hash.h b/src/hash.h index 0771555623..97955c8d5a 100644 --- a/src/hash.h +++ b/src/hash.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -8,6 +8,7 @@ #include "crypto/ripemd160.h" #include "crypto/sha256.h" +#include "prevector.h" #include "serialize.h" #include "uint256.h" #include "version.h" @@ -118,6 +119,13 @@ inline uint160 Hash160(const std::vector<unsigned char>& vch) return Hash160(vch.begin(), vch.end()); } +/** Compute the 160-bit hash of a vector. */ +template<unsigned int N> +inline uint160 Hash160(const prevector<N, unsigned char>& vch) +{ + return Hash160(vch.begin(), vch.end()); +} + /** A writer stream (for serialization) that computes a 256-bit hash. */ class CHashWriter { diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 98ac750bb1..1466dc0cbf 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -10,8 +10,12 @@ #include "util.h" #include "utilstrencodings.h" #include "ui_interface.h" +#include "crypto/hmac_sha256.h" +#include <stdio.h> +#include "utilstrencodings.h" #include <boost/algorithm/string.hpp> // boost::trim +#include <boost/foreach.hpp> //BOOST_FOREACH /** Simple one-shot callback timer to be used by the RPC mechanism to e.g. * re-lock the wellet. @@ -72,6 +76,50 @@ static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const Uni req->WriteReply(nStatus, strReply); } +//This function checks username and password against -rpcauth +//entries from config file. +static bool multiUserAuthorized(std::string strUserPass) +{ + if (strUserPass.find(":") == std::string::npos) { + return false; + } + std::string strUser = strUserPass.substr(0, strUserPass.find(":")); + std::string strPass = strUserPass.substr(strUserPass.find(":") + 1); + + if (mapMultiArgs.count("-rpcauth") > 0) { + //Search for multi-user login/pass "rpcauth" from config + BOOST_FOREACH(std::string strRPCAuth, mapMultiArgs["-rpcauth"]) + { + std::vector<std::string> vFields; + boost::split(vFields, strRPCAuth, boost::is_any_of(":$")); + if (vFields.size() != 3) { + //Incorrect formatting in config file + continue; + } + + std::string strName = vFields[0]; + if (!TimingResistantEqual(strName, strUser)) { + continue; + } + + std::string strSalt = vFields[1]; + std::string strHash = vFields[2]; + + unsigned int KEY_SIZE = 32; + unsigned char *out = new unsigned char[KEY_SIZE]; + + CHMAC_SHA256(reinterpret_cast<const unsigned char*>(strSalt.c_str()), strSalt.size()).Write(reinterpret_cast<const unsigned char*>(strPass.c_str()), strPass.size()).Finalize(out); + std::vector<unsigned char> hexvec(out, out+KEY_SIZE); + std::string strHashFromPass = HexStr(hexvec); + + if (TimingResistantEqual(strHashFromPass, strHash)) { + return true; + } + } + } + return false; +} + static bool RPCAuthorized(const std::string& strAuth) { if (strRPCUserColonPass.empty()) // Belt-and-suspenders measure if InitRPCAuthentication was not called @@ -81,7 +129,12 @@ static bool RPCAuthorized(const std::string& strAuth) std::string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64); std::string strUserPass = DecodeBase64(strUserPass64); - return TimingResistantEqual(strUserPass, strRPCUserColonPass); + + //Check if authorized under single-user field + if (TimingResistantEqual(strUserPass, strRPCUserColonPass)) { + return true; + } + return multiUserAuthorized(strUserPass); } static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) @@ -157,6 +210,7 @@ static bool InitRPCAuthentication() return false; } } else { + LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcuser for rpcauth auth generation."); strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; } return true; @@ -172,7 +226,7 @@ bool StartHTTPRPC() assert(EventBase()); httpRPCTimerInterface = new HTTPRPCTimerInterface(EventBase()); - RPCRegisterTimerInterface(httpRPCTimerInterface); + RPCSetTimerInterface(httpRPCTimerInterface); return true; } @@ -186,7 +240,7 @@ void StopHTTPRPC() LogPrint("rpc", "Stopping HTTP RPC server\n"); UnregisterHTTPHandler("/", true); if (httpRPCTimerInterface) { - RPCUnregisterTimerInterface(httpRPCTimerInterface); + RPCUnsetTimerInterface(httpRPCTimerInterface); delete httpRPCTimerInterface; httpRPCTimerInterface = 0; } diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 0a7f903e9f..91518d7c5f 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -38,6 +38,9 @@ #include <boost/foreach.hpp> #include <boost/scoped_ptr.hpp> +/** Maximum size of http request (request line + headers) */ +static const size_t MAX_HEADERS_SIZE = 8192; + /** HTTP request work item */ class HTTPWorkItem : public HTTPClosure { @@ -362,6 +365,10 @@ static void HTTPWorkQueueRun(WorkQueue<HTTPClosure>* queue) /** libevent event log callback */ static void libevent_log_cb(int severity, const char *msg) { +#ifndef EVENT_LOG_WARN +// EVENT_LOG_WARN was added in 2.0.19; but before then _EVENT_LOG_WARN existed. +# define EVENT_LOG_WARN _EVENT_LOG_WARN +#endif if (severity >= EVENT_LOG_WARN) // Log warn messages and higher without debug category LogPrintf("libevent: %s\n", msg); else @@ -414,6 +421,7 @@ bool InitHTTPServer() } evhttp_set_timeout(http, GetArg("-rpcservertimeout", DEFAULT_HTTP_SERVER_TIMEOUT)); + evhttp_set_max_headers_size(http, MAX_HEADERS_SIZE); evhttp_set_max_body_size(http, MAX_SIZE); evhttp_set_gencb(http, http_request_cb, NULL); @@ -434,15 +442,17 @@ bool InitHTTPServer() return true; } -bool StartHTTPServer(boost::thread_group& threadGroup) +boost::thread threadHTTP; + +bool StartHTTPServer() { LogPrint("http", "Starting HTTP server\n"); int rpcThreads = std::max((long)GetArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L); LogPrintf("HTTP: starting %d worker threads\n", rpcThreads); - threadGroup.create_thread(boost::bind(&ThreadHTTP, eventBase, eventHTTP)); + threadHTTP = boost::thread(boost::bind(&ThreadHTTP, eventBase, eventHTTP)); for (int i = 0; i < rpcThreads; i++) - threadGroup.create_thread(boost::bind(&HTTPWorkQueueRun, workQueue)); + boost::thread(boost::bind(&HTTPWorkQueueRun, workQueue)); return true; } @@ -457,13 +467,6 @@ void InterruptHTTPServer() // Reject requests on current connections evhttp_set_gencb(eventHTTP, http_reject_request_cb, NULL); } - if (eventBase) { - // Force-exit event loop after predefined time - struct timeval tv; - tv.tv_sec = 10; - tv.tv_usec = 0; - event_base_loopexit(eventBase, &tv); - } if (workQueue) workQueue->Interrupt(); } @@ -476,6 +479,24 @@ void StopHTTPServer() workQueue->WaitExit(); delete workQueue; } + if (eventBase) { + LogPrint("http", "Waiting for HTTP event thread to exit\n"); + // Give event loop a few seconds to exit (to send back last RPC responses), then break it + // Before this was solved with event_base_loopexit, but that didn't work as expected in + // at least libevent 2.0.21 and always introduced a delay. In libevent + // master that appears to be solved, so in the future that solution + // could be used again (if desirable). + // (see discussion in https://github.com/bitcoin/bitcoin/pull/6990) +#if BOOST_VERSION >= 105000 + if (!threadHTTP.try_join_for(boost::chrono::milliseconds(2000))) { +#else + if (!threadHTTP.timed_join(boost::posix_time::milliseconds(2000))) { +#endif + LogPrintf("HTTP event loop did not exit within allotted time, sending loopbreak\n"); + event_base_loopbreak(eventBase); + threadHTTP.join(); + } + } if (eventHTTP) { evhttp_free(eventHTTP); eventHTTP = 0; @@ -484,6 +505,7 @@ void StopHTTPServer() event_base_free(eventBase); eventBase = 0; } + LogPrint("http", "Stopped HTTP server\n"); } struct event_base* EventBase() diff --git a/src/httpserver.h b/src/httpserver.h index b377dc19fc..20a119cc5c 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -28,7 +28,7 @@ bool InitHTTPServer(); * This is separate from InitHTTPServer to give users race-condition-free time * to register their handlers between InitHTTPServer and StartHTTPServer. */ -bool StartHTTPServer(boost::thread_group& threadGroup); +bool StartHTTPServer(); /** Interrupt HTTP server threads */ void InterruptHTTPServer(); /** Stop HTTP server */ diff --git a/src/init.cpp b/src/init.cpp index a079dce5bc..374e756abd 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -25,9 +25,11 @@ #include "policy/policy.h" #include "rpcserver.h" #include "script/standard.h" +#include "script/sigcache.h" #include "scheduler.h" #include "txdb.h" #include "txmempool.h" +#include "torcontrol.h" #include "ui_interface.h" #include "util.h" #include "utilmoneystr.h" @@ -64,6 +66,10 @@ using namespace std; CWallet* pwalletMain = NULL; #endif bool fFeeEstimatesInitialized = false; +static const bool DEFAULT_PROXYRANDOMIZE = true; +static const bool DEFAULT_REST_ENABLE = false; +static const bool DEFAULT_DISABLE_SAFEMODE = false; +static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; #if ENABLE_ZMQ static CZMQNotificationInterface* pzmqNotificationInterface = NULL; @@ -152,6 +158,7 @@ public: static CCoinsViewDB *pcoinsdbview = NULL; static CCoinsViewErrorCatcher *pcoinscatcher = NULL; +static boost::scoped_ptr<ECCVerifyHandle> globalVerifyHandle; void Interrupt(boost::thread_group& threadGroup) { @@ -159,6 +166,7 @@ void Interrupt(boost::thread_group& threadGroup) InterruptHTTPRPC(); InterruptRPC(); InterruptREST(); + InterruptTorControl(); threadGroup.interrupt_all(); } @@ -187,6 +195,7 @@ void Shutdown() #endif GenerateBitcoins(false, 0, Params()); StopNode(); + StopTorControl(); UnregisterNodeSignals(GetNodeSignals()); if (fFeeEstimatesInitialized) @@ -222,7 +231,6 @@ void Shutdown() #if ENABLE_ZMQ if (pzmqNotificationInterface) { UnregisterValidationInterface(pzmqNotificationInterface); - pzmqNotificationInterface->Shutdown(); delete pzmqNotificationInterface; pzmqNotificationInterface = NULL; } @@ -240,6 +248,7 @@ void Shutdown() delete pwalletMain; pwalletMain = NULL; #endif + globalVerifyHandle.reset(); ECC_Stop(); LogPrintf("%s: done\n", __func__); } @@ -291,7 +300,7 @@ void OnRPCPreCommand(const CRPCCommand& cmd) { // Observe safe mode string strWarning = GetWarnings("rpc"); - if (strWarning != "" && !GetBoolArg("-disablesafemode", false) && + if (strWarning != "" && !GetBoolArg("-disablesafemode", DEFAULT_DISABLE_SAFEMODE) && !cmd.okSafeMode) throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning); } @@ -307,9 +316,11 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-alerts", strprintf(_("Receive and display P2P network alerts (default: %u)"), DEFAULT_ALERTS)); strUsage += HelpMessageOpt("-alertnotify=<cmd>", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)")); strUsage += HelpMessageOpt("-blocknotify=<cmd>", _("Execute command when the best block changes (%s in cmd is replaced by block hash)")); - strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288)); - strUsage += HelpMessageOpt("-checklevel=<n>", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3)); - strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf")); + if (showDebug) + strUsage += HelpMessageOpt("-blocksonly", strprintf(_("Whether to operate in a blocks only mode (default: %u)"), DEFAULT_BLOCKSONLY)); + strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), DEFAULT_CHECKBLOCKS)); + strUsage += HelpMessageOpt("-checklevel=<n>", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), DEFAULT_CHECKLEVEL)); + strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME)); if (mode == HMM_BITCOIND) { #ifndef WIN32 @@ -318,12 +329,14 @@ std::string HelpMessage(HelpMessageMode mode) } strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory")); strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache)); - strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup")); + strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file on startup")); strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS)); + strUsage += HelpMessageOpt("-maxmempool=<n>", strprintf(_("Keep the transaction memory pool below <n> megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE)); + strUsage += HelpMessageOpt("-mempoolexpiry=<n>", strprintf(_("Do not keep transactions in the mempool longer than <n> hours (default: %u)"), DEFAULT_MEMPOOL_EXPIRY)); strUsage += HelpMessageOpt("-par=<n>", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS)); #ifndef WIN32 - strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid")); + strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), BITCOIN_PID_FILENAME)); #endif strUsage += HelpMessageOpt("-prune=<n>", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. " "Warning: Reverting this setting requires re-downloading the entire blockchain. " @@ -332,31 +345,37 @@ std::string HelpMessage(HelpMessageMode mode) #ifndef WIN32 strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)")); #endif - strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0)); + strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), DEFAULT_TXINDEX)); strUsage += HelpMessageGroup(_("Connection options:")); strUsage += HelpMessageOpt("-addnode=<ip>", _("Add a node to connect to and attempt to keep the connection open")); - strUsage += HelpMessageOpt("-banscore=<n>", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100)); - strUsage += HelpMessageOpt("-bantime=<n>", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400)); + strUsage += HelpMessageOpt("-banscore=<n>", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), DEFAULT_BANSCORE_THRESHOLD)); + strUsage += HelpMessageOpt("-bantime=<n>", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), DEFAULT_MISBEHAVING_BANTIME)); strUsage += HelpMessageOpt("-bind=<addr>", _("Bind to given address and always listen on it. Use [host]:port notation for IPv6")); strUsage += HelpMessageOpt("-connect=<ip>", _("Connect only to the specified node(s)")); strUsage += HelpMessageOpt("-discover", _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)")); - strUsage += HelpMessageOpt("-dns", _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)")); + strUsage += HelpMessageOpt("-dns", _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + strprintf(_("(default: %u)"), DEFAULT_NAME_LOOKUP)); strUsage += HelpMessageOpt("-dnsseed", _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)")); strUsage += HelpMessageOpt("-externalip=<ip>", _("Specify your own public address")); - strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0)); + strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), DEFAULT_FORCEDNSSEED)); strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)")); + strUsage += HelpMessageOpt("-listenonion", strprintf(_("Automatically create Tor hidden service (default: %d)"), DEFAULT_LISTEN_ONION)); strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), DEFAULT_MAX_PEER_CONNECTIONS)); - strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000)); - strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000)); + strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), DEFAULT_MAXRECEIVEBUFFER)); + strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), DEFAULT_MAXSENDBUFFER)); strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy")); strUsage += HelpMessageOpt("-onlynet=<net>", _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)")); - strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), 1)); - strUsage += HelpMessageOpt("-port=<port>", strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 8333, 18333)); + strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG)); + strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with bloom filters (default: %u)"), 1)); + if (showDebug) + strUsage += HelpMessageOpt("-enforcenodebloom", strprintf("Enforce minimum protocol version to limit use of bloom filters (default: %u)", 0)); + strUsage += HelpMessageOpt("-port=<port>", strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), Params(CBaseChainParams::MAIN).GetDefaultPort(), Params(CBaseChainParams::TESTNET).GetDefaultPort())); strUsage += HelpMessageOpt("-proxy=<ip:port>", _("Connect through SOCKS5 proxy")); - strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), 1)); + strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), DEFAULT_PROXYRANDOMIZE)); strUsage += HelpMessageOpt("-seednode=<ip>", _("Connect to a node to retrieve peer addresses, and disconnect")); strUsage += HelpMessageOpt("-timeout=<n>", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT)); + strUsage += HelpMessageOpt("-torcontrol=<ip>:<port>", strprintf(_("Tor control port to use if onion listening enabled (default: %s)"), DEFAULT_TOR_CONTROL)); + strUsage += HelpMessageOpt("-torpassword=<pass>", _("Tor control port password (default: empty)")); #ifdef USE_UPNP #if USE_UPNP strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening and no -proxy)")); @@ -367,26 +386,29 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6")); strUsage += HelpMessageOpt("-whitelist=<netmask>", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway")); + strUsage += HelpMessageOpt("-whitelistalwaysrelay", strprintf(_("Always relay transactions received from whitelisted peers (default: %d)"), DEFAULT_WHITELISTALWAYSRELAY)); + strUsage += HelpMessageOpt("-maxuploadtarget=<n>", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET)); #ifdef ENABLE_WALLET strUsage += HelpMessageGroup(_("Wallet options:")); strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); - strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100)); - if (showDebug) - strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)", - CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), DEFAULT_KEYPOOL_SIZE)); + strUsage += HelpMessageOpt("-fallbackfee=<amt>", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE))); + strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE))); strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); - strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup")); - strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup")); - strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0)); - strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1)); + strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup")); + strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat on startup")); + strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); + strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"), - CURRENCY_UNIT, FormatMoney(maxTxFee))); - strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup")); + CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE))); + strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat")); - strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), true)); + strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); @@ -395,64 +417,71 @@ std::string HelpMessage(HelpMessageMode mode) #if ENABLE_ZMQ strUsage += HelpMessageGroup(_("ZeroMQ notification options:")); strUsage += HelpMessageOpt("-zmqpubhashblock=<address>", _("Enable publish hash block in <address>")); - strUsage += HelpMessageOpt("-zmqpubhashtransaction=<address>", _("Enable publish hash transaction in <address>")); + strUsage += HelpMessageOpt("-zmqpubhashtx=<address>", _("Enable publish hash transaction in <address>")); strUsage += HelpMessageOpt("-zmqpubrawblock=<address>", _("Enable publish raw block in <address>")); - strUsage += HelpMessageOpt("-zmqpubrawtransaction=<address>", _("Enable publish raw transaction in <address>")); + strUsage += HelpMessageOpt("-zmqpubrawtx=<address>", _("Enable publish raw transaction in <address>")); #endif strUsage += HelpMessageGroup(_("Debugging/Testing options:")); if (showDebug) { - strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", 1)); - strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)", 100)); - strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", 0)); - strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", 0)); + strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED)); +#ifdef ENABLE_WALLET + strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); +#endif + strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", DEFAULT_DISABLE_SAFEMODE)); + strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", DEFAULT_TESTSAFEMODE)); strUsage += HelpMessageOpt("-dropmessagestest=<n>", "Randomly drop 1 of every <n> network messages"); strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", "Randomly fuzz 1 of every <n> network messages"); - strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", 1)); - strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0)); +#ifdef ENABLE_WALLET + strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET)); +#endif + strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", DEFAULT_STOPAFTERBLOCKIMPORT)); strUsage += HelpMessageOpt("-limitancestorcount=<n>", strprintf("Do not accept transactions if number of in-mempool ancestors is <n> or more (default: %u)", DEFAULT_ANCESTOR_LIMIT)); strUsage += HelpMessageOpt("-limitancestorsize=<n>", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds <n> kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT)); strUsage += HelpMessageOpt("-limitdescendantcount=<n>", strprintf("Do not accept transactions if any ancestor would have <n> or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT)); strUsage += HelpMessageOpt("-limitdescendantsize=<n>", strprintf("Do not accept transactions if any ancestor would have more than <n> kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT)); } - string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, mempoolrej, net, proxy, prune, http, libevent"; // Don't translate these and qt below + string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, mempoolrej, net, proxy, prune, http, libevent, tor, zmq"; // Don't translate these and qt below if (mode == HMM_BITCOIN_QT) debugCategories += ", qt"; strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " + _("If <category> is not supplied or if <category> = 1, output all debugging information.") + _("<category> can be:") + " " + debugCategories + "."); - strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0)); - strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1)); + strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), DEFAULT_GENERATE)); + strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), DEFAULT_GENERATE_THREADS)); strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)")); - strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0)); - strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1)); + strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), DEFAULT_LOGIPS)); + strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), DEFAULT_LOGTIMESTAMPS)); if (showDebug) { - strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)", 15)); - strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", 1)); - strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> entries (default: %u)", 50000)); + strUsage += HelpMessageOpt("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS)); + strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)", DEFAULT_LIMITFREERELAY)); + strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", DEFAULT_RELAYPRIORITY)); + strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE)); } - strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for relaying (default: %s)"), - CURRENCY_UNIT, FormatMoney(::minRelayTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE))); strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file")); if (showDebug) { - strUsage += HelpMessageOpt("-printpriority", strprintf("Log transaction priority and fee per kB when mining blocks (default: %u)", 0)); - strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", 1)); - strUsage += HelpMessageOpt("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. " - "This is intended for regression testing tools and app development."); + strUsage += HelpMessageOpt("-printpriority", strprintf("Log transaction priority and fee per kB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY)); +#ifdef ENABLE_WALLET + strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB)); +#endif } strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)")); - strUsage += HelpMessageOpt("-testnet", _("Use the test network")); + + AppendParamsHelpMessages(strUsage, showDebug); strUsage += HelpMessageGroup(_("Node relay options:")); if (showDebug) strUsage += HelpMessageOpt("-acceptnonstdtxn", strprintf("Relay and mine \"non-standard\" transactions (%sdefault: %u)", "testnet/regtest only; ", !Params(CBaseChainParams::TESTNET).RequireStandard())); - strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1)); + strUsage += HelpMessageOpt("-bytespersigop", strprintf(_("Minimum bytes per sigop in transactions we relay and mine (default: %u)"), DEFAULT_BYTES_PER_SIGOP)); + strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), DEFAULT_ACCEPT_DATACARRIER)); strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY)); strUsage += HelpMessageGroup(_("Block creation options:")); - strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), 0)); + strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), DEFAULT_BLOCK_MIN_SIZE)); strUsage += HelpMessageOpt("-blockmaxsize=<n>", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockprioritysize=<n>", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); if (showDebug) @@ -460,11 +489,12 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageGroup(_("RPC server options:")); strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands")); - strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), 0)); + strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), DEFAULT_REST_ENABLE)); strUsage += HelpMessageOpt("-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)")); strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections")); - strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332)); + strUsage += HelpMessageOpt("-rpcauth=<userpw>", _("Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times")); + strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), BaseParams(CBaseChainParams::MAIN).RPCPort(), BaseParams(CBaseChainParams::TESTNET).RPCPort())); strUsage += HelpMessageOpt("-rpcallowip=<ip>", _("Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times")); strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS)); if (showDebug) { @@ -472,27 +502,12 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT)); } - if (mode == HMM_BITCOIN_QT) - { - strUsage += HelpMessageGroup(_("UI Options:")); - if (showDebug) { - strUsage += HelpMessageOpt("-allowselfsignedrootcertificates", "Allow self signed root certificates (default: 0)"); - } - strUsage += HelpMessageOpt("-choosedatadir", _("Choose data directory on startup (default: 0)")); - strUsage += HelpMessageOpt("-lang=<lang>", _("Set language, for example \"de_DE\" (default: system locale)")); - strUsage += HelpMessageOpt("-min", _("Start minimized")); - strUsage += HelpMessageOpt("-rootcertificates=<file>", _("Set SSL root certificates for payment request (default: -system-)")); - strUsage += HelpMessageOpt("-splash", _("Show splash screen on startup (default: 1)")); - if (showDebug) { - strUsage += HelpMessageOpt("-uiplatform", "Select platform to customize UI for (one of windows, macosx, other; default: platform compiled on)"); - } - } - return strUsage; } std::string LicenseInfo() { + // todo: remove urls from translations on next change return FormatParagraph(strprintf(_("Copyright (C) 2009-%i The Bitcoin Core Developers"), COPYRIGHT_YEAR)) + "\n" + "\n" + FormatParagraph(_("This is experimental software.")) + "\n" + @@ -503,11 +518,14 @@ std::string LicenseInfo() "\n"; } -static void BlockNotifyCallback(const uint256& hashNewTip) +static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex) { + if (initialSync || !pBlockIndex) + return; + std::string strCmd = GetArg("-blocknotify", ""); - boost::replace_all(strCmd, "%s", hashNewTip.GetHex()); + boost::replace_all(strCmd, "%s", pBlockIndex->GetBlockHash().GetHex()); boost::thread t(runCommand, strCmd); // thread runs free } @@ -569,6 +587,7 @@ void CleanupBlockRevFiles() void ThreadImport(std::vector<boost::filesystem::path> vImportFiles) { + const CChainParams& chainparams = Params(); RenameThread("bitcoin-loadblk"); // -reindex if (fReindex) { @@ -582,14 +601,14 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles) if (!file) break; // This error is logged in OpenBlockFile LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile); - LoadExternalBlockFile(file, &pos); + LoadExternalBlockFile(chainparams, file, &pos); nFile++; } pblocktree->WriteReindexing(false); fReindex = false; LogPrintf("Reindexing finished\n"); // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked): - InitBlockIndex(); + InitBlockIndex(chainparams); } // hardcoded $DATADIR/bootstrap.dat @@ -600,7 +619,7 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles) CImportingNow imp; boost::filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old"; LogPrintf("Importing bootstrap.dat...\n"); - LoadExternalBlockFile(file); + LoadExternalBlockFile(chainparams, file); RenameOver(pathBootstrap, pathBootstrapOld); } else { LogPrintf("Warning: Could not open bootstrap file %s\n", pathBootstrap.string()); @@ -613,13 +632,13 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles) if (file) { CImportingNow imp; LogPrintf("Importing blocks file %s...\n", path.string()); - LoadExternalBlockFile(file); + LoadExternalBlockFile(chainparams, file); } else { LogPrintf("Warning: Could not open blocks file %s\n", path.string()); } } - if (GetBoolArg("-stopafterblockimport", false)) { + if (GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) { LogPrintf("Stopping after block import\n"); StartShutdown(); } @@ -632,8 +651,7 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles) bool InitSanityCheck(void) { if(!ECC_InitSanityCheck()) { - InitError("OpenSSL appears to lack support for elliptic curve cryptography. For more " - "information, visit https://en.bitcoin.it/wiki/OpenSSL_and_EC_Libraries"); + InitError("Elliptic curve cryptography sanity check failure. Aborting."); return false; } if (!glibc_sanity_test() || !glibcxx_sanity_test()) @@ -652,13 +670,108 @@ bool AppInitServers(boost::thread_group& threadGroup) return false; if (!StartHTTPRPC()) return false; - if (GetBoolArg("-rest", false) && !StartREST()) + if (GetBoolArg("-rest", DEFAULT_REST_ENABLE) && !StartREST()) return false; - if (!StartHTTPServer(threadGroup)) + if (!StartHTTPServer()) return false; return true; } +// Parameter interaction based on rules +void InitParameterInteraction() +{ + // 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("%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("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__); + if (SoftSetBoolArg("-listen", false)) + 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("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__); + // to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1 + // to listen locally, so don't rely on this happening through -listen below. + if (SoftSetBoolArg("-upnp", false)) + LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__); + // to protect privacy, do not discover addresses by default + if (SoftSetBoolArg("-discover", false)) + LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__); + } + + if (!GetBoolArg("-listen", DEFAULT_LISTEN)) { + // do not map ports or try to retrieve public IP when not listening (pointless) + if (SoftSetBoolArg("-upnp", false)) + LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__); + if (SoftSetBoolArg("-discover", false)) + LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__); + if (SoftSetBoolArg("-listenonion", false)) + LogPrintf("%s: parameter interaction: -listen=0 -> setting -listenonion=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("%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("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); + } + + // -zapwallettx implies a rescan + if (GetBoolArg("-zapwallettxes", false)) { + if (SoftSetBoolArg("-rescan", true)) + LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__); + } + + // disable walletbroadcast and whitelistalwaysrelay in blocksonly mode + if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) { + if (SoftSetBoolArg("-whitelistalwaysrelay", false)) + LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistalwaysrelay=0\n", __func__); +#ifdef ENABLE_WALLET + if (SoftSetBoolArg("-walletbroadcast", false)) + LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__); +#endif + } +} + +static std::string ResolveErrMsg(const char * const optname, const std::string& strBind) +{ + return strprintf(_("Cannot resolve -%s address: '%s'"), optname, strBind); +} + +static std::string AmountErrMsg(const char * const optname, const std::string& strValue) +{ + return strprintf(_("Invalid amount for -%s=<amount>: '%s'"), optname, strValue); +} + +void InitLogging() +{ + fPrintToConsole = GetBoolArg("-printtoconsole", false); + fLogTimestamps = GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); + fLogTimeMicros = GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); + fLogIPs = GetBoolArg("-logips", DEFAULT_LOGIPS); + + LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + LogPrintf("Bitcoin version %s (%s)\n", FormatFullVersion(), CLIENT_DATE); +} + /** Initialize bitcoin. * @pre Parameters should be parsed and config file should be read. */ @@ -689,13 +802,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) #endif if (!SetupNetworking()) - return InitError("Error: Initializing networking failed"); + return InitError("Initializing networking failed"); #ifndef WIN32 if (GetBoolArg("-sysperms", false)) { #ifdef ENABLE_WALLET if (!GetBoolArg("-disablewallet", false)) - return InitError("Error: -sysperms is not allowed in combination with enabled wallet functionality"); + return InitError("-sysperms is not allowed in combination with enabled wallet functionality"); #endif } else { umask(077); @@ -723,75 +836,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 2: parameter interactions const CChainParams& chainparams = Params(); - // Set this early so that parameter interactions go to console - fPrintToConsole = GetBoolArg("-printtoconsole", false); - fLogTimestamps = GetBoolArg("-logtimestamps", true); - fLogIPs = GetBoolArg("-logips", false); - - LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - LogPrintf("Bitcoin version %s (%s)\n", FormatFullVersion(), CLIENT_DATE); - - // when specifying an explicit binding address, you want to listen on it - // even when -connect or -proxy is specified - if (mapArgs.count("-bind")) { - if (SoftSetBoolArg("-listen", true)) - LogPrintf("%s: parameter interaction: -bind set -> setting -listen=1\n", __func__); - } - if (mapArgs.count("-whitebind")) { - if (SoftSetBoolArg("-listen", true)) - 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("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__); - if (SoftSetBoolArg("-listen", false)) - 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("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__); - // to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1 - // to listen locally, so don't rely on this happening through -listen below. - if (SoftSetBoolArg("-upnp", false)) - LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__); - // to protect privacy, do not discover addresses by default - if (SoftSetBoolArg("-discover", false)) - LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__); - } - - if (!GetBoolArg("-listen", DEFAULT_LISTEN)) { - // do not map ports or try to retrieve public IP when not listening (pointless) - if (SoftSetBoolArg("-upnp", false)) - LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__); - if (SoftSetBoolArg("-discover", false)) - 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("%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("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); - } - - // -zapwallettx implies a rescan - if (GetBoolArg("-zapwallettxes", false)) { - if (SoftSetBoolArg("-rescan", true)) - LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__); - } + // also see: InitParameterInteraction() // if using block pruning, then disable txindex if (GetArg("-prune", 0)) { - if (GetBoolArg("-txindex", false)) + if (GetBoolArg("-txindex", DEFAULT_TXINDEX)) return InitError(_("Prune mode is incompatible with -txindex.")); #ifdef ENABLE_WALLET if (GetBoolArg("-rescan", false)) { @@ -799,7 +848,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } #endif } - + // Make sure enough file descriptors are available int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1); int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); @@ -825,21 +874,30 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // Check for -debugnet if (GetBoolArg("-debugnet", false)) - InitWarning(_("Warning: Unsupported argument -debugnet ignored, use -debug=net.")); + InitWarning(_("Unsupported argument -debugnet ignored, use -debug=net.")); // Check for -socks - as this is a privacy risk to continue, exit here if (mapArgs.count("-socks")) - return InitError(_("Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.")); + return InitError(_("Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.")); // Check for -tor - as this is a privacy risk to continue, exit here if (GetBoolArg("-tor", false)) - return InitError(_("Error: Unsupported argument -tor found, use -onion.")); + return InitError(_("Unsupported argument -tor found, use -onion.")); if (GetBoolArg("-benchmark", false)) - InitWarning(_("Warning: Unsupported argument -benchmark ignored, use -debug=bench.")); + InitWarning(_("Unsupported argument -benchmark ignored, use -debug=bench.")); // Checkmempool and checkblockindex default to true in regtest mode - mempool.setSanityCheck(GetBoolArg("-checkmempool", chainparams.DefaultConsistencyChecks())); + int ratio = std::min<int>(std::max<int>(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); + if (ratio != 0) { + mempool.setSanityCheck(1.0 / ratio); + } fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks()); - fCheckpointsEnabled = GetBoolArg("-checkpoints", true); + fCheckpointsEnabled = GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED); + + // mempool limits + int64_t nMempoolSizeMax = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; + int64_t nMempoolSizeMin = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000 * 40; + if (nMempoolSizeMax < 0 || nMempoolSizeMax < nMempoolSizeMin) + return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(nMempoolSizeMin / 1000000.0))); // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS); @@ -886,12 +944,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0) ::minRelayTxFee = CFeeRate(n); else - return InitError(strprintf(_("Invalid amount for -minrelaytxfee=<amount>: '%s'"), mapArgs["-minrelaytxfee"])); + return InitError(AmountErrMsg("minrelaytxfee", mapArgs["-minrelaytxfee"])); } fRequireStandard = !GetBoolArg("-acceptnonstdtxn", !Params().RequireStandard()); if (Params().RequireStandard() && !fRequireStandard) return InitError(strprintf("acceptnonstdtxn is not currently supported for %s chain", chainparams.NetworkIDString())); + nBytesPerSigOp = GetArg("-bytespersigop", nBytesPerSigOp); #ifdef ENABLE_WALLET if (mapArgs.count("-mintxfee")) @@ -900,15 +959,24 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0) CWallet::minTxFee = CFeeRate(n); else - return InitError(strprintf(_("Invalid amount for -mintxfee=<amount>: '%s'"), mapArgs["-mintxfee"])); + return InitError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"])); + } + if (mapArgs.count("-fallbackfee")) + { + CAmount nFeePerK = 0; + if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK)) + return InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), mapArgs["-fallbackfee"])); + if (nFeePerK > nHighTransactionFeeWarning) + InitWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available.")); + CWallet::fallbackFee = CFeeRate(nFeePerK); } if (mapArgs.count("-paytxfee")) { CAmount nFeePerK = 0; if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK)) - return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"])); + return InitError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"])); if (nFeePerK > nHighTransactionFeeWarning) - InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); + InitWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); payTxFee = CFeeRate(nFeePerK, 1000); if (payTxFee < ::minRelayTxFee) { @@ -920,9 +988,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) { CAmount nMaxFee = 0; if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee)) - return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s'"), mapArgs["-maptxfee"])); + return InitError(AmountErrMsg("maxtxfee", mapArgs["-maptxfee"])); if (nMaxFee > nHighTransactionMaxFeeWarning) - InitWarning(_("Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.")); + InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); maxTxFee = nMaxFee; if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) { @@ -931,13 +999,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); - bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", true); - fSendFreeTransactions = GetBoolArg("-sendfreetransactions", false); + bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); + fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS); std::string strWalletFile = GetArg("-wallet", "wallet.dat"); #endif // ENABLE_WALLET - fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", true); + fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); + fAcceptDatacarrier = GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER); nMaxDatacarrierBytes = GetArg("-datacarriersize", nMaxDatacarrierBytes); fAlerts = GetBoolArg("-alerts", DEFAULT_ALERTS); @@ -952,6 +1021,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // Initialize elliptic curve code ECC_Start(); + globalVerifyHandle.reset(new ECCVerifyHandle()); // Sanity check if (!InitSanityCheck()) @@ -985,7 +1055,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (fPrintToDebugLog) OpenDebugLog(); +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); +#else + LogPrintf("Using OpenSSL version %s\n", OpenSSL_version(OPENSSL_VERSION)); +#endif + #ifdef ENABLE_WALLET LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0)); #endif @@ -1049,12 +1124,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) BOOST_FOREACH(string cmt, mapMultiArgs["-uacomment"]) { if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) - return InitError(strprintf("User Agent comment (%s) contains unsafe characters.", cmt)); + return InitError(strprintf(_("User Agent comment (%s) contains unsafe characters."), cmt)); uacomments.push_back(SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)); } strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments); if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) { - return InitError(strprintf("Total length of network version string %i exceeds maximum of %i characters. Reduce the number and/or size of uacomments.", + return InitError(strprintf(_("Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments."), strSubVersion.size(), MAX_SUBVERSION_LENGTH)); } @@ -1082,7 +1157,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } - bool proxyRandomize = GetBoolArg("-proxyrandomize", true); + bool proxyRandomize = GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE); // -proxy sets a proxy for all outgoing network traffic // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default std::string proxyArg = GetArg("-proxy", ""); @@ -1117,7 +1192,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // see Step 2: parameter interactions for more information about these fListen = GetBoolArg("-listen", DEFAULT_LISTEN); fDiscover = GetBoolArg("-discover", true); - fNameLookup = GetBoolArg("-dns", true); + fNameLookup = GetBoolArg("-dns", DEFAULT_NAME_LOOKUP); bool fBound = false; if (fListen) { @@ -1125,13 +1200,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-bind"]) { CService addrBind; if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) - return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind)); + return InitError(ResolveErrMsg("bind", strBind)); fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR)); } BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-whitebind"]) { CService addrBind; if (!Lookup(strBind.c_str(), addrBind, 0, false)) - return InitError(strprintf(_("Cannot resolve -whitebind address: '%s'"), strBind)); + return InitError(ResolveErrMsg("whitebind", strBind)); if (addrBind.GetPort() == 0) return InitError(strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind)); fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST)); @@ -1151,7 +1226,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-externalip"]) { CService addrLocal(strAddr, GetListenPort(), fNameLookup); if (!addrLocal.IsValid()) - return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr)); + return InitError(ResolveErrMsg("externalip", strAddr)); AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL); } } @@ -1163,10 +1238,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs); if (pzmqNotificationInterface) { - pzmqNotificationInterface->Initialize(); RegisterValidationInterface(pzmqNotificationInterface); } #endif + if (mapArgs.count("-maxuploadtarget")) { + CNode::SetMaxOutboundTarget(GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET)*1024*1024); + } // ********************************************************* Step 7: load block chain @@ -1204,7 +1281,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greated than nMaxDbcache int64_t nBlockTreeDBCache = nTotalCache / 8; - if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", false)) + if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", DEFAULT_TXINDEX)) nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB nTotalCache -= nBlockTreeDBCache; int64_t nCoinDBCache = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache @@ -1254,13 +1331,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) 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) - if (!InitBlockIndex()) { + if (!InitBlockIndex(chainparams)) { strLoadError = _("Error initializing block database"); break; } // Check for changed -txindex state - if (fTxIndex != GetBoolArg("-txindex", false)) { + if (fTxIndex != GetBoolArg("-txindex", DEFAULT_TXINDEX)) { strLoadError = _("You need to rebuild the database using -reindex to change -txindex"); break; } @@ -1273,9 +1350,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } uiInterface.InitMessage(_("Verifying blocks...")); - if (fHavePruned && GetArg("-checkblocks", 288) > MIN_BLOCKS_TO_KEEP) { + if (fHavePruned && GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) { LogPrintf("Prune: pruned datadir may not have more than %d blocks; -checkblocks=%d may fail\n", - MIN_BLOCKS_TO_KEEP, GetArg("-checkblocks", 288)); + MIN_BLOCKS_TO_KEEP, GetArg("-checkblocks", DEFAULT_CHECKBLOCKS)); } { @@ -1289,8 +1366,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } - if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", 3), - GetArg("-checkblocks", 288))) { + if (!CVerifyDB().VerifyDB(chainparams, pcoinsdbview, GetArg("-checklevel", DEFAULT_CHECKLEVEL), + GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) { strLoadError = _("Corrupted block database detected"); break; } @@ -1375,9 +1452,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n"; else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) { - string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data" + InitWarning(_("Error reading wallet.dat! All keys read correctly, but transaction data" " or address book entries might be missing or incorrect.")); - InitWarning(msg); } else if (nLoadWalletRet == DB_TOO_NEW) strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin Core") << "\n"; @@ -1487,7 +1563,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } } - pwalletMain->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", true)); + pwalletMain->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST)); } // (!fDisableWallet) #else // ENABLE_WALLET LogPrintf("No wallet support compiled in!\n"); @@ -1498,10 +1574,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // if pruning, unset the service bit and perform the initial blockstore prune // after any wallet rescanning has taken place. if (fPruneMode) { - uiInterface.InitMessage(_("Pruning blockstore...")); LogPrintf("Unsetting NODE_NETWORK on prune mode\n"); nLocalServices &= ~NODE_NETWORK; if (!fReindex) { + uiInterface.InitMessage(_("Pruning blockstore...")); PruneAndFlush(); } } @@ -1514,7 +1590,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) uiInterface.InitMessage(_("Activating best chain...")); // scan for better chains in the block chain database, that are not yet connected in the active best chain CValidationState state; - if (!ActivateBestChain(state)) + if (!ActivateBestChain(state, chainparams)) strErrors << "Failed to connect best block"; std::vector<boost::filesystem::path> vImportFiles; @@ -1549,6 +1625,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0); #endif + if (GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) + StartTorControl(threadGroup, scheduler); + StartNode(threadGroup, scheduler); // Monitor the chain, and alert if we get blocks much quicker or slower than expected @@ -1558,7 +1637,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) scheduler.scheduleEvery(f, nPowTargetSpacing); // Generate coins in the background - GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), Params()); + GenerateBitcoins(GetBoolArg("-gen", DEFAULT_GENERATE), GetArg("-genproclimit", DEFAULT_GENERATE_THREADS), chainparams); // ********************************************************* Step 12: finished diff --git a/src/init.h b/src/init.h index 8cd51b0286..af1b94b72a 100644 --- a/src/init.h +++ b/src/init.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -23,6 +23,10 @@ bool ShutdownRequested(); /** Interrupt threads */ void Interrupt(boost::thread_group& threadGroup); void Shutdown(); +//!Initialize the logging infrastructure +void InitLogging(); +//!Parameter interaction: change current parameters depending on various rules +void InitParameterInteraction(); bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler); /** The help message mode determines what help message to show */ diff --git a/src/key.cpp b/src/key.cpp index b772dff333..28ba5144e4 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,17 +7,120 @@ #include "arith_uint256.h" #include "crypto/common.h" #include "crypto/hmac_sha512.h" -#include "eccryptoverify.h" #include "pubkey.h" #include "random.h" #include <secp256k1.h> -#include "ecwrapper.h" +#include <secp256k1_recovery.h> -static secp256k1_context_t* secp256k1_context = NULL; +static secp256k1_context* secp256k1_context_sign = NULL; + +/** These functions are taken from the libsecp256k1 distribution and are very ugly. */ +static int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *out32, const unsigned char *privkey, size_t privkeylen) { + const unsigned char *end = privkey + privkeylen; + int lenb = 0; + int len = 0; + memset(out32, 0, 32); + /* sequence header */ + if (end < privkey+1 || *privkey != 0x30) { + return 0; + } + privkey++; + /* sequence length constructor */ + 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 */ + 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; + } + memcpy(out32 + 32 - privkey[1], privkey + 2, privkey[1]); + if (!secp256k1_ec_seckey_verify(ctx, out32)) { + memset(out32, 0, 32); + return 0; + } + return 1; +} + +static int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) { + secp256k1_pubkey pubkey; + size_t pubkeylen = 0; + if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) { + *privkeylen = 0; + return 0; + } + 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); + memcpy(ptr, key32, 32); ptr += 32; + memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); + pubkeylen = 33; + secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED); + 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); + memcpy(ptr, key32, 32); ptr += 32; + memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); + pubkeylen = 65; + secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED); + ptr += pubkeylen; + *privkeylen = ptr - privkey; + } + return 1; +} bool CKey::Check(const unsigned char *vch) { - return eccrypto::Check(vch); + return secp256k1_ec_seckey_verify(secp256k1_context_sign, vch); } void CKey::MakeNewKey(bool fCompressedIn) { @@ -30,7 +133,7 @@ void CKey::MakeNewKey(bool fCompressedIn) { } bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) { - if (!secp256k1_ec_privkey_import(secp256k1_context, (unsigned char*)begin(), &privkey[0], privkey.size())) + if (!ec_privkey_import_der(secp256k1_context_sign, (unsigned char*)begin(), &privkey[0], privkey.size())) return false; fCompressed = fCompressedIn; fValid = true; @@ -40,10 +143,11 @@ bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) { CPrivKey CKey::GetPrivKey() const { assert(fValid); CPrivKey privkey; - int privkeylen, ret; + int ret; + size_t privkeylen; privkey.resize(279); privkeylen = 279; - ret = secp256k1_ec_privkey_export(secp256k1_context, begin(), (unsigned char*)&privkey[0], &privkeylen, fCompressed); + ret = ec_privkey_export_der(secp256k1_context_sign, (unsigned char*)&privkey[0], &privkeylen, begin(), fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); assert(ret); privkey.resize(privkeylen); return privkey; @@ -51,11 +155,13 @@ CPrivKey CKey::GetPrivKey() const { CPubKey CKey::GetPubKey() const { assert(fValid); + secp256k1_pubkey pubkey; + size_t clen = 65; CPubKey result; - int clen = 65; - int ret = secp256k1_ec_pubkey_create(secp256k1_context, (unsigned char*)result.begin(), &clen, begin(), fCompressed); - assert((int)result.size() == clen); + int ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, begin()); assert(ret); + secp256k1_ec_pubkey_serialize(secp256k1_context_sign, (unsigned char*)result.begin(), &clen, &pubkey, fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); + assert(result.size() == clen); assert(result.IsValid()); return result; } @@ -64,11 +170,13 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_ if (!fValid) return false; vchSig.resize(72); - int nSigLen = 72; + size_t nSigLen = 72; unsigned char extra_entropy[32] = {0}; WriteLE32(extra_entropy, test_case); - int ret = secp256k1_ecdsa_sign(secp256k1_context, hash.begin(), (unsigned char*)&vchSig[0], &nSigLen, begin(), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL); + secp256k1_ecdsa_signature sig; + int ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL); assert(ret); + secp256k1_ecdsa_signature_serialize_der(secp256k1_context_sign, (unsigned char*)&vchSig[0], &nSigLen, &sig); vchSig.resize(nSigLen); return true; } @@ -92,7 +200,10 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) return false; vchSig.resize(65); int rec = -1; - int ret = secp256k1_ecdsa_sign_compact(secp256k1_context, hash.begin(), &vchSig[1], begin(), secp256k1_nonce_function_rfc6979, NULL, &rec); + secp256k1_ecdsa_recoverable_signature sig; + int ret = secp256k1_ecdsa_sign_recoverable(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, NULL); + assert(ret); + secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_context_sign, (unsigned char*)&vchSig[1], &rec, &sig); assert(ret); assert(rec != -1); vchSig[0] = 27 + rec + (fCompressed ? 4 : 0); @@ -100,7 +211,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) } bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) { - if (!secp256k1_ec_privkey_import(secp256k1_context, (unsigned char*)begin(), &privkey[0], privkey.size())) + if (!ec_privkey_import_der(secp256k1_context_sign, (unsigned char*)begin(), &privkey[0], privkey.size())) return false; fCompressed = vchPubKey.IsCompressed(); fValid = true; @@ -126,7 +237,7 @@ bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const } memcpy(ccChild.begin(), out+32, 32); memcpy((unsigned char*)keyChild.begin(), begin(), 32); - bool ret = secp256k1_ec_privkey_tweak_add(secp256k1_context, (unsigned char*)keyChild.begin(), out); + bool ret = secp256k1_ec_privkey_tweak_add(secp256k1_context_sign, (unsigned char*)keyChild.begin(), out); UnlockObject(out); keyChild.fCompressed = true; keyChild.fValid = ret; @@ -184,20 +295,16 @@ void CExtKey::Decode(const unsigned char code[74]) { } bool ECC_InitSanityCheck() { - if (!CECKey::SanityCheck()) { - return false; - } CKey key; key.MakeNewKey(true); CPubKey pubkey = key.GetPubKey(); return key.VerifyPubKey(pubkey); } - void ECC_Start() { - assert(secp256k1_context == NULL); + assert(secp256k1_context_sign == NULL); - secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); + secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); assert(ctx != NULL); { @@ -210,12 +317,12 @@ void ECC_Start() { UnlockObject(seed); } - secp256k1_context = ctx; + secp256k1_context_sign = ctx; } void ECC_Stop() { - secp256k1_context_t *ctx = secp256k1_context; - secp256k1_context = NULL; + secp256k1_context *ctx = secp256k1_context_sign; + secp256k1_context_sign = NULL; if (ctx) { secp256k1_context_destroy(ctx); @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/keystore.cpp b/src/keystore.cpp index cf49ba83ad..cc8a573367 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/keystore.h b/src/keystore.h index b917bf20b4..d9290722e1 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/leveldb/util/env_win.cc b/src/leveldb/util/env_win.cc index ef2ecae830..e11a96b791 100644 --- a/src/leveldb/util/env_win.cc +++ b/src/leveldb/util/env_win.cc @@ -103,39 +103,20 @@ private: DISALLOW_COPY_AND_ASSIGN(Win32RandomAccessFile); }; -class Win32MapFile : public WritableFile +class Win32WritableFile : public WritableFile { public: - Win32MapFile(const std::string& fname); + Win32WritableFile(const std::string& fname); + ~Win32WritableFile(); - ~Win32MapFile(); virtual Status Append(const Slice& data); virtual Status Close(); virtual Status Flush(); virtual Status Sync(); BOOL isEnable(); private: - std::string _filename; - HANDLE _hFile; - size_t _page_size; - size_t _map_size; // How much extra memory to map at a time - char* _base; // The mapped region - HANDLE _base_handle; - char* _limit; // Limit of the mapped region - char* _dst; // Where to write next (in range [base_,limit_]) - char* _last_sync; // Where have we synced up to - uint64_t _file_offset; // Offset of base_ in file - //LARGE_INTEGER file_offset_; - // Have we done an munmap of unsynced data? - bool _pending_sync; - - // Roundup x to a multiple of y - static size_t _Roundup(size_t x, size_t y); - size_t _TruncateToPageBoundary(size_t s); - bool _UnmapCurrentRegion(); - bool _MapNewRegion(); - DISALLOW_COPY_AND_ASSIGN(Win32MapFile); - BOOL _Init(LPCWSTR Path); + std::string filename_; + ::HANDLE _hFile; }; class Win32FileLock : public FileLock @@ -442,202 +423,63 @@ void Win32RandomAccessFile::_CleanUp() } } -size_t Win32MapFile::_Roundup( size_t x, size_t y ) +Win32WritableFile::Win32WritableFile(const std::string& fname) + : filename_(fname) { - return ((x + y - 1) / y) * y; + std::wstring path; + ToWidePath(fname, path); + DWORD Flag = PathFileExistsW(path.c_str()) ? OPEN_EXISTING : CREATE_ALWAYS; + _hFile = CreateFileW(path.c_str(), + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE, + NULL, + Flag, + FILE_ATTRIBUTE_NORMAL, + NULL); + // CreateFileW returns INVALID_HANDLE_VALUE in case of error, always check isEnable() before use } -size_t Win32MapFile::_TruncateToPageBoundary( size_t s ) +Win32WritableFile::~Win32WritableFile() { - s -= (s & (_page_size - 1)); - assert((s % _page_size) == 0); - return s; + if (_hFile != INVALID_HANDLE_VALUE) + Close(); } -bool Win32MapFile::_UnmapCurrentRegion() +Status Win32WritableFile::Append(const Slice& data) { - bool result = true; - if (_base != NULL) { - if (_last_sync < _limit) { - // Defer syncing this data until next Sync() call, if any - _pending_sync = true; - } - if (!UnmapViewOfFile(_base) || !CloseHandle(_base_handle)) - result = false; - _file_offset += _limit - _base; - _base = NULL; - _base_handle = NULL; - _limit = NULL; - _last_sync = NULL; - _dst = NULL; - // Increase the amount we map the next time, but capped at 1MB - if (_map_size < (1<<20)) { - _map_size *= 2; - } + DWORD r = 0; + if (!WriteFile(_hFile, data.data(), data.size(), &r, NULL) || r != data.size()) { + return Status::IOError("Win32WritableFile.Append::WriteFile: "+filename_, Win32::GetLastErrSz()); } - return result; -} - -bool Win32MapFile::_MapNewRegion() -{ - assert(_base == NULL); - //LONG newSizeHigh = (LONG)((file_offset_ + map_size_) >> 32); - //LONG newSizeLow = (LONG)((file_offset_ + map_size_) & 0xFFFFFFFF); - DWORD off_hi = (DWORD)(_file_offset >> 32); - DWORD off_lo = (DWORD)(_file_offset & 0xFFFFFFFF); - LARGE_INTEGER newSize; - newSize.QuadPart = _file_offset + _map_size; - SetFilePointerEx(_hFile, newSize, NULL, FILE_BEGIN); - SetEndOfFile(_hFile); - - _base_handle = CreateFileMappingA( - _hFile, - NULL, - PAGE_READWRITE, - 0, - 0, - 0); - if (_base_handle != NULL) { - _base = (char*) MapViewOfFile(_base_handle, - FILE_MAP_ALL_ACCESS, - off_hi, - off_lo, - _map_size); - if (_base != NULL) { - _limit = _base + _map_size; - _dst = _base; - _last_sync = _base; - return true; - } - } - return false; + return Status::OK(); } -Win32MapFile::Win32MapFile( const std::string& fname) : - _filename(fname), - _hFile(NULL), - _page_size(Win32::g_PageSize), - _map_size(_Roundup(65536, Win32::g_PageSize)), - _base(NULL), - _base_handle(NULL), - _limit(NULL), - _dst(NULL), - _last_sync(NULL), - _file_offset(0), - _pending_sync(false) +Status Win32WritableFile::Close() { - std::wstring path; - ToWidePath(fname, path); - _Init(path.c_str()); - assert((Win32::g_PageSize & (Win32::g_PageSize - 1)) == 0); -} - -Status Win32MapFile::Append( const Slice& data ) -{ - const char* src = data.data(); - size_t left = data.size(); - Status s; - while (left > 0) { - assert(_base <= _dst); - assert(_dst <= _limit); - size_t avail = _limit - _dst; - if (avail == 0) { - if (!_UnmapCurrentRegion() || - !_MapNewRegion()) { - return Status::IOError("WinMmapFile.Append::UnmapCurrentRegion or MapNewRegion: ", Win32::GetLastErrSz()); - } - } - size_t n = (left <= avail) ? left : avail; - memcpy(_dst, src, n); - _dst += n; - src += n; - left -= n; - } - return s; -} - -Status Win32MapFile::Close() -{ - Status s; - size_t unused = _limit - _dst; - if (!_UnmapCurrentRegion()) { - s = Status::IOError("WinMmapFile.Close::UnmapCurrentRegion: ",Win32::GetLastErrSz()); - } else if (unused > 0) { - // Trim the extra space at the end of the file - LARGE_INTEGER newSize; - newSize.QuadPart = _file_offset - unused; - if (!SetFilePointerEx(_hFile, newSize, NULL, FILE_BEGIN)) { - s = Status::IOError("WinMmapFile.Close::SetFilePointer: ",Win32::GetLastErrSz()); - } else - SetEndOfFile(_hFile); - } if (!CloseHandle(_hFile)) { - if (s.ok()) { - s = Status::IOError("WinMmapFile.Close::CloseHandle: ", Win32::GetLastErrSz()); - } + return Status::IOError("Win32WritableFile.Close::CloseHandle: "+filename_, Win32::GetLastErrSz()); } _hFile = INVALID_HANDLE_VALUE; - _base = NULL; - _base_handle = NULL; - _limit = NULL; - - return s; -} - -Status Win32MapFile::Sync() -{ - Status s; - if (_pending_sync) { - // Some unmapped data was not synced - _pending_sync = false; - if (!FlushFileBuffers(_hFile)) { - s = Status::IOError("WinMmapFile.Sync::FlushFileBuffers: ",Win32::GetLastErrSz()); - } - } - if (_dst > _last_sync) { - // Find the beginnings of the pages that contain the first and last - // bytes to be synced. - size_t p1 = _TruncateToPageBoundary(_last_sync - _base); - size_t p2 = _TruncateToPageBoundary(_dst - _base - 1); - _last_sync = _dst; - if (!FlushViewOfFile(_base + p1, p2 - p1 + _page_size)) { - s = Status::IOError("WinMmapFile.Sync::FlushViewOfFile: ",Win32::GetLastErrSz()); - } - } - return s; + return Status::OK(); } -Status Win32MapFile::Flush() +Status Win32WritableFile::Flush() { + // Nothing to do here, there are no application-side buffers return Status::OK(); } -Win32MapFile::~Win32MapFile() +Status Win32WritableFile::Sync() { - if (_hFile != INVALID_HANDLE_VALUE) { - Win32MapFile::Close(); + if (!FlushFileBuffers(_hFile)) { + return Status::IOError("Win32WritableFile.Sync::FlushFileBuffers "+filename_, Win32::GetLastErrSz()); } + return Status::OK(); } -BOOL Win32MapFile::_Init( LPCWSTR Path ) -{ - DWORD Flag = PathFileExistsW(Path) ? OPEN_EXISTING : CREATE_ALWAYS; - _hFile = CreateFileW(Path, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE, - NULL, - Flag, - FILE_ATTRIBUTE_NORMAL, - NULL); - if(!_hFile || _hFile == INVALID_HANDLE_VALUE) - return FALSE; - else - return TRUE; -} - -BOOL Win32MapFile::isEnable() +BOOL Win32WritableFile::isEnable() { - return _hFile ? TRUE : FALSE; + return _hFile != INVALID_HANDLE_VALUE; } Win32FileLock::Win32FileLock( const std::string& fname ) : @@ -981,7 +823,7 @@ Status Win32Env::NewLogger( const std::string& fname, Logger** result ) { Status sRet; std::string path = fname; - Win32MapFile* pMapFile = new Win32MapFile(ModifyPath(path)); + Win32WritableFile* pMapFile = new Win32WritableFile(ModifyPath(path)); if(!pMapFile->isEnable()){ delete pMapFile; *result = NULL; @@ -995,7 +837,7 @@ Status Win32Env::NewWritableFile( const std::string& fname, WritableFile** resul { Status sRet; std::string path = fname; - Win32MapFile* pFile = new Win32MapFile(ModifyPath(path)); + Win32WritableFile* pFile = new Win32WritableFile(ModifyPath(path)); if(!pFile->isEnable()){ *result = NULL; sRet = Status::IOError(fname,Win32::GetLastErrSz()); diff --git a/src/leveldbwrapper.cpp b/src/leveldbwrapper.cpp deleted file mode 100644 index 26cacf95ae..0000000000 --- a/src/leveldbwrapper.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// 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" - -#include "util.h" - -#include <boost/filesystem.hpp> - -#include <leveldb/cache.h> -#include <leveldb/env.h> -#include <leveldb/filter_policy.h> -#include <memenv.h> - -void HandleError(const leveldb::Status& status) throw(leveldb_error) -{ - if (status.ok()) - return; - LogPrintf("%s\n", status.ToString()); - if (status.IsCorruption()) - throw leveldb_error("Database corrupted"); - if (status.IsIOError()) - throw leveldb_error("Database I/O error"); - if (status.IsNotFound()) - throw leveldb_error("Database entry missing"); - throw leveldb_error("Unknown database error"); -} - -static leveldb::Options GetOptions(size_t nCacheSize) -{ - leveldb::Options options; - options.block_cache = leveldb::NewLRUCache(nCacheSize / 2); - options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously - options.filter_policy = leveldb::NewBloomFilterPolicy(10); - options.compression = leveldb::kNoCompression; - options.max_open_files = 64; - if (leveldb::kMajorVersion > 1 || (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) { - // LevelDB versions before 1.16 consider short writes to be corruption. Only trigger error - // on corruption in later versions. - options.paranoid_checks = true; - } - return options; -} - -CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory, bool fWipe) -{ - penv = NULL; - readoptions.verify_checksums = true; - iteroptions.verify_checksums = true; - iteroptions.fill_cache = false; - syncoptions.sync = true; - options = GetOptions(nCacheSize); - options.create_if_missing = true; - if (fMemory) { - penv = leveldb::NewMemEnv(leveldb::Env::Default()); - options.env = penv; - } else { - if (fWipe) { - LogPrintf("Wiping LevelDB in %s\n", path.string()); - leveldb::Status result = leveldb::DestroyDB(path.string(), options); - HandleError(result); - } - TryCreateDirectory(path); - LogPrintf("Opening LevelDB in %s\n", path.string()); - } - leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb); - HandleError(status); - LogPrintf("Opened LevelDB successfully\n"); -} - -CLevelDBWrapper::~CLevelDBWrapper() -{ - delete pdb; - pdb = NULL; - delete options.filter_policy; - options.filter_policy = NULL; - delete options.block_cache; - options.block_cache = NULL; - delete penv; - options.env = NULL; -} - -bool CLevelDBWrapper::WriteBatch(CLevelDBBatch& batch, bool fSync) throw(leveldb_error) -{ - leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch); - HandleError(status); - return true; -} diff --git a/src/leveldbwrapper.h b/src/leveldbwrapper.h deleted file mode 100644 index c65e842704..0000000000 --- a/src/leveldbwrapper.h +++ /dev/null @@ -1,173 +0,0 @@ -// 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" - -#include <boost/filesystem/path.hpp> - -#include <leveldb/db.h> -#include <leveldb/write_batch.h> - -class leveldb_error : public std::runtime_error -{ -public: - leveldb_error(const std::string& msg) : std::runtime_error(msg) {} -}; - -void HandleError(const leveldb::Status& status) throw(leveldb_error); - -/** Batch of changes queued to be written to a CLevelDBWrapper */ -class CLevelDBBatch -{ - friend class CLevelDBWrapper; - -private: - leveldb::WriteBatch batch; - -public: - template <typename K, typename V> - void Write(const K& key, const V& value) - { - CDataStream ssKey(SER_DISK, CLIENT_VERSION); - ssKey.reserve(ssKey.GetSerializeSize(key)); - ssKey << key; - leveldb::Slice slKey(&ssKey[0], ssKey.size()); - - CDataStream ssValue(SER_DISK, CLIENT_VERSION); - ssValue.reserve(ssValue.GetSerializeSize(value)); - ssValue << value; - leveldb::Slice slValue(&ssValue[0], ssValue.size()); - - batch.Put(slKey, slValue); - } - - template <typename K> - void Erase(const K& key) - { - CDataStream ssKey(SER_DISK, CLIENT_VERSION); - ssKey.reserve(ssKey.GetSerializeSize(key)); - ssKey << key; - leveldb::Slice slKey(&ssKey[0], ssKey.size()); - - batch.Delete(slKey); - } -}; - -class CLevelDBWrapper -{ -private: - //! custom environment this database is using (may be NULL in case of default environment) - leveldb::Env* penv; - - //! database options used - leveldb::Options options; - - //! options used when reading from the database - leveldb::ReadOptions readoptions; - - //! options used when iterating over values of the database - leveldb::ReadOptions iteroptions; - - //! options used when writing to the database - leveldb::WriteOptions writeoptions; - - //! options used when sync writing to the database - leveldb::WriteOptions syncoptions; - - //! the database itself - leveldb::DB* pdb; - -public: - CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false); - ~CLevelDBWrapper(); - - template <typename K, typename V> - bool Read(const K& key, V& value) const throw(leveldb_error) - { - CDataStream ssKey(SER_DISK, CLIENT_VERSION); - ssKey.reserve(ssKey.GetSerializeSize(key)); - ssKey << key; - leveldb::Slice slKey(&ssKey[0], ssKey.size()); - - std::string strValue; - leveldb::Status status = pdb->Get(readoptions, slKey, &strValue); - if (!status.ok()) { - if (status.IsNotFound()) - return false; - LogPrintf("LevelDB read failure: %s\n", status.ToString()); - HandleError(status); - } - try { - CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); - ssValue >> value; - } catch (const std::exception&) { - return false; - } - return true; - } - - template <typename K, typename V> - bool Write(const K& key, const V& value, bool fSync = false) throw(leveldb_error) - { - CLevelDBBatch batch; - batch.Write(key, value); - return WriteBatch(batch, fSync); - } - - template <typename K> - bool Exists(const K& key) const throw(leveldb_error) - { - CDataStream ssKey(SER_DISK, CLIENT_VERSION); - ssKey.reserve(ssKey.GetSerializeSize(key)); - ssKey << key; - leveldb::Slice slKey(&ssKey[0], ssKey.size()); - - std::string strValue; - leveldb::Status status = pdb->Get(readoptions, slKey, &strValue); - if (!status.ok()) { - if (status.IsNotFound()) - return false; - LogPrintf("LevelDB read failure: %s\n", status.ToString()); - HandleError(status); - } - return true; - } - - template <typename K> - bool Erase(const K& key, bool fSync = false) throw(leveldb_error) - { - CLevelDBBatch batch; - batch.Erase(key); - return WriteBatch(batch, fSync); - } - - bool WriteBatch(CLevelDBBatch& batch, bool fSync = false) throw(leveldb_error); - - // not available for LevelDB; provide for compatibility with BDB - bool Flush() - { - return true; - } - - bool Sync() throw(leveldb_error) - { - CLevelDBBatch batch; - return WriteBatch(batch, true); - } - - // not exactly clean encapsulation, but it's easiest for now - leveldb::Iterator* NewIterator() - { - return pdb->NewIterator(iteroptions); - } -}; - -#endif // BITCOIN_LEVELDBWRAPPER_H diff --git a/src/limitedmap.h b/src/limitedmap.h index 5456dfc7c4..4d9bb4fa21 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/main.cpp b/src/main.cpp index 5cfb05b0d2..06374cc1b6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,6 +12,7 @@ #include "checkpoints.h" #include "checkqueue.h" #include "consensus/consensus.h" +#include "consensus/merkle.h" #include "consensus/validation.h" #include "hash.h" #include "init.h" @@ -66,16 +67,17 @@ bool fReindex = false; bool fTxIndex = false; bool fHavePruned = false; bool fPruneMode = false; -bool fIsBareMultisigStd = true; +bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG; bool fRequireStandard = true; +unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; bool fCheckBlockIndex = false; -bool fCheckpointsEnabled = true; +bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED; size_t nCoinCacheUsage = 5000 * 300; uint64_t nPruneTarget = 0; bool fAlerts = DEFAULT_ALERTS; -/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */ -CFeeRate minRelayTxFee = CFeeRate(1000); +/** Fees smaller than this (in satoshi) are considered zero fee (for relaying, mining and transaction creation) */ +CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); CTxMemPool mempool(::minRelayTxFee); @@ -83,8 +85,8 @@ struct COrphanTx { CTransaction tx; NodeId fromPeer; }; -map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);; -map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);; +map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main); +map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main); void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** @@ -92,7 +94,7 @@ void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards. */ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams); -static void CheckBlockIndex(); +static void CheckBlockIndex(const Consensus::Params& consensusParams); /** Constant stuff for coinbase transactions we create: */ CScript COINBASE_FLAGS; @@ -133,9 +135,9 @@ namespace { 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. - * Pruned nodes may have entries where B is missing data. - */ + /** All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions. + * Pruned nodes may have entries where B is missing data. + */ multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked; CCriticalSection cs_LastBlockFile; @@ -180,7 +182,7 @@ namespace { * million to make it highly unlikely for users to have issues with this * filter. * - * Memory used: 1.7MB + * Memory used: 1.3 MB */ boost::scoped_ptr<CRollingBloomFilter> recentRejects; uint256 hashRecentRejectsChainTip; @@ -246,6 +248,8 @@ struct CNodeState { uint256 hashLastUnknownBlock; //! The last full block we both have. CBlockIndex *pindexLastCommonBlock; + //! The best header we have sent our peer. + CBlockIndex *pindexBestHeaderSent; //! Whether we've started headers synchronization with this peer. bool fSyncStarted; //! Since when we're stalling block download progress (in microseconds), or 0. @@ -255,6 +259,8 @@ struct CNodeState { int nBlocksInFlightValidHeaders; //! Whether we consider this a preferred download peer. bool fPreferredDownload; + //! Whether this peer wants invs or headers (when possible) for block announcements. + bool fPreferHeaders; CNodeState() { fCurrentlyConnected = false; @@ -263,11 +269,13 @@ struct CNodeState { pindexBestKnownBlock = NULL; hashLastUnknownBlock.SetNull(); pindexLastCommonBlock = NULL; + pindexBestHeaderSent = NULL; fSyncStarted = false; nStallingSince = 0; nBlocksInFlight = 0; nBlocksInFlightValidHeaders = 0; fPreferredDownload = false; + fPreferHeaders = false; } }; @@ -397,6 +405,22 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) { } } +// Requires cs_main +bool CanDirectFetch(const Consensus::Params &consensusParams) +{ + return chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - consensusParams.nPowTargetSpacing * 20; +} + +// Requires cs_main +bool PeerHasHeader(CNodeState *state, CBlockIndex *pindex) +{ + if (state->pindexBestKnownBlock && pindex == state->pindexBestKnownBlock->GetAncestor(pindex->nHeight)) + return true; + if (state->pindexBestHeaderSent && pindex == state->pindexBestHeaderSent->GetAncestor(pindex->nHeight)) + return true; + return false; +} + /** Find the last common ancestor two blocks have. * Both pa and pb must be non-NULL. */ CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) { @@ -650,10 +674,36 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) return true; } -bool CheckFinalTx(const CTransaction &tx) +bool CheckFinalTx(const CTransaction &tx, int flags) { AssertLockHeld(cs_main); - return IsFinalTx(tx, chainActive.Height() + 1, GetAdjustedTime()); + + // By convention a negative value for flags indicates that the + // current network-enforced consensus rules should be used. In + // a future soft-fork scenario that would mean checking which + // rules would be enforced for the next block and setting the + // appropriate flags. At the present time no soft-forks are + // scheduled, so no flags are set. + flags = std::max(flags, 0); + + // CheckFinalTx() uses chainActive.Height()+1 to evaluate + // nLockTime because when IsFinalTx() is called within + // CBlock::AcceptBlock(), the height of the block *being* + // evaluated is what is used. Thus if we want to know if a + // transaction can be part of the *next* block, we need to call + // IsFinalTx() with one more than chainActive.Height(). + const int nBlockHeight = chainActive.Height() + 1; + + // BIP113 will require that time-locked transactions have nLockTime set to + // less than the median time of the previous block they're contained in. + // When the next block is created its previous block will be the current + // chain tip, so we use that to calculate the median time passed to + // IsFinalTx() if LOCKTIME_MEDIAN_TIME_PAST is set. + const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST) + ? chainActive.Tip()->GetMedianTimePast() + : GetAdjustedTime(); + + return IsFinalTx(tx, nBlockHeight, nBlockTime); } unsigned int GetLegacySigOpCount(const CTransaction& tx) @@ -740,37 +790,19 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) return true; } -CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree) -{ - { - LOCK(mempool.cs); - uint256 hash = tx.GetHash(); - double dPriorityDelta = 0; - CAmount nFeeDelta = 0; - mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta); - if (dPriorityDelta > 0 || nFeeDelta > 0) - return 0; - } - - CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes); +void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age) { + int expired = pool.Expire(GetTime() - age); + if (expired != 0) + LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired); - if (fAllowFree) - { - // There is a free transaction area in blocks created by most miners, - // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000 - // to be considered to fall into this category. We don't want to encourage sending - // multiple transactions instead of one big transaction to avoid fees. - if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000)) - nMinFee = 0; - } - - if (!MoneyRange(nMinFee)) - nMinFee = MAX_MONEY; - return nMinFee; + std::vector<uint256> vNoSpendsRemaining; + pool.TrimToSize(limit, &vNoSpendsRemaining); + BOOST_FOREACH(const uint256& removed, vNoSpendsRemaining) + pcoinsTip->Uncache(removed); } /** Convert CValidationState to a human-readable message for logging */ -static std::string FormatStateMessage(const CValidationState &state) +std::string FormatStateMessage(const CValidationState &state) { return strprintf("%s%s (code %i)", state.GetRejectReason(), @@ -778,8 +810,9 @@ static std::string FormatStateMessage(const CValidationState &state) state.GetRejectCode()); } -bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs, bool fRejectAbsurdFee) +bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, + bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee, + std::vector<uint256>& vHashTxnToUncache) { AssertLockHeld(cs_main); if (pfMissingInputs) @@ -800,7 +833,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Only accept nLockTime-using transactions that can be mined in the next // block; we don't want our mempool filled up with transactions that can't // be mined yet. - if (!CheckFinalTx(tx)) + if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS)) return state.DoS(0, false, REJECT_NONSTANDARD, "non-final"); // is it already in the memory pool? @@ -809,15 +842,42 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-in-mempool"); // Check for conflicts with in-memory transactions + set<uint256> setConflicts; { LOCK(pool.cs); // protect pool.mapNextTx - for (unsigned int i = 0; i < tx.vin.size(); i++) + BOOST_FOREACH(const CTxIn &txin, tx.vin) { - COutPoint outpoint = tx.vin[i].prevout; - if (pool.mapNextTx.count(outpoint)) + if (pool.mapNextTx.count(txin.prevout)) { - // Disable replacement feature for now - return state.Invalid(false, REJECT_CONFLICT, "txn-mempool-conflict"); + const CTransaction *ptxConflicting = pool.mapNextTx[txin.prevout].ptx; + if (!setConflicts.count(ptxConflicting->GetHash())) + { + // Allow opt-out of transaction replacement by setting + // nSequence >= maxint-1 on all inputs. + // + // maxint-1 is picked to still allow use of nLockTime by + // non-replacable transactions. All inputs rather than just one + // is for the sake of multi-party protocols, where we don't + // want a single party to be able to disable replacement. + // + // The opt-out ignores descendants as anyone relying on + // first-seen mempool behavior should be checking all + // unconfirmed ancestors anyway; doing otherwise is hopelessly + // insecure. + bool fReplacementOptOut = true; + BOOST_FOREACH(const CTxIn &txin, ptxConflicting->vin) + { + if (txin.nSequence < std::numeric_limits<unsigned int>::max()-1) + { + fReplacementOptOut = false; + break; + } + } + if (fReplacementOptOut) + return state.Invalid(false, REJECT_CONFLICT, "txn-mempool-conflict"); + + setConflicts.insert(ptxConflicting->GetHash()); + } } } } @@ -833,13 +893,19 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa view.SetBackend(viewMemPool); // do we already have it? - if (view.HaveCoins(hash)) + bool fHadTxInCache = pcoinsTip->HaveCoinsInCache(hash); + if (view.HaveCoins(hash)) { + if (!fHadTxInCache) + vHashTxnToUncache.push_back(hash); return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-known"); + } // do all inputs exist? // Note that this does not check for the presence of actual outputs (see the next check for that), // and only helps with filling in pfMissingInputs (to determine missing vs spent). BOOST_FOREACH(const CTxIn txin, tx.vin) { + if (!pcoinsTip->HaveCoinsInCache(txin.prevout.hash)) + vHashTxnToUncache.push_back(txin.prevout.hash); if (!view.HaveCoins(txin.prevout.hash)) { if (pfMissingInputs) *pfMissingInputs = true; @@ -864,39 +930,54 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if (fRequireStandard && !AreInputsStandard(tx, view)) return state.Invalid(false, REJECT_NONSTANDARD, "bad-txns-nonstandard-inputs"); - // Check that the transaction doesn't have an excessive number of - // sigops, making it impossible to mine. Since the coinbase transaction - // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than - // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than - // merely non-standard transaction. unsigned int nSigOps = GetLegacySigOpCount(tx); nSigOps += GetP2SHSigOpCount(tx, view); - if (nSigOps > MAX_STANDARD_TX_SIGOPS) - return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false, - strprintf("%d > %d", nSigOps, MAX_STANDARD_TX_SIGOPS)); CAmount nValueOut = tx.GetValueOut(); CAmount nFees = nValueIn-nValueOut; - double dPriority = view.GetPriority(tx, chainActive.Height()); + // nModifiedFees includes any fee deltas from PrioritiseTransaction + CAmount nModifiedFees = nFees; + double nPriorityDummy = 0; + pool.ApplyDeltas(hash, nPriorityDummy, nModifiedFees); + + CAmount inChainInputValue; + double dPriority = view.GetPriority(tx, chainActive.Height(), inChainInputValue); - CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx)); + // Keep track of transactions that spend a coinbase, which we re-scan + // during reorgs to ensure COINBASE_MATURITY is still met. + bool fSpendsCoinbase = false; + BOOST_FOREACH(const CTxIn &txin, tx.vin) { + const CCoins *coins = view.AccessCoins(txin.prevout.hash); + if (coins->IsCoinBase()) { + fSpendsCoinbase = true; + break; + } + } + + CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOps); unsigned int nSize = entry.GetTxSize(); - // Don't accept it if it can't get into a block - CAmount txMinFee = GetMinRelayFee(tx, nSize, true); - if (fLimitFree && nFees < txMinFee) - return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false, - strprintf("%d < %d", nFees, txMinFee)); + // Check that the transaction doesn't have an excessive number of + // sigops, making it impossible to mine. Since the coinbase transaction + // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than + // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than + // merely non-standard transaction. + if ((nSigOps > MAX_STANDARD_TX_SIGOPS) || (nBytesPerSigOp && nSigOps > nSize / nBytesPerSigOp)) + return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false, + strprintf("%d", nSigOps)); - // Require that free transactions have sufficient priority to be mined in the next block. - if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) { + CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize); + if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) { + return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee)); + } else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nModifiedFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) { + // Require that free transactions have sufficient priority to be mined in the next block. return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority"); } // Continuously rate-limit free (really, very-low-fee) transactions // This mitigates 'penny-flooding' -- sending thousands of free transactions just to // be annoying or make others' transactions take longer to confirm. - if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize)) + if (fLimitFree && nModifiedFees < ::minRelayTxFee.GetFee(nSize)) { static CCriticalSection csFreeLimiter; static double dFreeCount; @@ -910,7 +991,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa nLastTime = nNow; // -limitfreerelay unit is thousand-bytes-per-minute // At default rate it would take over a month to fill 1GB - if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000) + if (dFreeCount >= GetArg("-limitfreerelay", DEFAULT_LIMITFREERELAY) * 10 * 1000) return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "rate limited free transaction"); LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); dFreeCount += nSize; @@ -932,6 +1013,160 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return state.DoS(0, false, REJECT_NONSTANDARD, "too-long-mempool-chain", false, errString); } + // A transaction that spends outputs that would be replaced by it is invalid. Now + // that we have the set of all ancestors we can detect this + // pathological case by making sure setConflicts and setAncestors don't + // intersect. + BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) + { + const uint256 &hashAncestor = ancestorIt->GetTx().GetHash(); + if (setConflicts.count(hashAncestor)) + { + return state.DoS(10, error("AcceptToMemoryPool: %s spends conflicting transaction %s", + hash.ToString(), + hashAncestor.ToString()), + REJECT_INVALID, "bad-txns-spends-conflicting-tx"); + } + } + + // Check if it's economically rational to mine this transaction rather + // than the ones it replaces. + CAmount nConflictingFees = 0; + size_t nConflictingSize = 0; + uint64_t nConflictingCount = 0; + CTxMemPool::setEntries allConflicting; + + // If we don't hold the lock allConflicting might be incomplete; the + // subsequent RemoveStaged() and addUnchecked() calls don't guarantee + // mempool consistency for us. + LOCK(pool.cs); + if (setConflicts.size()) + { + CFeeRate newFeeRate(nModifiedFees, nSize); + set<uint256> setConflictsParents; + const int maxDescendantsToVisit = 100; + CTxMemPool::setEntries setIterConflicting; + BOOST_FOREACH(const uint256 &hashConflicting, setConflicts) + { + CTxMemPool::txiter mi = pool.mapTx.find(hashConflicting); + if (mi == pool.mapTx.end()) + continue; + + // Save these to avoid repeated lookups + setIterConflicting.insert(mi); + + // If this entry is "dirty", then we don't have descendant + // state for this transaction, which means we probably have + // lots of in-mempool descendants. + // Don't allow replacements of dirty transactions, to ensure + // that we don't spend too much time walking descendants. + // This should be rare. + if (mi->IsDirty()) { + return state.DoS(0, + error("AcceptToMemoryPool: rejecting replacement %s; cannot replace tx %s with untracked descendants", + hash.ToString(), + mi->GetTx().GetHash().ToString()), + REJECT_NONSTANDARD, "too many potential replacements"); + } + + // Don't allow the replacement to reduce the feerate of the + // mempool. + // + // We usually don't want to accept replacements with lower + // feerates than what they replaced as that would lower the + // feerate of the next block. Requiring that the feerate always + // be increased is also an easy-to-reason about way to prevent + // DoS attacks via replacements. + // + // The mining code doesn't (currently) take children into + // account (CPFP) so we only consider the feerates of + // transactions being directly replaced, not their indirect + // descendants. While that does mean high feerate children are + // ignored when deciding whether or not to replace, we do + // require the replacement to pay more overall fees too, + // mitigating most cases. + CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize()); + if (newFeeRate <= oldFeeRate) + { + return state.DoS(0, + error("AcceptToMemoryPool: rejecting replacement %s; new feerate %s <= old feerate %s", + hash.ToString(), + newFeeRate.ToString(), + oldFeeRate.ToString()), + REJECT_INSUFFICIENTFEE, "insufficient fee"); + } + + BOOST_FOREACH(const CTxIn &txin, mi->GetTx().vin) + { + setConflictsParents.insert(txin.prevout.hash); + } + + nConflictingCount += mi->GetCountWithDescendants(); + } + // This potentially overestimates the number of actual descendants + // but we just want to be conservative to avoid doing too much + // work. + if (nConflictingCount <= maxDescendantsToVisit) { + // If not too many to replace, then calculate the set of + // transactions that would have to be evicted + BOOST_FOREACH(CTxMemPool::txiter it, setIterConflicting) { + pool.CalculateDescendants(it, allConflicting); + } + BOOST_FOREACH(CTxMemPool::txiter it, allConflicting) { + nConflictingFees += it->GetModifiedFee(); + nConflictingSize += it->GetTxSize(); + } + } else { + return state.DoS(0, + error("AcceptToMemoryPool: rejecting replacement %s; too many potential replacements (%d > %d)\n", + hash.ToString(), + nConflictingCount, + maxDescendantsToVisit), + REJECT_NONSTANDARD, "too many potential replacements"); + } + + for (unsigned int j = 0; j < tx.vin.size(); j++) + { + // We don't want to accept replacements that require low + // feerate junk to be mined first. Ideally we'd keep track of + // the ancestor feerates and make the decision based on that, + // but for now requiring all new inputs to be confirmed works. + if (!setConflictsParents.count(tx.vin[j].prevout.hash)) + { + // Rather than check the UTXO set - potentially expensive - + // it's cheaper to just check if the new input refers to a + // tx that's in the mempool. + if (pool.mapTx.find(tx.vin[j].prevout.hash) != pool.mapTx.end()) + return state.DoS(0, error("AcceptToMemoryPool: replacement %s adds unconfirmed input, idx %d", + hash.ToString(), j), + REJECT_NONSTANDARD, "replacement-adds-unconfirmed"); + } + } + + // The replacement must pay greater fees than the transactions it + // replaces - if we did the bandwidth used by those conflicting + // transactions would not be paid for. + if (nModifiedFees < nConflictingFees) + { + return state.DoS(0, error("AcceptToMemoryPool: rejecting replacement %s, less fees than conflicting txs; %s < %s", + hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees)), + REJECT_INSUFFICIENTFEE, "insufficient fee"); + } + + // Finally in addition to paying more fees than the conflicts the + // new transaction must pay for its own bandwidth. + CAmount nDeltaFees = nModifiedFees - nConflictingFees; + if (nDeltaFees < ::minRelayTxFee.GetFee(nSize)) + { + return state.DoS(0, + error("AcceptToMemoryPool: rejecting replacement %s, not enough additional fees to relay; %s < %s", + hash.ToString(), + FormatMoney(nDeltaFees), + FormatMoney(::minRelayTxFee.GetFee(nSize))), + REJECT_INSUFFICIENTFEE, "insufficient fee"); + } + } + // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true)) @@ -952,8 +1187,26 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa __func__, hash.ToString(), FormatStateMessage(state)); } + // Remove conflicting transactions from the mempool + BOOST_FOREACH(const CTxMemPool::txiter it, allConflicting) + { + LogPrint("mempool", "replacing tx %s with %s for %s BTC additional fees, %d delta bytes\n", + it->GetTx().GetHash().ToString(), + hash.ToString(), + FormatMoney(nModifiedFees - nConflictingFees), + (int)nSize - (int)nConflictingSize); + } + pool.RemoveStaged(allConflicting); + // Store transaction in memory pool.addUnchecked(hash, entry, setAncestors, !IsInitialBlockDownload()); + + // trim mempool and check if tx was trimmed + if (!fOverrideMempoolLimit) { + LimitMempoolSize(pool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); + if (!pool.exists(hash)) + return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool full"); + } } SyncWithWallets(tx, NULL); @@ -961,8 +1214,20 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return true; } +bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, + bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee) +{ + std::vector<uint256> vHashTxToUncache; + bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, fOverrideMempoolLimit, fRejectAbsurdFee, vHashTxToUncache); + if (!res) { + BOOST_FOREACH(const uint256& hashTx, vHashTxToUncache) + pcoinsTip->Uncache(hashTx); + } + return res; +} + /** 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) +bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow) { CBlockIndex *pindexSlow = NULL; @@ -1008,7 +1273,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock if (pindexSlow) { CBlock block; - if (ReadBlockFromDisk(block, pindexSlow)) { + if (ReadBlockFromDisk(block, pindexSlow, consensusParams)) { BOOST_FOREACH(const CTransaction &tx, block.vtx) { if (tx.GetHash() == hash) { txOut = tx; @@ -1053,7 +1318,7 @@ bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHea return true; } -bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) +bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams) { block.SetNull(); @@ -1071,15 +1336,15 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) } // Check the header - if (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) + if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString()); return true; } -bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex) +bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams) { - if (!ReadBlockFromDisk(block, pindex->GetBlockPos())) + if (!ReadBlockFromDisk(block, pindex->GetBlockPos(), consensusParams)) return false; if (block.GetHash() != pindex->GetBlockHash()) return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s", @@ -1207,7 +1472,7 @@ void Misbehaving(NodeId pnode, int howmuch) return; state->nMisbehavior += howmuch; - int banscore = GetArg("-banscore", 100); + int banscore = GetArg("-banscore", DEFAULT_BANSCORE_THRESHOLD); if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore) { LogPrintf("%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior); @@ -1274,10 +1539,17 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach undo.nVersion = coins->nVersion; } } + // add outputs + inputs.ModifyNewCoins(tx.GetHash())->FromTx(tx, nHeight); + } + else { + // add outputs for coinbase tx + // In this case call the full ModifyCoins which will do a database + // lookup to be sure the coins do not already exist otherwise we do not + // know whether to mark them fresh or not. We want the duplicate coinbases + // before BIP30 to still be properly overwritten. + inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); } - - // add outputs - inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); } void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight) @@ -1383,9 +1655,9 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // arguments; if so, don't trigger DoS protection to // avoid splitting the network between upgraded and // non-upgraded nodes. - CScriptCheck check(*coins, tx, i, + CScriptCheck check2(*coins, tx, i, flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore); - if (check()) + if (check2()) return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); } // Failures of other flags indicate a transaction that is @@ -1648,8 +1920,8 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const // How likely is it to find that many by chance? double p = boost::math::pdf(poisson, nBlocks); - LogPrint("partitioncheck", "%s : Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS); - LogPrint("partitioncheck", "%s : likelihood: %g\n", __func__, p); + LogPrint("partitioncheck", "%s: Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS); + LogPrint("partitioncheck", "%s: likelihood: %g\n", __func__, p); // Aim for one false-positive about every fifty years of normal running: const int FIFTY_YEARS = 50*365*24*60*60; @@ -1675,6 +1947,8 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const } } +static int64_t nTimeCheck = 0; +static int64_t nTimeForks = 0; static int64_t nTimeVerify = 0; static int64_t nTimeConnect = 0; static int64_t nTimeIndex = 0; @@ -1685,6 +1959,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin { const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); + + int64_t nTimeStart = GetTimeMicros(); + // Check it again in case a previous version let a bad block in if (!CheckBlock(block, state, !fJustCheck, !fJustCheck)) return false; @@ -1710,6 +1987,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } } + int64_t nTime1 = GetTimeMicros(); nTimeCheck += nTime1 - nTimeStart; + LogPrint("bench", " - Sanity checks: %.2fms [%.2fs]\n", 0.001 * (nTime1 - nTimeStart), nTimeCheck * 0.000001); + // Do not allow blocks that contain transactions which 'overwrite' older transactions, // unless those are already completely spent. // If such overwrites are allowed, coinbases and transactions depending upon those @@ -1725,6 +2005,17 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash. !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) || (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256S("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721"))); + + // Once BIP34 activated it was not possible to create new duplicate coinbases and thus other than starting + // with the 2 existing duplicate coinbase pairs, not possible to create overwriting txs. But by the + // time BIP34 activated, in each of the existing pairs the duplicate coinbase had overwritten the first + // before the first had been spent. Since those coinbases are sufficiently buried its no longer possible to create further + // duplicate transactions descending from the known pairs either. + // If we're on the known chain at height greater than where BIP34 activated, we can save the db accesses needed for the BIP30 check. + CBlockIndex *pindexBIP34height = pindex->pprev->GetAncestor(chainparams.GetConsensus().BIP34Height); + //Only continue to enforce if we're below BIP34 activation height or the block hash at that height doesn't correspond. + fEnforceBIP30 = fEnforceBIP30 && (!pindexBIP34height || !(pindexBIP34height->GetBlockHash() == chainparams.GetConsensus().BIP34Hash)); + if (fEnforceBIP30) { BOOST_FOREACH(const CTransaction& tx, block.vtx) { const CCoins* coins = view.AccessCoins(tx.GetHash()); @@ -1740,16 +2031,25 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE; - // Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks, when 75% of the network has upgraded: + // Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks, + // when 75% of the network has upgraded: if (block.nVersion >= 3 && IsSuperMajority(3, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) { flags |= SCRIPT_VERIFY_DERSIG; } + // Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4 + // blocks, when 75% of the network has upgraded: + if (block.nVersion >= 4 && IsSuperMajority(4, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) { + flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; + } + + int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1; + LogPrint("bench", " - Fork checks: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeForks * 0.000001); + CBlockUndo blockundo; CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); - int64_t nTimeStart = GetTimeMicros(); CAmount nFees = 0; int nInputs = 0; unsigned int nSigOps = 0; @@ -1787,7 +2087,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin nFees += view.GetValueIn(tx)-tx.GetValueOut(); std::vector<CScriptCheck> vChecks; - if (!CheckInputs(tx, state, view, fScriptChecks, flags, false, nScriptCheckThreads ? &vChecks : NULL)) + bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */ + if (!CheckInputs(tx, state, view, fScriptChecks, flags, fCacheResults, nScriptCheckThreads ? &vChecks : NULL)) return error("ConnectBlock(): CheckInputs on %s failed with %s", tx.GetHash().ToString(), FormatStateMessage(state)); control.Add(vChecks); @@ -1802,8 +2103,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin vPos.push_back(std::make_pair(tx.GetHash(), pos)); pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); } - int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart; - LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001); + int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2; + LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime3 - nTime2), 0.001 * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * 0.000001); CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()); if (block.vtx[0].GetValueOut() > blockReward) @@ -1814,8 +2115,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (!control.Wait()) return state.DoS(100, false); - int64_t nTime2 = GetTimeMicros(); nTimeVerify += nTime2 - nTimeStart; - LogPrint("bench", " - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs]\n", nInputs - 1, 0.001 * (nTime2 - nTimeStart), nInputs <= 1 ? 0 : 0.001 * (nTime2 - nTimeStart) / (nInputs-1), nTimeVerify * 0.000001); + int64_t nTime4 = GetTimeMicros(); nTimeVerify += nTime4 - nTime2; + LogPrint("bench", " - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs]\n", nInputs - 1, 0.001 * (nTime4 - nTime2), nInputs <= 1 ? 0 : 0.001 * (nTime4 - nTime2) / (nInputs-1), nTimeVerify * 0.000001); if (fJustCheck) return true; @@ -1846,16 +2147,16 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // add this block to the view's block chain 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); + int64_t nTime5 = GetTimeMicros(); nTimeIndex += nTime5 - nTime4; + LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime5 - nTime4), nTimeIndex * 0.000001); // Watch for changes to the previous coinbase transaction. static uint256 hashPrevBestCoinBase; GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase); hashPrevBestCoinBase = block.vtx[0].GetHash(); - int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3; - LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001); + int64_t nTime6 = GetTimeMicros(); nTimeCallbacks += nTime6 - nTime5; + LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime6 - nTime5), nTimeCallbacks * 0.000001); return true; } @@ -1874,6 +2175,7 @@ enum FlushStateMode { * or always and in all cases if we're in prune mode and are deleting files. */ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { + const CChainParams& chainparams = Params(); LOCK2(cs_main, cs_LastBlockFile); static int64_t nLastWrite = 0; static int64_t nLastFlush = 0; @@ -1881,8 +2183,8 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { std::set<int> setFilesToPrune; bool fFlushForPrune = false; try { - if (fPruneMode && fCheckForPruning) { - FindFilesToPrune(setFilesToPrune); + if (fPruneMode && fCheckForPruning && !fReindex) { + FindFilesToPrune(setFilesToPrune, chainparams.PruneAfterHeight()); fCheckForPruning = false; if (!setFilesToPrune.empty()) { fFlushForPrune = true; @@ -2020,14 +2322,14 @@ void static UpdateTip(CBlockIndex *pindexNew) { } } -/** Disconnect chainActive's tip. */ -bool static DisconnectTip(CValidationState &state) { +/** Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and manually re-limit mempool size after this, with cs_main held. */ +bool static DisconnectTip(CValidationState& state, const Consensus::Params& consensusParams) +{ CBlockIndex *pindexDelete = chainActive.Tip(); assert(pindexDelete); - mempool.check(pcoinsTip); // Read block from disk. CBlock block; - if (!ReadBlockFromDisk(block, pindexDelete)) + if (!ReadBlockFromDisk(block, pindexDelete, consensusParams)) return AbortNode(state, "Failed to read block"); // Apply the block atomically to the chain state. int64_t nStart = GetTimeMicros(); @@ -2047,7 +2349,7 @@ bool static DisconnectTip(CValidationState &state) { // ignore validation errors in resurrected transactions list<CTransaction> removed; CValidationState stateDummy; - if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) { + if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL, true)) { mempool.remove(tx, removed, true); } else if (mempool.exists(tx.GetHash())) { vHashUpdate.push_back(tx.GetHash()); @@ -2059,8 +2361,6 @@ bool static DisconnectTip(CValidationState &state) { // UpdateTransactionsFromBlock finds descendants of any transactions in this // block that were added back and cleans up the mempool state. mempool.UpdateTransactionsFromBlock(vHashUpdate); - mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight); - mempool.check(pcoinsTip); // Update chainActive and related variables. UpdateTip(pindexDelete->pprev); // Let wallets know transactions went from 1-confirmed to @@ -2081,14 +2381,14 @@ static int64_t nTimePostConnect = 0; * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock * corresponding to pindexNew, to bypass loading it again from disk. */ -bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, const CBlock *pblock) { +bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const CBlock* pblock) +{ assert(pindexNew->pprev == chainActive.Tip()); - mempool.check(pcoinsTip); // Read block from disk. int64_t nTime1 = GetTimeMicros(); CBlock block; if (!pblock) { - if (!ReadBlockFromDisk(block, pindexNew)) + if (!ReadBlockFromDisk(block, pindexNew, chainparams.GetConsensus())) return AbortNode(state, "Failed to read block"); pblock = █ } @@ -2120,7 +2420,6 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, const CB // Remove conflicting transactions from the mempool. list<CTransaction> txConflicted; mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload()); - mempool.check(pcoinsTip); // Update chainActive & related variables. UpdateTip(pindexNew); // Tell wallet about transactions that went from mempool @@ -2213,16 +2512,19 @@ static void PruneBlockIndexCandidates() { * Try to make some progress towards making pindexMostWork the active block. * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. */ -static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, const CBlock *pblock) { +static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const CBlock* pblock) +{ AssertLockHeld(cs_main); bool fInvalidFound = false; const CBlockIndex *pindexOldTip = chainActive.Tip(); const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork); // Disconnect active blocks which are no longer in the best chain. + bool fBlocksDisconnected = false; while (chainActive.Tip() && chainActive.Tip() != pindexFork) { - if (!DisconnectTip(state)) + if (!DisconnectTip(state, chainparams.GetConsensus())) return false; + fBlocksDisconnected = true; } // Build list of new blocks to connect. @@ -2230,43 +2532,49 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo 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) { - if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) { - if (state.IsInvalid()) { - // The block violates a consensus rule. - if (!state.CorruptionPossible()) - InvalidChainFound(vpindexToConnect.back()); - state = CValidationState(); - fInvalidFound = true; - fContinue = false; - break; + // 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) { + if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) { + if (state.IsInvalid()) { + // The block violates a consensus rule. + if (!state.CorruptionPossible()) + InvalidChainFound(vpindexToConnect.back()); + state = CValidationState(); + fInvalidFound = true; + fContinue = false; + break; + } else { + // A system error occurred (disk space, database error, ...). + return false; + } } else { - // A system error occurred (disk space, database error, ...). - return false; - } - } else { - 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; + 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; + } } } } + + if (fBlocksDisconnected) { + mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); + LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); } + mempool.check(pcoinsTip); // Callbacks/notifications for a new best chain. if (fInvalidFound) @@ -2282,49 +2590,72 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo * or an activated best chain. pblock is either NULL or a pointer to a block * that is already loaded (to avoid loading it again from disk). */ -bool ActivateBestChain(CValidationState &state, const CBlock *pblock) { - CBlockIndex *pindexNewTip = NULL; +bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, const CBlock *pblock) { CBlockIndex *pindexMostWork = NULL; - const CChainParams& chainParams = Params(); do { boost::this_thread::interruption_point(); + CBlockIndex *pindexNewTip = NULL; + const CBlockIndex *pindexFork; bool fInitialDownload; { LOCK(cs_main); + CBlockIndex *pindexOldTip = chainActive.Tip(); pindexMostWork = FindMostWorkChain(); // Whether we have anything to do at all. if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip()) return true; - if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL)) + if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL)) return false; pindexNewTip = chainActive.Tip(); + pindexFork = chainActive.FindFork(pindexOldTip); fInitialDownload = IsInitialBlockDownload(); } // When we reach this point, we switched to a new tip (stored in pindexNewTip). // Notifications/callbacks that can run without cs_main - if (!fInitialDownload) { - uint256 hashNewTip = pindexNewTip->GetBlockHash(); - // Relay inventory, but don't relay old inventory during initial block download. - int nBlockEstimate = 0; - if (fCheckpointsEnabled) - nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()); - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) - pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip)); + // Always notify the UI if a new block tip was connected + if (pindexFork != pindexNewTip) { + uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip); + + if (!fInitialDownload) { + // Find the hashes of all blocks that weren't previously in the best chain. + std::vector<uint256> vHashes; + CBlockIndex *pindexToAnnounce = pindexNewTip; + while (pindexToAnnounce != pindexFork) { + vHashes.push_back(pindexToAnnounce->GetBlockHash()); + pindexToAnnounce = pindexToAnnounce->pprev; + if (vHashes.size() == MAX_BLOCKS_TO_ANNOUNCE) { + // Limit announcements in case of a huge reorganization. + // Rely on the peer's synchronization mechanism in that case. + break; + } + } + // Relay inventory, but don't relay old inventory during initial block download. + int nBlockEstimate = 0; + if (fCheckpointsEnabled) + nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()); + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) { + if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) { + BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) { + pnode->PushBlockHash(hash); + } + } + } + } + // Notify external listeners about the new tip. + if (!vHashes.empty()) { + GetMainSignals().UpdatedBlockTip(pindexNewTip); + } } - // Notify external listeners about the new tip. - GetMainSignals().UpdatedBlockTip(pindexNewTip); - uiInterface.NotifyBlockTip(hashNewTip); } } while(pindexMostWork != chainActive.Tip()); - CheckBlockIndex(); + CheckBlockIndex(chainparams.GetConsensus()); // Write changes periodically to disk, after relay. if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) { @@ -2334,7 +2665,8 @@ bool ActivateBestChain(CValidationState &state, const CBlock *pblock) { return true; } -bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { +bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex *pindex) +{ AssertLockHeld(cs_main); // Mark the block itself as invalid. @@ -2349,11 +2681,14 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { setBlockIndexCandidates.erase(pindexWalk); // ActivateBestChain considers blocks already in chainActive // unconditionally valid already, so force disconnect away from it. - if (!DisconnectTip(state)) { + if (!DisconnectTip(state, consensusParams)) { + mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); return false; } } + LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); + // The resulting new best tip may not be in setBlockIndexCandidates anymore, so // add it again. BlockMap::iterator it = mapBlockIndex.begin(); @@ -2365,6 +2700,7 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { } InvalidChainFound(pindex); + mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); return true; } @@ -2492,8 +2828,6 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd if (!fKnown) { while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) { - LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString()); - FlushBlockFile(true); nFile++; if (vinfoBlockFile.size() <= nFile) { vinfoBlockFile.resize(nFile + 1); @@ -2503,7 +2837,14 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd pos.nPos = vinfoBlockFile[nFile].nSize; } - nLastBlockFile = nFile; + if ((int)nFile != nLastBlockFile) { + if (!fKnown) { + LogPrintf("Leaving block file %i: %s\n", nLastBlockFile, vinfoBlockFile[nLastBlockFile].ToString()); + } + FlushBlockFile(!fKnown); + nLastBlockFile = nFile; + } + vinfoBlockFile[nFile].AddBlock(nHeight, nTime); if (fKnown) vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize); @@ -2594,7 +2935,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // Check the merkle root. if (fCheckMerkleRoot) { bool mutated; - uint256 hashMerkleRoot2 = block.ComputeMerkleRoot(&mutated); + uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated); if (block.hashMerkleRoot != hashMerkleRoot2) return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"), REJECT_INVALID, "bad-txnmrklroot", true); @@ -2639,7 +2980,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo } if (nSigOps > MAX_BLOCK_SIGOPS) return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"), - REJECT_INVALID, "bad-blk-sigops", true); + REJECT_INVALID, "bad-blk-sigops"); if (fCheckPOW && fCheckMerkleRoot) block.fChecked = true; @@ -2681,7 +3022,12 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded: if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) - return state.Invalid(error("%s : rejected nVersion=2 block", __func__), + return state.Invalid(error("%s: rejected nVersion=2 block", __func__), + REJECT_OBSOLETE, "bad-version"); + + // Reject block.nVersion=3 blocks when 95% (75% on testnet) of the network has upgraded: + if (block.nVersion < 4 && IsSuperMajority(4, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) + return state.Invalid(error("%s : rejected nVersion=3 block", __func__), REJECT_OBSOLETE, "bad-version"); return true; @@ -2693,10 +3039,15 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn const Consensus::Params& consensusParams = Params().GetConsensus(); // Check that all transactions are finalized - BOOST_FOREACH(const CTransaction& tx, block.vtx) - if (!IsFinalTx(tx, nHeight, block.GetBlockTime())) { + BOOST_FOREACH(const CTransaction& tx, block.vtx) { + int nLockTimeFlags = 0; + int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST) + ? pindexPrev->GetMedianTimePast() + : block.GetBlockTime(); + if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) { return state.DoS(10, 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): @@ -2712,9 +3063,8 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn return true; } -bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex) +static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex=NULL) { - const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); // Check for duplicate uint256 hash = block.GetHash(); @@ -2760,14 +3110,14 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc return true; } -bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp) +/** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */ +static bool AcceptBlock(const CBlock& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp) { - const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); CBlockIndex *&pindex = *ppindex; - if (!AcceptBlockHeader(block, state, &pindex)) + if (!AcceptBlockHeader(block, state, chainparams, &pindex)) return false; // Try to process all requested blocks that we don't have, but only @@ -2837,7 +3187,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned } -bool ProcessNewBlock(CValidationState &state, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp) +bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos* dbp) { // Preliminary checks bool checked = CheckBlock(*pblock, state); @@ -2852,24 +3202,23 @@ bool ProcessNewBlock(CValidationState &state, const CNode* pfrom, const CBlock* // Store to disk CBlockIndex *pindex = NULL; - bool ret = AcceptBlock(*pblock, state, &pindex, fRequested, dbp); + bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fRequested, dbp); if (pindex && pfrom) { mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId(); } - CheckBlockIndex(); + CheckBlockIndex(chainparams.GetConsensus()); if (!ret) return error("%s: AcceptBlock FAILED", __func__); } - if (!ActivateBestChain(state, pblock)) + if (!ActivateBestChain(state, chainparams, pblock)) return error("%s: ActivateBestChain failed", __func__); return true; } -bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) +bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) { - const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); assert(pindexPrev && pindexPrev == chainActive.Tip()); if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, block.GetHash())) @@ -2952,13 +3301,13 @@ void UnlinkPrunedFiles(std::set<int>& setFilesToPrune) } /* Calculate the block/rev files that should be deleted to remain under target*/ -void FindFilesToPrune(std::set<int>& setFilesToPrune) +void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight) { LOCK2(cs_main, cs_LastBlockFile); if (chainActive.Tip() == NULL || nPruneTarget == 0) { return; } - if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) { + if ((uint64_t)chainActive.Tip()->nHeight <= nPruneAfterHeight) { return; } @@ -3186,7 +3535,7 @@ CVerifyDB::~CVerifyDB() uiInterface.ShowProgress("", 100); } -bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth) +bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth) { LOCK(cs_main); if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL) @@ -3212,7 +3561,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth break; CBlock block; // check level 0: read from disk - if (!ReadBlockFromDisk(block, pindex)) + if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 1: verify block validity if (nCheckLevel >= 1 && !CheckBlock(block, state)) @@ -3252,7 +3601,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)))); pindex = chainActive.Next(pindex); CBlock block; - if (!ReadBlockFromDisk(block, pindex)) + if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); if (!ConnectBlock(block, state, pindex, coins)) return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); @@ -3303,9 +3652,8 @@ bool LoadBlockIndex() return true; } - -bool InitBlockIndex() { - const CChainParams& chainparams = Params(); +bool InitBlockIndex(const CChainParams& chainparams) +{ LOCK(cs_main); // Initialize global variables that cannot be constructed at startup. @@ -3316,14 +3664,14 @@ bool InitBlockIndex() { return true; // Use the provided setting for -txindex in the new database - fTxIndex = GetBoolArg("-txindex", false); + fTxIndex = GetBoolArg("-txindex", DEFAULT_TXINDEX); pblocktree->WriteFlag("txindex", fTxIndex); LogPrintf("Initializing databases...\n"); // Only add the genesis block if not reindexing (in which case we reuse the one already on disk) if (!fReindex) { try { - CBlock &block = const_cast<CBlock&>(Params().GenesisBlock()); + CBlock &block = const_cast<CBlock&>(chainparams.GenesisBlock()); // Start new block file unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); CDiskBlockPos blockPos; @@ -3335,7 +3683,7 @@ bool InitBlockIndex() { CBlockIndex *pindex = AddToBlockIndex(block); if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) return error("LoadBlockIndex(): genesis block not accepted"); - if (!ActivateBestChain(state, &block)) + if (!ActivateBestChain(state, chainparams, &block)) return error("LoadBlockIndex(): genesis block cannot be activated"); // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data return FlushStateToDisk(state, FLUSH_STATE_ALWAYS); @@ -3347,11 +3695,8 @@ bool InitBlockIndex() { return true; } - - -bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) +bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskBlockPos *dbp) { - const CChainParams& chainparams = Params(); // Map of disk positions for blocks with unknown parent (only used for reindex) static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent; int64_t nStart = GetTimeMillis(); @@ -3371,10 +3716,10 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) try { // locate a header unsigned char buf[MESSAGE_START_SIZE]; - blkdat.FindByte(Params().MessageStart()[0]); + blkdat.FindByte(chainparams.MessageStart()[0]); nRewind = blkdat.GetPos()+1; blkdat >> FLATDATA(buf); - if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE)) + if (memcmp(buf, chainparams.MessageStart(), MESSAGE_START_SIZE)) continue; // read size blkdat >> nSize; @@ -3408,7 +3753,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) // process in case the block isn't known yet if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) { CValidationState state; - if (ProcessNewBlock(state, NULL, &block, true, dbp)) + if (ProcessNewBlock(state, chainparams, NULL, &block, true, dbp)) nLoaded++; if (state.IsError()) break; @@ -3425,12 +3770,12 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) 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)) + if (ReadBlockFromDisk(block, it->second, chainparams.GetConsensus())) { LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(), head.ToString()); CValidationState dummy; - if (ProcessNewBlock(dummy, NULL, &block, true, &it->second)) + if (ProcessNewBlock(dummy, chainparams, NULL, &block, true, &it->second)) { nLoaded++; queue.push_back(block.GetHash()); @@ -3452,9 +3797,8 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) return nLoaded > 0; } -void static CheckBlockIndex() +void static CheckBlockIndex(const Consensus::Params& consensusParams) { - const Consensus::Params& consensusParams = Params().GetConsensus(); if (!fCheckBlockIndex) { return; } @@ -3647,29 +3991,34 @@ std::string GetWarnings(const std::string& strFor) int nPriority = 0; string strStatusBar; string strRPC; + string strGUI; - 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 (!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"; + strGUI = _("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"; + if (GetBoolArg("-testsafemode", DEFAULT_TESTSAFEMODE)) + strStatusBar = strRPC = strGUI = "testsafemode enabled"; // Misc warnings like out of disk space and clock is wrong if (strMiscWarning != "") { nPriority = 1000; - strStatusBar = strMiscWarning; + strStatusBar = strGUI = strMiscWarning; } if (fLargeWorkForkFound) { nPriority = 2000; - strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."); + strStatusBar = strRPC = "Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."; + strGUI = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."); } else if (fLargeWorkInvalidChainFound) { nPriority = 2000; - strStatusBar = strRPC = _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."); + strStatusBar = strRPC = "Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."; + strGUI = _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."); } // Alerts @@ -3681,12 +4030,14 @@ std::string GetWarnings(const std::string& strFor) if (alert.AppliesToMe() && alert.nPriority > nPriority) { nPriority = alert.nPriority; - strStatusBar = alert.strStatusBar; + strStatusBar = strGUI = alert.strStatusBar; } } } - if (strFor == "statusbar") + if (strFor == "gui") + return strGUI; + else if (strFor == "statusbar") return strStatusBar; else if (strFor == "rpc") return strRPC; @@ -3736,7 +4087,7 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) return true; } -void static ProcessGetData(CNode* pfrom) +void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParams) { std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin(); @@ -3769,29 +4120,40 @@ void static ProcessGetData(CNode* pfrom) // best equivalent proof of work) than the best header chain we know about. send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) && - (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth); + (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, consensusParams) < nOneMonth); if (!send) { LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId()); } } } + // disconnect node in case we have reached the outbound limit for serving historical blocks + // never disconnect whitelisted nodes + static const int nOneWeek = 7 * 24 * 60 * 60; // assume > 1 week = historical + if (send && CNode::OutboundTargetReached(true) && ( ((pindexBestHeader != NULL) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() > nOneWeek)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted) + { + LogPrint("net", "historical block serving limit reached, disconnect peer=%d\n", pfrom->GetId()); + + //disconnect node + pfrom->fDisconnect = true; + send = false; + } // Pruned nodes may have deleted the block, so check whether // it's available before trying to send. if (send && (mi->second->nStatus & BLOCK_HAVE_DATA)) { // Send block from disk CBlock block; - if (!ReadBlockFromDisk(block, (*mi).second)) + if (!ReadBlockFromDisk(block, (*mi).second, consensusParams)) assert(!"cannot load block from disk"); if (inv.type == MSG_BLOCK) - pfrom->PushMessage("block", block); + pfrom->PushMessage(NetMsgType::BLOCK, block); else // MSG_FILTERED_BLOCK) { LOCK(pfrom->cs_filter); if (pfrom->pfilter) { CMerkleBlock merkleBlock(block, *pfrom->pfilter); - pfrom->PushMessage("merkleblock", merkleBlock); + pfrom->PushMessage(NetMsgType::MERKLEBLOCK, merkleBlock); // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see // This avoids hurting performance by pointlessly requiring a round-trip // Note that there is currently no way for a node to request any single transactions we didn't send here - @@ -3800,8 +4162,7 @@ void static ProcessGetData(CNode* pfrom) // however we MUST always provide at least what the remote peer needs typedef std::pair<unsigned int, uint256> PairType; BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn) - if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second))) - pfrom->PushMessage("tx", block.vtx[pair.first]); + pfrom->PushMessage(NetMsgType::TX, block.vtx[pair.first]); } // else // no response @@ -3815,7 +4176,7 @@ void static ProcessGetData(CNode* pfrom) // wait for other stuff first. vector<CInv> vInv; vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash())); - pfrom->PushMessage("inv", vInv); + pfrom->PushMessage(NetMsgType::INV, vInv); pfrom->hashContinue.SetNull(); } } @@ -3838,7 +4199,7 @@ void static ProcessGetData(CNode* pfrom) CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss.reserve(1000); ss << tx; - pfrom->PushMessage("tx", ss); + pfrom->PushMessage(NetMsgType::TX, ss); pushed = true; } } @@ -3865,7 +4226,7 @@ void static ProcessGetData(CNode* pfrom) // do that because they want to know about (and store and rebroadcast and // risk analyze) the dependencies of transactions relevant to them, without // having to download the entire memory pool. - pfrom->PushMessage("notfound", vNotFound); + pfrom->PushMessage(NetMsgType::NOTFOUND, vNotFound); } } @@ -3881,14 +4242,27 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } + if (!(nLocalServices & NODE_BLOOM) && + (strCommand == NetMsgType::FILTERLOAD || + strCommand == NetMsgType::FILTERADD || + strCommand == NetMsgType::FILTERCLEAR)) + { + if (pfrom->nVersion >= NO_BLOOM_VERSION) { + Misbehaving(pfrom->GetId(), 100); + return false; + } else if (GetBoolArg("-enforcenodebloom", false)) { + pfrom->fDisconnect = true; + return false; + } + } - if (strCommand == "version") + if (strCommand == NetMsgType::VERSION) { // Each connection can only send one version message if (pfrom->nVersion != 0) { - pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message")); + pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_DUPLICATE, string("Duplicate version message")); Misbehaving(pfrom->GetId(), 1); return false; } @@ -3902,7 +4276,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { // disconnect from peers older than this proto version LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion); - pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE, + pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION)); pfrom->fDisconnect = true; return false; @@ -3947,7 +4321,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, UpdatePreferredDownload(pfrom, State(pfrom->GetId())); // Change version - pfrom->PushMessage("verack"); + pfrom->PushMessage(NetMsgType::VERACK); pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); if (!pfrom->fInbound) @@ -3958,9 +4332,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CAddress addr = GetLocalAddress(&pfrom->addr); if (addr.IsRoutable()) { + LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString()); pfrom->PushAddress(addr); } else if (IsPeerAddrLocalGood(pfrom)) { addr.SetIP(pfrom->addrLocal); + LogPrintf("ProcessMessages: advertizing address %s\n", addr.ToString()); pfrom->PushAddress(addr); } } @@ -3968,7 +4344,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Get recent addresses if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000) { - pfrom->PushMessage("getaddr"); + pfrom->PushMessage(NetMsgType::GETADDR); pfrom->fGetAddr = true; } addrman.Good(pfrom->addr); @@ -4012,7 +4388,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "verack") + else if (strCommand == NetMsgType::VERACK) { pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); @@ -4021,10 +4397,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LOCK(cs_main); State(pfrom->GetId())->fCurrentlyConnected = true; } + + if (pfrom->nVersion >= SENDHEADERS_VERSION) { + // Tell our peer we prefer to receive headers rather than inv's + // We send this to non-NODE NETWORK peers as well, because even + // non-NODE NETWORK peers can announce blocks (such as pruning + // nodes) + pfrom->PushMessage(NetMsgType::SENDHEADERS); + } } - else if (strCommand == "addr") + else if (strCommand == NetMsgType::ADDR) { vector<CAddress> vAddr; vRecv >> vAddr; @@ -4090,8 +4474,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->fDisconnect = true; } + else if (strCommand == NetMsgType::SENDHEADERS) + { + LOCK(cs_main); + State(pfrom->GetId())->fPreferHeaders = true; + } + - else if (strCommand == "inv") + else if (strCommand == NetMsgType::INV) { vector<CInv> vInv; vRecv >> vInv; @@ -4101,6 +4491,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return error("message inv size() = %u", vInv.size()); } + bool fBlocksOnly = GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY); + + // Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistalwaysrelay is true + if (pfrom->fWhitelisted && GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY)) + fBlocksOnly = false; + LOCK(cs_main); std::vector<CInv> vToFetch; @@ -4115,9 +4511,6 @@ 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 && !fImporting && !fReindex && inv.type != MSG_BLOCK) - pfrom->AskFor(inv); - if (inv.type == MSG_BLOCK) { UpdateBlockAvailability(pfrom->GetId(), inv.hash); if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) { @@ -4129,9 +4522,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // time the block arrives, the header chain leading up to it is already validated. Not // doing this will result in the received block being rejected as an orphan in case it is // not a direct successor. - pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash); + pfrom->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), inv.hash); CNodeState *nodestate = State(pfrom->GetId()); - if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 && + if (CanDirectFetch(chainparams.GetConsensus()) && 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 @@ -4141,6 +4534,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id); } } + else + { + if (fBlocksOnly) + LogPrint("net", "transaction (%s) inv sent in violation of protocol peer=%d\n", inv.hash.ToString(), pfrom->id); + else if (!fAlreadyHave && !fImporting && !fReindex) + pfrom->AskFor(inv); + } // Track requests for our stuff GetMainSignals().Inventory(inv.hash); @@ -4152,11 +4552,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } if (!vToFetch.empty()) - pfrom->PushMessage("getdata", vToFetch); + pfrom->PushMessage(NetMsgType::GETDATA, vToFetch); } - else if (strCommand == "getdata") + else if (strCommand == NetMsgType::GETDATA) { vector<CInv> vInv; vRecv >> vInv; @@ -4173,11 +4573,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id); pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end()); - ProcessGetData(pfrom); + ProcessGetData(pfrom, chainparams.GetConsensus()); } - else if (strCommand == "getblocks") + else if (strCommand == NetMsgType::GETBLOCKS) { CBlockLocator locator; uint256 hashStop; @@ -4221,17 +4621,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "getheaders") + else if (strCommand == NetMsgType::GETHEADERS) { CBlockLocator locator; uint256 hashStop; vRecv >> locator >> hashStop; LOCK(cs_main); - - if (IsInitialBlockDownload()) + if (IsInitialBlockDownload() && !pfrom->fWhitelisted) { + LogPrint("net", "Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom->id); return true; + } + CNodeState *nodestate = State(pfrom->GetId()); CBlockIndex* pindex = NULL; if (locator.IsNull()) { @@ -4259,12 +4661,25 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop) break; } - pfrom->PushMessage("headers", vHeaders); + // pindex can be NULL either if we sent chainActive.Tip() OR + // if our peer has chainActive.Tip() (and thus we are sending an empty + // headers message). In both cases it's safe to update + // pindexBestHeaderSent to be our tip. + nodestate->pindexBestHeaderSent = pindex ? pindex : chainActive.Tip(); + pfrom->PushMessage(NetMsgType::HEADERS, vHeaders); } - else if (strCommand == "tx") + else if (strCommand == NetMsgType::TX) { + // Stop processing the transaction early if + // We are in blocks only mode and peer is either not whitelisted or whitelistalwaysrelay is off + if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY))) + { + LogPrint("net", "transaction sent in violation of protocol peer=%d\n", pfrom->id); + return true; + } + vector<uint256> vWorkQueue; vector<uint256> vEraseQueue; CTransaction tx; @@ -4278,22 +4693,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, bool fMissingInputs = false; CValidationState state; + pfrom->setAskFor.erase(inv.hash); mapAlreadyAskedFor.erase(inv); - // Check for recently rejected (and do other quick existence checks) - if (AlreadyHave(inv)) - return true; - - if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs)) + if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs)) { mempool.check(pcoinsTip); RelayTransaction(tx); vWorkQueue.push_back(inv.hash); - LogPrint("mempool", "AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u)\n", + LogPrint("mempool", "AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u txn, %u kB)\n", pfrom->id, tx.GetHash().ToString(), - mempool.size()); + mempool.size(), mempool.DynamicMemoryUsage() / 1000); // Recursively process any orphan transactions that depended on this one set<NodeId> setMisbehaving; @@ -4362,15 +4774,22 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, assert(recentRejects); recentRejects->insert(tx.GetHash()); - if (pfrom->fWhitelisted) { + if (pfrom->fWhitelisted && GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY)) { // Always relay transactions received from whitelisted peers, even - // if they were rejected from the mempool, allowing the node to - // function as a gateway for nodes hidden behind it. + // if they were already in the mempool or rejected from it due + // to policy, allowing the node to function as a gateway for + // nodes hidden behind it. // - // FIXME: This includes invalid transactions, which means a - // whitelisted peer could get us banned! We may want to change - // that. - RelayTransaction(tx); + // Never relay transactions that we would assign a non-zero DoS + // score for, as we expect peers to do the same with us in that + // case. + int nDoS = 0; + if (!state.IsInvalid(nDoS) || nDoS == 0) { + LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id); + RelayTransaction(tx); + } else { + LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s)\n", tx.GetHash().ToString(), pfrom->id, FormatStateMessage(state)); + } } } int nDoS = 0; @@ -4380,15 +4799,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->id, FormatStateMessage(state)); if (state.GetRejectCode() < REJECT_INTERNAL) // Never send AcceptToMemoryPool's internal codes over P2P - pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), + pfrom->PushMessage(NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) Misbehaving(pfrom->GetId(), nDoS); } + FlushStateToDisk(state, FLUSH_STATE_PERIODIC); } - else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing + else if (strCommand == NetMsgType::HEADERS && !fImporting && !fReindex) // Ignore headers received while importing { std::vector<CBlockHeader> headers; @@ -4418,7 +4838,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, Misbehaving(pfrom->GetId(), 20); return error("non-continuous headers sequence"); } - if (!AcceptBlockHeader(header, state, &pindexLast)) { + if (!AcceptBlockHeader(header, state, chainparams, &pindexLast)) { int nDoS; if (state.IsInvalid(nDoS)) { if (nDoS > 0) @@ -4436,13 +4856,60 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue // from there instead. LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight); - pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256()); + pfrom->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexLast), uint256()); + } + + bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus()); + CNodeState *nodestate = State(pfrom->GetId()); + // If this set of headers is valid and ends in a block with at least as + // much work as our tip, download as much as possible. + if (fCanDirectFetch && pindexLast->IsValid(BLOCK_VALID_TREE) && chainActive.Tip()->nChainWork <= pindexLast->nChainWork) { + vector<CBlockIndex *> vToFetch; + CBlockIndex *pindexWalk = pindexLast; + // Calculate all the blocks we'd need to switch to pindexLast, up to a limit. + while (pindexWalk && !chainActive.Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) { + if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) && + !mapBlocksInFlight.count(pindexWalk->GetBlockHash())) { + // We don't have this block, and it's not yet in flight. + vToFetch.push_back(pindexWalk); + } + pindexWalk = pindexWalk->pprev; + } + // If pindexWalk still isn't on our main chain, we're looking at a + // very large reorg at a time we think we're close to caught up to + // the main chain -- this shouldn't really happen. Bail out on the + // direct fetch and rely on parallel download instead. + if (!chainActive.Contains(pindexWalk)) { + LogPrint("net", "Large reorg, won't direct fetch to %s (%d)\n", + pindexLast->GetBlockHash().ToString(), + pindexLast->nHeight); + } else { + vector<CInv> vGetData; + // Download as much as possible, from earliest to latest. + BOOST_REVERSE_FOREACH(CBlockIndex *pindex, vToFetch) { + if (nodestate->nBlocksInFlight >= MAX_BLOCKS_IN_TRANSIT_PER_PEER) { + // Can't download any more from this peer + break; + } + vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash())); + MarkBlockAsInFlight(pfrom->GetId(), pindex->GetBlockHash(), chainparams.GetConsensus(), pindex); + LogPrint("net", "Requesting block %s from peer=%d\n", + pindex->GetBlockHash().ToString(), pfrom->id); + } + if (vGetData.size() > 1) { + LogPrint("net", "Downloading blocks toward %s (%d) via headers direct fetch\n", + pindexLast->GetBlockHash().ToString(), pindexLast->nHeight); + } + if (vGetData.size() > 0) { + pfrom->PushMessage(NetMsgType::GETDATA, vGetData); + } + } } - CheckBlockIndex(); + CheckBlockIndex(chainparams.GetConsensus()); } - else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing + else if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) // Ignore blocks received while importing { CBlock block; vRecv >> block; @@ -4458,11 +4925,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Such an unrequested block may still be processed, subject to the // conditions in AcceptBlock(). bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload(); - ProcessNewBlock(state, pfrom, &block, forceProcessing, NULL); + ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL); int nDoS; if (state.IsInvalid(nDoS)) { assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes - pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), + pfrom->PushMessage(NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) { LOCK(cs_main); @@ -4478,7 +4945,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // to users' AddrMan and later request them by sending getaddr messages. // Making nodes which are behind NAT and can only make outgoing connections ignore // the getaddr message mitigates the attack. - else if ((strCommand == "getaddr") && (pfrom->fInbound)) + else if ((strCommand == NetMsgType::GETADDR) && (pfrom->fInbound)) { pfrom->vAddrToSend.clear(); vector<CAddress> vAddr = addrman.GetAddr(); @@ -4487,8 +4954,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "mempool") + else if (strCommand == NetMsgType::MEMPOOL) { + if (CNode::OutboundTargetReached(false) && !pfrom->fWhitelisted) + { + LogPrint("net", "mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom->GetId()); + pfrom->fDisconnect = true; + return true; + } LOCK2(cs_main, pfrom->cs_filter); std::vector<uint256> vtxid; @@ -4496,23 +4969,24 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vector<CInv> vInv; BOOST_FOREACH(uint256& hash, vtxid) { CInv inv(MSG_TX, hash); - CTransaction tx; - bool fInMemPool = mempool.lookup(hash, tx); - if (!fInMemPool) continue; // another thread removed since queryHashes, maybe... - if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx)) || - (!pfrom->pfilter)) - vInv.push_back(inv); + if (pfrom->pfilter) { + CTransaction tx; + bool fInMemPool = mempool.lookup(hash, tx); + if (!fInMemPool) continue; // another thread removed since queryHashes, maybe... + if (!pfrom->pfilter->IsRelevantAndUpdate(tx)) continue; + } + vInv.push_back(inv); if (vInv.size() == MAX_INV_SZ) { - pfrom->PushMessage("inv", vInv); + pfrom->PushMessage(NetMsgType::INV, vInv); vInv.clear(); } } if (vInv.size() > 0) - pfrom->PushMessage("inv", vInv); + pfrom->PushMessage(NetMsgType::INV, vInv); } - else if (strCommand == "ping") + else if (strCommand == NetMsgType::PING) { if (pfrom->nVersion > BIP0031_VERSION) { @@ -4529,12 +5003,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // it, if the remote node sends a ping once per second and this node takes 5 // seconds to respond to each, the 5th ping the remote sends would appear to // return very quickly. - pfrom->PushMessage("pong", nonce); + pfrom->PushMessage(NetMsgType::PONG, nonce); } } - else if (strCommand == "pong") + else if (strCommand == NetMsgType::PONG) { int64_t pingUsecEnd = nTimeReceived; uint64_t nonce = 0; @@ -4591,7 +5065,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (fAlerts && strCommand == "alert") + else if (fAlerts && strCommand == NetMsgType::ALERT) { CAlert alert; vRecv >> alert; @@ -4599,7 +5073,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, uint256 alertHash = alert.GetHash(); if (pfrom->setKnown.count(alertHash) == 0) { - if (alert.ProcessAlert(Params().AlertKey())) + if (alert.ProcessAlert(chainparams.AlertKey())) { // Relay pfrom->setKnown.insert(alertHash); @@ -4622,22 +5096,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (!(nLocalServices & NODE_BLOOM) && - (strCommand == "filterload" || - strCommand == "filteradd" || - strCommand == "filterclear") && - //TODO: Remove this line after reasonable network upgrade - pfrom->nVersion >= NO_BLOOM_VERSION) - { - if (pfrom->nVersion >= NO_BLOOM_VERSION) - Misbehaving(pfrom->GetId(), 100); - //TODO: Enable this after reasonable network upgrade - //else - // pfrom->fDisconnect = true; - } - - - else if (strCommand == "filterload") + else if (strCommand == NetMsgType::FILTERLOAD) { CBloomFilter filter; vRecv >> filter; @@ -4656,7 +5115,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "filteradd") + else if (strCommand == NetMsgType::FILTERADD) { vector<unsigned char> vData; vRecv >> vData; @@ -4676,7 +5135,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "filterclear") + else if (strCommand == NetMsgType::FILTERCLEAR) { LOCK(pfrom->cs_filter); delete pfrom->pfilter; @@ -4685,7 +5144,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "reject") + else if (strCommand == NetMsgType::REJECT) { if (fDebug) { try { @@ -4695,7 +5154,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, ostringstream ss; ss << strMsg << " code " << itostr(ccode) << ": " << strReason; - if (strMsg == "block" || strMsg == "tx") + if (strMsg == NetMsgType::BLOCK || strMsg == NetMsgType::TX) { uint256 hash; vRecv >> hash; @@ -4723,6 +5182,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // requires LOCK(cs_vRecvMsg) bool ProcessMessages(CNode* pfrom) { + const CChainParams& chainparams = Params(); //if (fDebug) // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size()); @@ -4737,7 +5197,7 @@ bool ProcessMessages(CNode* pfrom) bool fOk = true; if (!pfrom->vRecvGetData.empty()) - ProcessGetData(pfrom); + ProcessGetData(pfrom, chainparams.GetConsensus()); // this maintains the order of responses if (!pfrom->vRecvGetData.empty()) return fOk; @@ -4764,7 +5224,7 @@ bool ProcessMessages(CNode* pfrom) it++; // Scan for message start - if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) { + if (memcmp(msg.hdr.pchMessageStart, chainparams.MessageStart(), MESSAGE_START_SIZE) != 0) { LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id); fOk = false; break; @@ -4772,7 +5232,7 @@ bool ProcessMessages(CNode* pfrom) // Read header CMessageHeader& hdr = msg.hdr; - if (!hdr.IsValid(Params().MessageStart())) + if (!hdr.IsValid(chainparams.MessageStart())) { LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id); continue; @@ -4802,7 +5262,7 @@ bool ProcessMessages(CNode* pfrom) } catch (const std::ios_base::failure& e) { - pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message")); + pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_MALFORMED, string("error parsing message")); if (strstr(e.what(), "end of data")) { // Allow exceptions from under-length message on vRecv @@ -4841,7 +5301,7 @@ bool ProcessMessages(CNode* pfrom) } -bool SendMessages(CNode* pto, bool fSendTrickle) +bool SendMessages(CNode* pto) { const Consensus::Params& consensusParams = Params().GetConsensus(); { @@ -4870,11 +5330,11 @@ bool SendMessages(CNode* pto, bool fSendTrickle) pto->nPingUsecStart = GetTimeMicros(); if (pto->nVersion > BIP0031_VERSION) { pto->nPingNonceSent = nonce; - pto->PushMessage("ping", nonce); + pto->PushMessage(NetMsgType::PING, nonce); } else { // Peer is too old to support ping command with nonce, pong will never arrive. pto->nPingNonceSent = 0; - pto->PushMessage("ping"); + pto->PushMessage(NetMsgType::PING); } } @@ -4883,28 +5343,17 @@ bool SendMessages(CNode* pto, bool fSendTrickle) return true; // Address refresh broadcast - static int64_t nLastRebroadcast; - if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60)) - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - { - // Periodically clear addrKnown to allow refresh broadcasts - if (nLastRebroadcast) - pnode->addrKnown.reset(); - - // Rebroadcast our address - AdvertizeLocal(pnode); - } - if (!vNodes.empty()) - nLastRebroadcast = GetTime(); + int64_t nNow = GetTimeMicros(); + if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) { + AdvertizeLocal(pto); + pto->nNextLocalAddrSend = PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL); } // // Message: addr // - if (fSendTrickle) - { + if (pto->nNextAddrSend < nNow) { + pto->nNextAddrSend = PoissonNextSend(nNow, AVG_ADDRESS_BROADCAST_INTERVAL); vector<CAddress> vAddr; vAddr.reserve(pto->vAddrToSend.size()); BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend) @@ -4916,14 +5365,14 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // receiver rejects addr messages larger than 1000 if (vAddr.size() >= 1000) { - pto->PushMessage("addr", vAddr); + pto->PushMessage(NetMsgType::ADDR, vAddr); vAddr.clear(); } } } pto->vAddrToSend.clear(); if (!vAddr.empty()) - pto->PushMessage("addr", vAddr); + pto->PushMessage(NetMsgType::ADDR, vAddr); } CNodeState &state = *State(pto->GetId()); @@ -4943,7 +5392,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } BOOST_FOREACH(const CBlockReject& reject, state.rejects) - pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock); + pto->PushMessage(NetMsgType::REJECT, (string)NetMsgType::BLOCK, reject.chRejectCode, reject.strRejectReason, reject.hashBlock); state.rejects.clear(); // Start block sync @@ -4955,9 +5404,18 @@ bool SendMessages(CNode* pto, bool fSendTrickle) if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) { state.fSyncStarted = true; nSyncStarted++; - CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader; + const CBlockIndex *pindexStart = pindexBestHeader; + /* If possible, start at the block preceding the currently + best known header. This ensures that we always get a + non-empty list of headers back as long as the peer + is up-to-date. With a non-empty response, we can initialise + the peer's known best block. This wouldn't be possible + if we requested starting at pindexBestHeader and + got back an empty response. */ + if (pindexStart->pprev) + pindexStart = pindexStart->pprev; LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight); - pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256()); + pto->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexStart), uint256()); } } @@ -4970,17 +5428,116 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } // + // Try sending block announcements via headers + // + { + // If we have less than MAX_BLOCKS_TO_ANNOUNCE in our + // list of block hashes we're relaying, and our peer wants + // headers announcements, then find the first header + // not yet known to our peer but would connect, and send. + // If no header would connect, or if we have too many + // blocks, or if the peer doesn't want headers, just + // add all to the inv queue. + LOCK(pto->cs_inventory); + vector<CBlock> vHeaders; + bool fRevertToInv = (!state.fPreferHeaders || pto->vBlockHashesToAnnounce.size() > MAX_BLOCKS_TO_ANNOUNCE); + CBlockIndex *pBestIndex = NULL; // last header queued for delivery + ProcessBlockAvailability(pto->id); // ensure pindexBestKnownBlock is up-to-date + + if (!fRevertToInv) { + bool fFoundStartingHeader = false; + // Try to find first header that our peer doesn't have, and + // then send all headers past that one. If we come across any + // headers that aren't on chainActive, give up. + BOOST_FOREACH(const uint256 &hash, pto->vBlockHashesToAnnounce) { + BlockMap::iterator mi = mapBlockIndex.find(hash); + assert(mi != mapBlockIndex.end()); + CBlockIndex *pindex = mi->second; + if (chainActive[pindex->nHeight] != pindex) { + // Bail out if we reorged away from this block + fRevertToInv = true; + break; + } + assert(pBestIndex == NULL || pindex->pprev == pBestIndex); + pBestIndex = pindex; + if (fFoundStartingHeader) { + // add this to the headers message + vHeaders.push_back(pindex->GetBlockHeader()); + } else if (PeerHasHeader(&state, pindex)) { + continue; // keep looking for the first new block + } else if (pindex->pprev == NULL || PeerHasHeader(&state, pindex->pprev)) { + // Peer doesn't have this header but they do have the prior one. + // Start sending headers. + fFoundStartingHeader = true; + vHeaders.push_back(pindex->GetBlockHeader()); + } else { + // Peer doesn't have this header or the prior one -- nothing will + // connect, so bail out. + fRevertToInv = true; + break; + } + } + } + if (fRevertToInv) { + // If falling back to using an inv, just try to inv the tip. + // The last entry in vBlockHashesToAnnounce was our tip at some point + // in the past. + if (!pto->vBlockHashesToAnnounce.empty()) { + const uint256 &hashToAnnounce = pto->vBlockHashesToAnnounce.back(); + BlockMap::iterator mi = mapBlockIndex.find(hashToAnnounce); + assert(mi != mapBlockIndex.end()); + CBlockIndex *pindex = mi->second; + + // Warn if we're announcing a block that is not on the main chain. + // This should be very rare and could be optimized out. + // Just log for now. + if (chainActive[pindex->nHeight] != pindex) { + LogPrint("net", "Announcing block %s not on main chain (tip=%s)\n", + hashToAnnounce.ToString(), chainActive.Tip()->GetBlockHash().ToString()); + } + + // If the peer announced this block to us, don't inv it back. + // (Since block announcements may not be via inv's, we can't solely rely on + // setInventoryKnown to track this.) + if (!PeerHasHeader(&state, pindex)) { + pto->PushInventory(CInv(MSG_BLOCK, hashToAnnounce)); + LogPrint("net", "%s: sending inv peer=%d hash=%s\n", __func__, + pto->id, hashToAnnounce.ToString()); + } + } + } else if (!vHeaders.empty()) { + if (vHeaders.size() > 1) { + LogPrint("net", "%s: %u headers, range (%s, %s), to peer=%d\n", __func__, + vHeaders.size(), + vHeaders.front().GetHash().ToString(), + vHeaders.back().GetHash().ToString(), pto->id); + } else { + LogPrint("net", "%s: sending header %s to peer=%d\n", __func__, + vHeaders.front().GetHash().ToString(), pto->id); + } + pto->PushMessage(NetMsgType::HEADERS, vHeaders); + state.pindexBestHeaderSent = pBestIndex; + } + pto->vBlockHashesToAnnounce.clear(); + } + + // // Message: inventory // vector<CInv> vInv; vector<CInv> vInvWait; { + bool fSendTrickle = pto->fWhitelisted; + if (pto->nNextInvSend < nNow) { + fSendTrickle = true; + pto->nNextInvSend = PoissonNextSend(nNow, AVG_INVENTORY_BROADCAST_INTERVAL); + } LOCK(pto->cs_inventory); - vInv.reserve(pto->vInventoryToSend.size()); + vInv.reserve(std::min<size_t>(1000, pto->vInventoryToSend.size())); vInvWait.reserve(pto->vInventoryToSend.size()); BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend) { - if (pto->setInventoryKnown.count(inv)) + if (inv.type == MSG_TX && pto->filterInventoryKnown.contains(inv.hash)) continue; // trickle out tx inv to protect privacy @@ -5001,24 +5558,22 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } } - // returns true if wasn't already contained in the set - if (pto->setInventoryKnown.insert(inv).second) + pto->filterInventoryKnown.insert(inv.hash); + + vInv.push_back(inv); + if (vInv.size() >= 1000) { - vInv.push_back(inv); - if (vInv.size() >= 1000) - { - pto->PushMessage("inv", vInv); - vInv.clear(); - } + pto->PushMessage(NetMsgType::INV, vInv); + vInv.clear(); } } pto->vInventoryToSend = vInvWait; } if (!vInv.empty()) - pto->PushMessage("inv", vInv); + pto->PushMessage(NetMsgType::INV, vInv); // Detect whether we're stalling - int64_t nNow = GetTimeMicros(); + nNow = GetTimeMicros(); if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) { // Stalling only triggers when the block download window cannot move. During normal steady state, // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection @@ -5084,14 +5639,17 @@ bool SendMessages(CNode* pto, bool fSendTrickle) vGetData.push_back(inv); if (vGetData.size() >= 1000) { - pto->PushMessage("getdata", vGetData); + pto->PushMessage(NetMsgType::GETDATA, vGetData); vGetData.clear(); } + } else { + //If we're not going to ask, don't expect a response. + pto->setAskFor.erase(inv.hash); } pto->mapAskFor.erase(pto->mapAskFor.begin()); } if (!vGetData.empty()) - pto->PushMessage("getdata", vGetData); + pto->PushMessage(NetMsgType::GETDATA, vGetData); } return true; diff --git a/src/main.h b/src/main.h index a6001eed8f..cefaedabf5 100644 --- a/src/main.h +++ b/src/main.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -31,6 +31,7 @@ class CBlockIndex; class CBlockTreeDB; class CBloomFilter; +class CChainParams; class CInv; class CScriptCheck; class CTxMemPool; @@ -41,22 +42,29 @@ struct CNodeStateStats; /** Default for accepting alerts from the P2P network. */ static const bool DEFAULT_ALERTS = true; +/** Default for DEFAULT_WHITELISTALWAYSRELAY. */ +static const bool DEFAULT_WHITELISTALWAYSRELAY = true; +/** Default for -minrelaytxfee, minimum relay fee for transactions */ +static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; /** Default for -limitancestorcount, max number of in-mempool ancestors */ -static const unsigned int DEFAULT_ANCESTOR_LIMIT = 100; +static const unsigned int DEFAULT_ANCESTOR_LIMIT = 25; /** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */ -static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 900; +static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 101; /** Default for -limitdescendantcount, max number of in-mempool descendants */ -static const unsigned int DEFAULT_DESCENDANT_LIMIT = 1000; +static const unsigned int DEFAULT_DESCENDANT_LIMIT = 25; /** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */ -static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 2500; +static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 101; +/** Default for -mempoolexpiry, expiration time for mempool transactions in hours */ +static const unsigned int DEFAULT_MEMPOOL_EXPIRY = 72; /** 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) */ static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB /** The pre-allocation chunk size for rev?????.dat files (since 0.8) */ static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB + /** Maximum number of script-checking threads allowed */ static const int MAX_SCRIPTCHECK_THREADS = 16; /** -par default (number of script-checking threads, 0 = auto) */ @@ -79,6 +87,28 @@ static const unsigned int DATABASE_WRITE_INTERVAL = 60 * 60; static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60; /** Maximum length of reject messages. */ static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111; +/** Average delay between local address broadcasts in seconds. */ +static const unsigned int AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 24 * 60; +/** Average delay between peer address broadcasts in seconds. */ +static const unsigned int AVG_ADDRESS_BROADCAST_INTERVAL = 30; +/** Average delay between trickled inventory broadcasts in seconds. + * Blocks, whitelisted receivers, and a random 25% of transactions bypass this. */ +static const unsigned int AVG_INVENTORY_BROADCAST_INTERVAL = 5; + +static const unsigned int DEFAULT_LIMITFREERELAY = 15; +static const bool DEFAULT_RELAYPRIORITY = true; + +/** Default for -permitbaremultisig */ +static const bool DEFAULT_PERMIT_BAREMULTISIG = true; +static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20; +static const bool DEFAULT_CHECKPOINTS_ENABLED = true; +static const bool DEFAULT_TXINDEX = false; +static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100; + +static const bool DEFAULT_TESTSAFEMODE = false; + +/** Maximum number of headers to announce when relaying blocks with headers message.*/ +static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8; struct BlockHasher { @@ -101,6 +131,7 @@ extern int nScriptCheckThreads; extern bool fTxIndex; extern bool fIsBareMultisigStd; extern bool fRequireStandard; +extern unsigned int nBytesPerSigOp; extern bool fCheckBlockIndex; extern bool fCheckpointsEnabled; extern size_t nCoinCacheUsage; @@ -123,6 +154,9 @@ extern uint64_t nPruneTarget; /** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of chainActive.Tip() will not be pruned. */ static const unsigned int MIN_BLOCKS_TO_KEEP = 288; +static const signed int DEFAULT_CHECKBLOCKS = MIN_BLOCKS_TO_KEEP; +static const unsigned int DEFAULT_CHECKLEVEL = 3; + // Require that user allocate at least 550MB for block & undo files (blk???.dat and rev???.dat) // At 1MB per block, 288 blocks = 288MB. // Add 15% for Undo data = 331MB @@ -150,7 +184,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals); * @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, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp); +bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos* dbp); /** Check whether enough disk space is available for an incoming block */ bool CheckDiskSpace(uint64_t nAdditionalBytes = 0); /** Open a block file (blk?????.dat) */ @@ -160,9 +194,9 @@ FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false); /** Translation to a filesystem path */ boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix); /** Import blocks from an external file */ -bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp = NULL); +bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskBlockPos *dbp = NULL); /** Initialize a new block tree database + block data on disk */ -bool InitBlockIndex(); +bool InitBlockIndex(const CChainParams& chainparams); /** Load the block tree and coins database from disk */ bool LoadBlockIndex(); /** Unload database information */ @@ -173,21 +207,26 @@ bool ProcessMessages(CNode* pfrom); * Send queued protocol messages to be sent to a give node. * * @param[in] pto The node which we are sending messages to. - * @param[in] fSendTrickle When true send the trickled data, otherwise trickle the data until true. */ -bool SendMessages(CNode* pto, bool fSendTrickle); +bool SendMessages(CNode* pto); /** Run an instance of the script checking thread */ void ThreadScriptCheck(); /** Try to detect Partition (network isolation) attacks against us */ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader, int64_t nPowTargetSpacing); /** Check whether we are doing an initial block download (synchronizing from disk or network) */ bool IsInitialBlockDownload(); -/** Format a string that describes several potential problems detected by the core */ +/** Format a string that describes several potential problems detected by the core. + * strFor can have three values: + * - "rpc": get critical warnings, which should put the client in safe mode if non-empty + * - "statusbar": get all warnings + * - "gui": get all warnings, translated (where possible) for GUI + * This function only returns the highest priority warning of the set selected by strFor. + */ std::string GetWarnings(const std::string& strFor); /** Retrieve a transaction (from memory pool, or from disk, if possible) */ -bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false); +bool GetTransaction(const uint256 &hash, CTransaction &tx, const Consensus::Params& params, uint256 &hashBlock, bool fAllowSlow = false); /** Find the best known block, and make it the tip of the block chain */ -bool ActivateBestChain(CValidationState &state, const CBlock *pblock = NULL); +bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams, const CBlock* pblock = NULL); CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); /** @@ -198,14 +237,14 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); * * Pruning functions are called from FlushStateToDisk when the global fCheckForPruning flag has been set. * Block and undo files are deleted in lock-step (when blk00003.dat is deleted, so is rev00003.dat.) - * Pruning cannot take place until the longest chain is at least a certain length (100000 on mainnet, 1000 on testnet, 10 on regtest). + * Pruning cannot take place until the longest chain is at least a certain length (100000 on mainnet, 1000 on testnet, 1000 on regtest). * Pruning will never delete a block within a defined distance (currently 288) from the active chain's tip. * The block index is updated by unsetting HAVE_DATA and HAVE_UNDO for any blocks that were stored in the deleted files. * A db flag records the fact that at least some block files have been pruned. * * @param[out] setFilesToPrune The set of file indices that can be unlinked will be returned */ -void FindFilesToPrune(std::set<int>& setFilesToPrune); +void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight); /** * Actually unlink the specified files @@ -225,8 +264,10 @@ void PruneAndFlush(); /** (try to) add transaction to memory pool **/ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs, bool fRejectAbsurdFee=false); + bool* pfMissingInputs, bool fOverrideMempoolLimit=false, bool fRejectAbsurdFee=false); +/** Convert CValidationState to a human-readable message for logging */ +std::string FormatStateMessage(const CValidationState &state); struct CNodeStateStats { int nMisbehavior; @@ -261,8 +302,6 @@ struct CDiskTxPos : public CDiskBlockPos }; -CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree); - /** * Count ECDSA signature operations the old-fashioned (pre-0.6) way * @return number of sigops this transaction's outputs will produce when spent @@ -304,8 +343,10 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime); * Check if transaction will be final in the next block to be created. * * Calls IsFinalTx() with current block height and appropriate block time. + * + * See consensus/consensus.h for flag definitions. */ -bool CheckFinalTx(const CTransaction &tx); +bool CheckFinalTx(const CTransaction &tx, int flags = -1); /** * Closure representing one script verification @@ -344,9 +385,8 @@ public: /** Functions for disk access for blocks */ bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); -bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos); -bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex); - +bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams); +bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams); /** Functions for validating blocks and updating the block tree */ @@ -368,12 +408,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta 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 non-NULL, the file is known to already reside on disk */ -bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp); -bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL); - +bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); class CBlockFileInfo @@ -435,19 +470,19 @@ class CVerifyDB { public: CVerifyDB(); ~CVerifyDB(); - bool VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth); + bool VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth); }; /** Find the last common block between the parameter chain and a locator. */ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator); /** Mark a block as invalid. */ -bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex); +bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex *pindex); /** Remove invalidity status from a block and its descendants. */ bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex); -/** The currently-connected chain of blocks. */ +/** The currently-connected chain of blocks (protected by cs_main). */ extern CChain chainActive; /** Global variable that points to the active CCoinsView (protected by cs_main) */ diff --git a/src/memusage.h b/src/memusage.h index b475c3313b..49760e64c7 100644 --- a/src/memusage.h +++ b/src/memusage.h @@ -46,7 +46,9 @@ template<typename X> static inline size_t DynamicUsage(const X * const &v) { ret static inline size_t MallocUsage(size_t alloc) { // Measured on libc6 2.19 on Linux. - if (sizeof(void*) == 8) { + if (alloc == 0) { + return 0; + } else if (sizeof(void*) == 8) { return ((alloc + 31) >> 4) << 4; } else if (sizeof(void*) == 4) { return ((alloc + 15) >> 3) << 3; @@ -74,6 +76,12 @@ static inline size_t DynamicUsage(const std::vector<X>& v) return MallocUsage(v.capacity() * sizeof(X)); } +template<unsigned int N, typename X, typename S, typename D> +static inline size_t DynamicUsage(const prevector<N, X, S, D>& v) +{ + return MallocUsage(v.allocated_memory()); +} + template<typename X, typename Y> static inline size_t DynamicUsage(const std::set<X, Y>& s) { @@ -121,4 +129,4 @@ static inline size_t DynamicUsage(const boost::unordered_map<X, Y, Z>& m) } -#endif +#endif // BITCOIN_MEMUSAGE_H diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index f8e877df25..8447f924e4 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/merkleblock.h b/src/merkleblock.h index 904c22abc2..996cd12624 100644 --- a/src/merkleblock.h +++ b/src/merkleblock.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/miner.cpp b/src/miner.cpp index 42c8bb970b..c454c0279c 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,6 +10,7 @@ #include "chainparams.h" #include "coins.h" #include "consensus/consensus.h" +#include "consensus/merkle.h" #include "consensus/validation.h" #include "hash.h" #include "main.h" @@ -26,6 +27,7 @@ #include <boost/thread.hpp> #include <boost/tuple/tuple.hpp> +#include <queue> using namespace std; @@ -39,48 +41,18 @@ using namespace std; // transactions in the memory pool. When we select transactions from the // pool, we select by highest priority or fee rate, so we might consider // transactions that depend on transactions that aren't yet in the block. -// The COrphan class keeps track of these 'temporary orphans' while -// CreateBlock is figuring out which transactions to include. -// -class COrphan -{ -public: - const CTransaction* ptx; - set<uint256> setDependsOn; - CFeeRate feeRate; - double dPriority; - - COrphan(const CTransaction* ptxIn) : ptx(ptxIn), feeRate(0), dPriority(0) - { - } -}; uint64_t nLastBlockTx = 0; uint64_t nLastBlockSize = 0; -// We want to sort transactions by priority and fee rate, so: -typedef boost::tuple<double, CFeeRate, const CTransaction*> TxPriority; -class TxPriorityCompare +class ScoreCompare { - bool byFee; - public: - TxPriorityCompare(bool _byFee) : byFee(_byFee) { } + ScoreCompare() {} - bool operator()(const TxPriority& a, const TxPriority& b) + bool operator()(const CTxMemPool::txiter a, const CTxMemPool::txiter b) { - if (byFee) - { - if (a.get<1>() == b.get<1>()) - return a.get<0>() < b.get<0>(); - return a.get<1>() < b.get<1>(); - } - else - { - if (a.get<0>() == b.get<0>()) - return a.get<1>() < b.get<1>(); - return a.get<0>() < b.get<0>(); - } + return CompareTxMemPoolEntryByScore()(*b,*a); // Convert to less than } }; @@ -99,9 +71,8 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam return nNewTime - nOldTime; } -CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) +CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& scriptPubKeyIn) { - const CChainParams& chainparams = Params(); // Create new block auto_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate()); if(!pblocktemplate.get()) @@ -110,7 +81,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // -regtest only: allow overriding block.nVersion with // -blockversion=N to test forking scenarios - if (Params().MineBlocksOnDemand()) + if (chainparams.MineBlocksOnDemand()) pblock->nVersion = GetArg("-blockversion", pblock->nVersion); // Create coinbase tx @@ -127,7 +98,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // Largest block you're willing to create: unsigned int nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); - // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity: + // Limit to between 1K and MAX_BLOCK_SIZE-1K for sanity: nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); // How much of the block should be dedicated to high-priority transactions, @@ -141,6 +112,22 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); // Collect memory pool transactions into the block + CTxMemPool::setEntries inBlock; + CTxMemPool::setEntries waitSet; + + // This vector will be sorted into a priority queue: + vector<TxCoinAgePriority> vecPriority; + TxCoinAgePriorityCompare pricomparer; + std::map<CTxMemPool::txiter, double, CTxMemPool::CompareIteratorByHash> waitPriMap; + typedef std::map<CTxMemPool::txiter, double, CTxMemPool::CompareIteratorByHash>::iterator waitPriIter; + double actualPriority = -1; + + std::priority_queue<CTxMemPool::txiter, std::vector<CTxMemPool::txiter>, ScoreCompare> clearedTxs; + bool fPrintPriority = GetBoolArg("-printpriority", DEFAULT_PRINTPRIORITY); + uint64_t nBlockSize = 1000; + uint64_t nBlockTx = 0; + unsigned int nBlockSigOps = 100; + int lastFewTxs = 0; CAmount nFees = 0; { @@ -148,152 +135,103 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) CBlockIndex* pindexPrev = chainActive.Tip(); const int nHeight = pindexPrev->nHeight + 1; pblock->nTime = GetAdjustedTime(); - CCoinsViewCache view(pcoinsTip); - - // Priority order to process transactions - list<COrphan> vOrphan; // list memory doesn't move - map<uint256, vector<COrphan*> > mapDependers; - bool fPrintPriority = GetBoolArg("-printpriority", false); - - // This vector will be sorted into a priority queue: - vector<TxPriority> vecPriority; - vecPriority.reserve(mempool.mapTx.size()); - for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin(); - mi != mempool.mapTx.end(); ++mi) - { - const CTransaction& tx = mi->GetTx(); - if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, pblock->nTime)) - continue; + const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); - COrphan* porphan = NULL; - double dPriority = 0; - CAmount nTotalIn = 0; - bool fMissingInputs = false; - BOOST_FOREACH(const CTxIn& txin, tx.vin) - { - // Read prev transaction - if (!view.HaveCoins(txin.prevout.hash)) - { - // This should never happen; all transactions in the memory - // pool should connect to either transactions in the chain - // or other transactions in the memory pool. - if (!mempool.mapTx.count(txin.prevout.hash)) - { - LogPrintf("ERROR: mempool transaction missing input\n"); - if (fDebug) assert("mempool transaction missing input" == 0); - fMissingInputs = true; - if (porphan) - vOrphan.pop_back(); - break; - } - - // Has to wait for dependencies - if (!porphan) - { - // Use list for automatic deletion - vOrphan.push_back(COrphan(&tx)); - porphan = &vOrphan.back(); - } - mapDependers[txin.prevout.hash].push_back(porphan); - porphan->setDependsOn.insert(txin.prevout.hash); - nTotalIn += mempool.mapTx.find(txin.prevout.hash)->GetTx().vout[txin.prevout.n].nValue; - continue; - } - const CCoins* coins = view.AccessCoins(txin.prevout.hash); - assert(coins); - - CAmount nValueIn = coins->vout[txin.prevout.n].nValue; - nTotalIn += nValueIn; + int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST) + ? nMedianTimePast + : pblock->GetBlockTime(); - int nConf = nHeight - coins->nHeight; - - dPriority += (double)nValueIn * nConf; - } - if (fMissingInputs) continue; - - // Priority is sum(valuein * age) / modified_txsize - unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - dPriority = tx.ComputePriority(dPriority, nTxSize); - - uint256 hash = tx.GetHash(); - mempool.ApplyDeltas(hash, dPriority, nTotalIn); - - CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize); - - if (porphan) + bool fPriorityBlock = nBlockPrioritySize > 0; + if (fPriorityBlock) { + vecPriority.reserve(mempool.mapTx.size()); + for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin(); + mi != mempool.mapTx.end(); ++mi) { - porphan->dPriority = dPriority; - porphan->feeRate = feeRate; + double dPriority = mi->GetPriority(nHeight); + CAmount dummy; + mempool.ApplyDeltas(mi->GetTx().GetHash(), dPriority, dummy); + vecPriority.push_back(TxCoinAgePriority(dPriority, mi)); } - else - vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx()))); + std::make_heap(vecPriority.begin(), vecPriority.end(), pricomparer); } - // Collect transactions into block - uint64_t nBlockSize = 1000; - uint64_t nBlockTx = 0; - int nBlockSigOps = 100; - bool fSortedByFee = (nBlockPrioritySize <= 0); - - TxPriorityCompare comparer(fSortedByFee); - std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); + CTxMemPool::indexed_transaction_set::nth_index<3>::type::iterator mi = mempool.mapTx.get<3>().begin(); + CTxMemPool::txiter iter; - while (!vecPriority.empty()) + while (mi != mempool.mapTx.get<3>().end() || !clearedTxs.empty()) { - // Take highest priority transaction off the priority queue: - double dPriority = vecPriority.front().get<0>(); - CFeeRate feeRate = vecPriority.front().get<1>(); - const CTransaction& tx = *(vecPriority.front().get<2>()); - - std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer); - vecPriority.pop_back(); - - // Size limits - unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - if (nBlockSize + nTxSize >= nBlockMaxSize) - continue; + bool priorityTx = false; + if (fPriorityBlock && !vecPriority.empty()) { // add a tx from priority queue to fill the blockprioritysize + priorityTx = true; + iter = vecPriority.front().second; + actualPriority = vecPriority.front().first; + std::pop_heap(vecPriority.begin(), vecPriority.end(), pricomparer); + vecPriority.pop_back(); + } + else if (clearedTxs.empty()) { // add tx with next highest score + iter = mempool.mapTx.project<0>(mi); + mi++; + } + else { // try to add a previously postponed child tx + iter = clearedTxs.top(); + clearedTxs.pop(); + } - // Legacy limits on sigOps: - unsigned int nTxSigOps = GetLegacySigOpCount(tx); - if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) - continue; + if (inBlock.count(iter)) + continue; // could have been added to the priorityBlock - // Skip free transactions if we're past the minimum block size: - const uint256& hash = tx.GetHash(); - double dPriorityDelta = 0; - CAmount nFeeDelta = 0; - mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta); - if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize)) - continue; + const CTransaction& tx = iter->GetTx(); - // Prioritise by fee once past the priority size or we run out of high-priority - // transactions: - if (!fSortedByFee && - ((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority))) + bool fOrphan = false; + BOOST_FOREACH(CTxMemPool::txiter parent, mempool.GetMemPoolParents(iter)) { - fSortedByFee = true; - comparer = TxPriorityCompare(fSortedByFee); - std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); + if (!inBlock.count(parent)) { + fOrphan = true; + break; + } } - - if (!view.HaveInputs(tx)) + if (fOrphan) { + if (priorityTx) + waitPriMap.insert(std::make_pair(iter,actualPriority)); + else + waitSet.insert(iter); continue; + } - CAmount nTxFees = view.GetValueIn(tx)-tx.GetValueOut(); - - nTxSigOps += GetP2SHSigOpCount(tx, view); - if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) + unsigned int nTxSize = iter->GetTxSize(); + if (fPriorityBlock && + (nBlockSize + nTxSize >= nBlockPrioritySize || !AllowFree(actualPriority))) { + fPriorityBlock = false; + waitPriMap.clear(); + } + if (!priorityTx && + (iter->GetModifiedFee() < ::minRelayTxFee.GetFee(nTxSize) && nBlockSize >= nBlockMinSize)) { + break; + } + if (nBlockSize + nTxSize >= nBlockMaxSize) { + if (nBlockSize > nBlockMaxSize - 100 || lastFewTxs > 50) { + break; + } + // Once we're within 1000 bytes of a full block, only look at 50 more txs + // to try to fill the remaining space. + if (nBlockSize > nBlockMaxSize - 1000) { + lastFewTxs++; + } continue; + } - // Note that flags: we don't want to set mempool/IsStandard() - // 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, true)) + if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) continue; - UpdateCoins(tx, state, view, nHeight); + unsigned int nTxSigOps = iter->GetSigOpCount(); + if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) { + if (nBlockSigOps > MAX_BLOCK_SIGOPS - 2) { + break; + } + continue; + } + CAmount nTxFees = iter->GetFee(); // Added pblock->vtx.push_back(tx); pblocktemplate->vTxFees.push_back(nTxFees); @@ -305,31 +243,37 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) if (fPrintPriority) { + double dPriority = iter->GetPriority(nHeight); + CAmount dummy; + mempool.ApplyDeltas(tx.GetHash(), dPriority, dummy); LogPrintf("priority %.1f fee %s txid %s\n", - dPriority, feeRate.ToString(), tx.GetHash().ToString()); + dPriority , CFeeRate(iter->GetModifiedFee(), nTxSize).ToString(), tx.GetHash().ToString()); } + inBlock.insert(iter); + // Add transactions that depend on this one to the priority queue - if (mapDependers.count(hash)) + BOOST_FOREACH(CTxMemPool::txiter child, mempool.GetMemPoolChildren(iter)) { - BOOST_FOREACH(COrphan* porphan, mapDependers[hash]) - { - if (!porphan->setDependsOn.empty()) - { - porphan->setDependsOn.erase(hash); - if (porphan->setDependsOn.empty()) - { - vecPriority.push_back(TxPriority(porphan->dPriority, porphan->feeRate, porphan->ptx)); - std::push_heap(vecPriority.begin(), vecPriority.end(), comparer); - } + if (fPriorityBlock) { + waitPriIter wpiter = waitPriMap.find(child); + if (wpiter != waitPriMap.end()) { + vecPriority.push_back(TxCoinAgePriority(wpiter->second,child)); + std::push_heap(vecPriority.begin(), vecPriority.end(), pricomparer); + waitPriMap.erase(wpiter); + } + } + else { + if (waitSet.count(child)) { + clearedTxs.push(child); + waitSet.erase(child); } } } } - nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; - LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize); + LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOps); // Compute final coinbase transaction. txNew.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus()); @@ -339,14 +283,15 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); - UpdateTime(pblock, Params().GetConsensus(), pindexPrev); - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); + UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus()); pblock->nNonce = 0; pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); CValidationState state; - if (!TestBlockValidity(state, *pblock, pindexPrev, false, false)) - throw std::runtime_error("CreateNewBlock(): TestBlockValidity failed"); + if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) { + throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state))); + } } return pblocktemplate.release(); @@ -368,7 +313,7 @@ void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned assert(txCoinbase.vin[0].scriptSig.size() <= 100); pblock->vtx[0] = txCoinbase; - pblock->hashMerkleRoot = pblock->ComputeMerkleRoot(); + pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); } ////////////////////////////////////////////////////////////////////////////// @@ -426,7 +371,7 @@ static bool ProcessBlockFound(const CBlock* pblock, const CChainParams& chainpar // Process this block the same as if we had received it from another node CValidationState state; - if (!ProcessNewBlock(state, NULL, pblock, true, NULL)) + if (!ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL)) return error("BitcoinMiner: ProcessNewBlock, block not accepted"); return true; @@ -472,7 +417,7 @@ void static BitcoinMiner(const CChainParams& chainparams) unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); CBlockIndex* pindexPrev = chainActive.Tip(); - auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript)); + auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(chainparams, coinbaseScript->reserveScript)); if (!pblocktemplate.get()) { LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n"); diff --git a/src/miner.h b/src/miner.h index 7e0e58d540..512494198b 100644 --- a/src/miner.h +++ b/src/miner.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -17,6 +17,11 @@ class CScript; class CWallet; namespace Consensus { struct Params; }; +static const bool DEFAULT_GENERATE = false; +static const int DEFAULT_GENERATE_THREADS = 1; + +static const bool DEFAULT_PRINTPRIORITY = false; + struct CBlockTemplate { CBlock block; @@ -27,7 +32,7 @@ struct CBlockTemplate /** Run the miner threads */ void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainparams); /** Generate a new block, without valid proof-of-work */ -CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn); +CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& scriptPubKeyIn); /** Modify the extranonce in a block */ void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce); int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev); diff --git a/src/mruset.h b/src/mruset.h deleted file mode 100644 index 398aa173bf..0000000000 --- a/src/mruset.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_MRUSET_H -#define BITCOIN_MRUSET_H - -#include <set> -#include <vector> -#include <utility> - -/** STL-like set container that only keeps the most recent N elements. */ -template <typename T> -class mruset -{ -public: - typedef T key_type; - typedef T value_type; - typedef typename std::set<T>::iterator iterator; - typedef typename std::set<T>::const_iterator const_iterator; - typedef typename std::set<T>::size_type size_type; - -protected: - std::set<T> set; - std::vector<iterator> order; - size_type first_used; - size_type first_unused; - const size_type nMaxSize; - -public: - mruset(size_type nMaxSizeIn = 1) : nMaxSize(nMaxSizeIn) { clear(); } - iterator begin() const { return set.begin(); } - iterator end() const { return set.end(); } - size_type size() const { return set.size(); } - bool empty() const { return set.empty(); } - iterator find(const key_type& k) const { return set.find(k); } - size_type count(const key_type& k) const { return set.count(k); } - void clear() - { - set.clear(); - order.assign(nMaxSize, set.end()); - first_used = 0; - first_unused = 0; - } - bool inline friend operator==(const mruset<T>& a, const mruset<T>& b) { return a.set == b.set; } - bool inline friend operator==(const mruset<T>& a, const std::set<T>& b) { return a.set == b; } - bool inline friend operator<(const mruset<T>& a, const mruset<T>& b) { return a.set < b.set; } - std::pair<iterator, bool> insert(const key_type& x) - { - std::pair<iterator, bool> ret = set.insert(x); - if (ret.second) { - if (set.size() == nMaxSize + 1) { - set.erase(order[first_used]); - order[first_used] = set.end(); - if (++first_used == nMaxSize) first_used = 0; - } - order[first_unused] = ret.first; - if (++first_unused == nMaxSize) first_unused = 0; - } - return ret; - } - size_type max_size() const { return nMaxSize; } -}; - -#endif // BITCOIN_MRUSET_H diff --git a/src/net.cpp b/src/net.cpp index 15ddaac63d..ac7a8c1bc0 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,6 +12,7 @@ #include "addrman.h" #include "chainparams.h" #include "clientversion.h" +#include "consensus/consensus.h" #include "crypto/common.h" #include "hash.h" #include "primitives/transaction.h" @@ -35,6 +36,8 @@ #include <boost/filesystem.hpp> #include <boost/thread.hpp> +#include <math.h> + // Dump addresses to peers.dat and banlist.dat every 15 minutes (900s) #define DUMP_ADDRESSES_INTERVAL 900 @@ -66,6 +69,8 @@ namespace { }; } +const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; + // // Global state variables // @@ -215,6 +220,7 @@ void AdvertizeLocal(CNode *pnode) } if (addrLocal.IsRoutable()) { + LogPrintf("AdvertizeLocal: advertizing address %s\n", addrLocal.ToString()); pnode->PushAddress(addrLocal); } } @@ -261,6 +267,14 @@ bool AddLocal(const CNetAddr &addr, int nScore) return AddLocal(CService(addr, GetListenPort()), nScore); } +bool RemoveLocal(const CService& addr) +{ + LOCK(cs_mapLocalHost); + LogPrintf("RemoveLocal(%s)\n", addr.ToString()); + mapLocalHost.erase(addr); + return true; +} + /** Make a particular network entirely off-limits (no automatic connects to it) */ void SetLimited(enum Network net, bool fLimited) { @@ -326,6 +340,11 @@ uint64_t CNode::nTotalBytesSent = 0; CCriticalSection CNode::cs_totalBytesRecv; CCriticalSection CNode::cs_totalBytesSent; +uint64_t CNode::nMaxOutboundLimit = 0; +uint64_t CNode::nMaxOutboundTotalBytesSentInCycle = 0; +uint64_t CNode::nMaxOutboundTimeframe = 60*60*24; //1 day +uint64_t CNode::nMaxOutboundCycleStartTime = 0; + CNode* FindNode(const CNetAddr& ip) { LOCK(cs_vNodes); @@ -444,8 +463,8 @@ void CNode::PushVersion() LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id); else LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id); - PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, - nLocalHostNonce, strSubVersion, nBestHeight, true); + PushMessage(NetMsgType::VERSION, PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, + nLocalHostNonce, strSubVersion, nBestHeight, !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)); } @@ -506,12 +525,11 @@ void CNode::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t banti banEntry.banReason = banReason; if (bantimeoffset <= 0) { - bantimeoffset = GetArg("-bantime", 60*60*24); // Default 24-hour ban + bantimeoffset = GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME); sinceUnixEpoch = false; } banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset; - LOCK(cs_setBanned); if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) setBanned[subNet] = banEntry; @@ -604,6 +622,7 @@ void CNode::copyStats(CNodeStats &stats) { stats.nodeid = this->GetId(); X(nServices); + X(fRelayTxes); X(nLastSend); X(nLastRecv); X(nTimeConnected); @@ -614,7 +633,9 @@ void CNode::copyStats(CNodeStats &stats) X(fInbound); X(nStartingHeight); X(nSendBytes); + X(mapSendBytesPerMsgCmd); X(nRecvBytes); + X(mapRecvBytesPerMsgCmd); X(fWhitelisted); // It is common for nodes with good ping times to suddenly become lagged, @@ -669,6 +690,15 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes) nBytes -= handled; if (msg.complete()) { + + //store received bytes per message command + //to prevent a memory DOS, only allow valid commands + mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.hdr.pchCommand); + if (i == mapRecvBytesPerMsgCmd.end()) + i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER); + assert(i != mapRecvBytesPerMsgCmd.end()); + i->second += msg.hdr.nMessageSize + CMessageHeader::HEADER_SIZE; + msg.nTime = GetTimeMicros(); messageHandlerCondition.notify_one(); } @@ -965,6 +995,15 @@ static void AcceptConnection(const ListenSocket& hListenSocket) { return; } + // According to the internet TCP_NODELAY is not carried into accepted sockets + // on all platforms. Set it again here just to be sure. + int set = 1; +#ifdef WIN32 + setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&set, sizeof(int)); +#else + setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&set, sizeof(int)); +#endif + if (CNode::IsBanned(addr) && !whitelisted) { LogPrintf("connection from %s dropped (banned)\n", addr.ToString()); @@ -1333,7 +1372,7 @@ void ThreadMapPort() LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r)); else - LogPrintf("UPnP Port Mapping successful.\n");; + LogPrintf("UPnP Port Mapping successful.\n"); MilliSleep(20*60*1000); // Refresh every 20 minutes } @@ -1391,7 +1430,7 @@ void ThreadDNSAddressSeed() { // goal: only query DNS seeds if address need is acute if ((addrman.size() > 0) && - (!GetBoolArg("-forcednsseed", false))) { + (!GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) { MilliSleep(11 * 1000); LOCK(cs_vNodes); @@ -1693,11 +1732,6 @@ void ThreadMessageHandler() } } - // Poll the connected nodes for messages - CNode* pnodeTrickle = NULL; - if (!vNodesCopy.empty()) - pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())]; - bool fSleep = true; BOOST_FOREACH(CNode* pnode, vNodesCopy) @@ -1728,7 +1762,7 @@ void ThreadMessageHandler() { TRY_LOCK(pnode->cs_vSend, lockSend); if (lockSend) - g_signals.SendMessages(pnode, pnode == pnodeTrickle || pnode->fWhitelisted); + g_signals.SendMessages(pnode); } boost::this_thread::interruption_point(); } @@ -1787,8 +1821,11 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste // Allow binding if the port is still in TIME_WAIT state after // the program was closed and restarted. setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); + // Disable Nagle's algorithm + setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&nOne, sizeof(int)); #else setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int)); + setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&nOne, sizeof(int)); #endif // Set to non-blocking, incoming connections will also inherit this @@ -2073,6 +2110,94 @@ void CNode::RecordBytesSent(uint64_t bytes) { LOCK(cs_totalBytesSent); nTotalBytesSent += bytes; + + uint64_t now = GetTime(); + if (nMaxOutboundCycleStartTime + nMaxOutboundTimeframe < now) + { + // timeframe expired, reset cycle + nMaxOutboundCycleStartTime = now; + nMaxOutboundTotalBytesSentInCycle = 0; + } + + // TODO, exclude whitebind peers + nMaxOutboundTotalBytesSentInCycle += bytes; +} + +void CNode::SetMaxOutboundTarget(uint64_t limit) +{ + LOCK(cs_totalBytesSent); + uint64_t recommendedMinimum = (nMaxOutboundTimeframe / 600) * MAX_BLOCK_SIZE; + nMaxOutboundLimit = limit; + + if (limit > 0 && limit < recommendedMinimum) + LogPrintf("Max outbound target is very small (%s bytes) and will be overshot. Recommended minimum is %s bytes.\n", nMaxOutboundLimit, recommendedMinimum); +} + +uint64_t CNode::GetMaxOutboundTarget() +{ + LOCK(cs_totalBytesSent); + return nMaxOutboundLimit; +} + +uint64_t CNode::GetMaxOutboundTimeframe() +{ + LOCK(cs_totalBytesSent); + return nMaxOutboundTimeframe; +} + +uint64_t CNode::GetMaxOutboundTimeLeftInCycle() +{ + LOCK(cs_totalBytesSent); + if (nMaxOutboundLimit == 0) + return 0; + + if (nMaxOutboundCycleStartTime == 0) + return nMaxOutboundTimeframe; + + uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe; + uint64_t now = GetTime(); + return (cycleEndTime < now) ? 0 : cycleEndTime - GetTime(); +} + +void CNode::SetMaxOutboundTimeframe(uint64_t timeframe) +{ + LOCK(cs_totalBytesSent); + if (nMaxOutboundTimeframe != timeframe) + { + // reset measure-cycle in case of changing + // the timeframe + nMaxOutboundCycleStartTime = GetTime(); + } + nMaxOutboundTimeframe = timeframe; +} + +bool CNode::OutboundTargetReached(bool historicalBlockServingLimit) +{ + LOCK(cs_totalBytesSent); + if (nMaxOutboundLimit == 0) + return false; + + if (historicalBlockServingLimit) + { + // keep a large enought buffer to at least relay each block once + uint64_t timeLeftInCycle = GetMaxOutboundTimeLeftInCycle(); + uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SIZE; + if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer) + return true; + } + else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) + return true; + + return false; +} + +uint64_t CNode::GetOutboundTargetBytesLeft() +{ + LOCK(cs_totalBytesSent); + if (nMaxOutboundLimit == 0) + return 0; + + return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle; } uint64_t CNode::GetTotalBytesRecv() @@ -2223,13 +2348,13 @@ bool CAddrDB::Read(CAddrMan& addr) return true; } -unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); } -unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); } +unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER); } +unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER); } CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), addrKnown(5000, 0.001), - setInventoryKnown(SendBufferSize() / 1000) + filterInventoryKnown(50000, 0.000001) { nServices = 0; hSocket = hSocketIn; @@ -2256,7 +2381,11 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nSendOffset = 0; hashContinue = uint256(); nStartingHeight = -1; + filterInventoryKnown.reset(); fGetAddr = false; + nNextLocalAddrSend = 0; + nNextAddrSend = 0; + nNextInvSend = 0; fRelayTxes = false; pfilter = new CBloomFilter(); nPingNonceSent = 0; @@ -2264,6 +2393,9 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nPingUsecTime = 0; fPingQueued = false; nMinPingUsecTime = std::numeric_limits<int64_t>::max(); + BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes()) + mapRecvBytesPerMsgCmd[msg] = 0; + mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; { LOCK(cs_nLastNodeId); @@ -2294,8 +2426,12 @@ CNode::~CNode() void CNode::AskFor(const CInv& inv) { - if (mapAskFor.size() > MAPASKFOR_MAX_SZ) + if (mapAskFor.size() > MAPASKFOR_MAX_SZ || setAskFor.size() > SETASKFOR_MAX_SZ) + return; + // a peer may not have multiple non-responded queue positions for a single inv item + if (!setAskFor.insert(inv.hash).second) return; + // We're using mapAskFor as a priority queue, // the key is the earliest time the request can be sent int64_t nRequestTime; @@ -2339,7 +2475,7 @@ void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend) LogPrint("net", "(aborted)\n"); } -void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend) +void CNode::EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend) { // The -*messagestest options are intentionally not documented in the help message, // since they are only used during development to debug the networking code and are @@ -2362,6 +2498,9 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend) unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE; WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize); + //log total amount of bytes per command + mapSendBytesPerMsgCmd[std::string(pszCommand)] += nSize + CMessageHeader::HEADER_SIZE; + // Set the checksum uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end()); unsigned int nChecksum = 0; @@ -2501,3 +2640,7 @@ void DumpBanlist() LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", banmap.size(), GetTimeMillis() - nStart); } + +int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) { + return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5); +} @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,7 +9,6 @@ #include "bloom.h" #include "compat.h" #include "limitedmap.h" -#include "mruset.h" #include "netbase.h" #include "protocol.h" #include "random.h" @@ -58,8 +57,21 @@ static const bool DEFAULT_UPNP = false; #endif /** The maximum number of entries in mapAskFor */ static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ; +/** The maximum number of entries in setAskFor (larger due to getdata latency)*/ +static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ; /** The maximum number of peer connections to maintain. */ static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125; +/** The default for -maxuploadtarget. 0 = Unlimited */ +static const uint64_t DEFAULT_MAX_UPLOAD_TARGET = 0; +/** Default for blocks only*/ +static const bool DEFAULT_BLOCKSONLY = false; + +static const bool DEFAULT_FORCEDNSSEED = false; +static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000; +static const size_t DEFAULT_MAXSENDBUFFER = 1 * 1000; + +// NOTE: When adjusting this, update rpcnet:setban's help ("24h") +static const unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban unsigned int ReceiveFloodSize(); unsigned int SendBufferSize(); @@ -101,7 +113,7 @@ struct CNodeSignals { boost::signals2::signal<int ()> GetHeight; boost::signals2::signal<bool (CNode*), CombinerAll> ProcessMessages; - boost::signals2::signal<bool (CNode*, bool), CombinerAll> SendMessages; + boost::signals2::signal<bool (CNode*), CombinerAll> SendMessages; boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode; boost::signals2::signal<void (NodeId)> FinalizeNode; }; @@ -128,6 +140,7 @@ bool IsLimited(enum Network net); bool IsLimited(const CNetAddr& addr); bool AddLocal(const CService& addr, int nScore = LOCAL_NONE); bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE); +bool RemoveLocal(const CService& addr); bool SeenLocal(const CService& addr); bool IsLocal(const CService& addr); bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL); @@ -169,12 +182,14 @@ struct LocalServiceInfo { extern CCriticalSection cs_mapLocalHost; extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost; +typedef std::map<std::string, uint64_t> mapMsgCmdSize; //command, total bytes class CNodeStats { public: NodeId nodeid; uint64_t nServices; + bool fRelayTxes; int64_t nLastSend; int64_t nLastRecv; int64_t nTimeConnected; @@ -185,7 +200,9 @@ public: bool fInbound; int nStartingHeight; uint64_t nSendBytes; + mapMsgCmdSize mapSendBytesPerMsgCmd; uint64_t nRecvBytes; + mapMsgCmdSize mapRecvBytesPerMsgCmd; bool fWhitelisted; double dPingTime; double dPingWait; @@ -339,7 +356,7 @@ public: // We use fRelayTxes for two purposes - // a) it allows us to not relay tx invs before receiving the peer's version message // b) the peer may tell us in its version message that we should not relay tx invs - // until it has initialized its bloom filter. + // unless it loads a bloom filter. bool fRelayTxes; CSemaphoreGrant grantOutbound; CCriticalSection cs_filter; @@ -359,6 +376,9 @@ protected: static std::vector<CSubNet> vWhitelistedRange; static CCriticalSection cs_vWhitelistedRange; + mapMsgCmdSize mapSendBytesPerMsgCmd; + mapMsgCmdSize mapRecvBytesPerMsgCmd; + // Basic fuzz-testing void Fuzz(int nChance); // modifies ssSend @@ -371,12 +391,19 @@ public: CRollingBloomFilter addrKnown; bool fGetAddr; std::set<uint256> setKnown; + int64_t nNextAddrSend; + int64_t nNextLocalAddrSend; // inventory based relay - mruset<CInv> setInventoryKnown; + CRollingBloomFilter filterInventoryKnown; std::vector<CInv> vInventoryToSend; CCriticalSection cs_inventory; + std::set<uint256> setAskFor; std::multimap<int64_t, CInv> mapAskFor; + int64_t nNextInvSend; + // Used for headers announcements - unfiltered blocks to relay + // Also protected by cs_inventory + std::vector<uint256> vBlockHashesToAnnounce; // Ping time measurement: // The pong reply we're expecting, or 0 if no pong expected. @@ -400,6 +427,12 @@ private: static uint64_t nTotalBytesRecv; static uint64_t nTotalBytesSent; + // outbound limit & stats + static uint64_t nMaxOutboundTotalBytesSentInCycle; + static uint64_t nMaxOutboundCycleStartTime; + static uint64_t nMaxOutboundLimit; + static uint64_t nMaxOutboundTimeframe; + CNode(const CNode&); void operator=(const CNode&); @@ -472,7 +505,7 @@ public: { { LOCK(cs_inventory); - setInventoryKnown.insert(inv); + filterInventoryKnown.insert(inv.hash); } } @@ -480,11 +513,18 @@ public: { { LOCK(cs_inventory); - if (!setInventoryKnown.count(inv)) - vInventoryToSend.push_back(inv); + if (inv.type == MSG_TX && filterInventoryKnown.contains(inv.hash)) + return; + vInventoryToSend.push_back(inv); } } + void PushBlockHash(const uint256 &hash) + { + LOCK(cs_inventory); + vBlockHashesToAnnounce.push_back(hash); + } + void AskFor(const CInv& inv); // TODO: Document the postcondition of this function. Is cs_vSend locked? @@ -494,7 +534,7 @@ public: void AbortMessage() UNLOCK_FUNCTION(cs_vSend); // TODO: Document the precondition of this function. Is cs_vSend locked? - void EndMessage() UNLOCK_FUNCTION(cs_vSend); + void EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend); void PushVersion(); @@ -504,7 +544,7 @@ public: try { BeginMessage(pszCommand); - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -520,7 +560,7 @@ public: { BeginMessage(pszCommand); ssSend << a1; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -536,7 +576,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -552,7 +592,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -568,7 +608,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -584,7 +624,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -600,7 +640,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5 << a6; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -616,7 +656,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -632,7 +672,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -648,7 +688,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -701,6 +741,27 @@ public: static uint64_t GetTotalBytesRecv(); static uint64_t GetTotalBytesSent(); + + //!set the max outbound target in bytes + static void SetMaxOutboundTarget(uint64_t limit); + static uint64_t GetMaxOutboundTarget(); + + //!set the timeframe for the max outbound target + static void SetMaxOutboundTimeframe(uint64_t timeframe); + static uint64_t GetMaxOutboundTimeframe(); + + //!check if the outbound target is reached + // if param historicalBlockServingLimit is set true, the function will + // response true if the limit for serving historical blocks has been reached + static bool OutboundTargetReached(bool historicalBlockServingLimit); + + //!response the bytes left in the current max outbound cycle + // in case of no limit, it will always response 0 + static uint64_t GetOutboundTargetBytesLeft(); + + //!response the time in second left in the current max outbound cycle + // in case of no limit, it will always response 0 + static uint64_t GetMaxOutboundTimeLeftInCycle(); }; @@ -733,4 +794,7 @@ public: void DumpBanlist(); +/** Return a timestamp in the future (in microseconds) for exponentially distributed events. */ +int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds); + #endif // BITCOIN_NET_H diff --git a/src/netbase.cpp b/src/netbase.cpp index c3d56d9184..4e1f267607 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -40,7 +40,7 @@ static proxyType proxyInfo[NET_MAX]; static proxyType nameProxy; static CCriticalSection cs_proxyInfos; int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; -bool fNameLookup = false; +bool fNameLookup = DEFAULT_NAME_LOOKUP; static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; @@ -227,10 +227,7 @@ bool LookupNumeric(const char *pszName, CService& addr, int portDefault) return Lookup(pszName, addr, portDefault, false); } -/** - * Convert milliseconds to a struct timeval for select. - */ -struct timeval static MillisToTimeval(int64_t nTimeout) +struct timeval MillisToTimeval(int64_t nTimeout) { struct timeval timeout; timeout.tv_sec = nTimeout / 1000; @@ -444,12 +441,19 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe if (hSocket == INVALID_SOCKET) return false; -#ifdef SO_NOSIGPIPE int set = 1; +#ifdef SO_NOSIGPIPE // Different way of disabling SIGPIPE on BSD setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); #endif + //Disable Nagle's algorithm +#ifdef WIN32 + setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&set, sizeof(int)); +#else + setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&set, sizeof(int)); +#endif + // Set to non-blocking if (!SetSocketNonBlocking(hSocket, true)) return error("ConnectSocketDirectly: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError())); diff --git a/src/netbase.h b/src/netbase.h index 6f8882b852..1db66ac27f 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -19,8 +19,10 @@ extern int nConnectTimeout; extern bool fNameLookup; -/** -timeout default */ +//! -timeout default static const int DEFAULT_CONNECT_TIMEOUT = 5000; +//! -dns default +static const int DEFAULT_NAME_LOOKUP = true; #ifdef WIN32 // In MSVC, this is defined as a macro, undefine it to prevent a compile and link error @@ -215,5 +217,9 @@ std::string NetworkErrorString(int err); bool CloseSocket(SOCKET& hSocket); /** Disable or enable blocking-mode for a socket */ bool SetSocketNonBlocking(SOCKET& hSocket, bool fNonBlocking); +/** + * Convert milliseconds to a struct timeval for e.g. select. + */ +struct timeval MillisToTimeval(int64_t nTimeout); #endif // BITCOIN_NETBASE_H diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index ffe31d1942..980ecf10df 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -4,6 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "policy/fees.h" +#include "policy/policy.h" #include "amount.h" #include "primitives/transaction.h" @@ -504,6 +505,33 @@ CFeeRate CBlockPolicyEstimator::estimateFee(int confTarget) return CFeeRate(median); } +CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool) +{ + if (answerFoundAtTarget) + *answerFoundAtTarget = confTarget; + // Return failure if trying to analyze a target we're not tracking + if (confTarget <= 0 || (unsigned int)confTarget > feeStats.GetMaxConfirms()) + return CFeeRate(0); + + double median = -1; + while (median < 0 && (unsigned int)confTarget <= feeStats.GetMaxConfirms()) { + median = feeStats.EstimateMedianVal(confTarget++, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBestSeenHeight); + } + + if (answerFoundAtTarget) + *answerFoundAtTarget = confTarget - 1; + + // If mempool is limiting txs , return at least the min fee from the mempool + CAmount minPoolFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(); + if (minPoolFee > 0 && minPoolFee > median) + return CFeeRate(minPoolFee); + + if (median < 0) + return CFeeRate(0); + + return CFeeRate(median); +} + double CBlockPolicyEstimator::estimatePriority(int confTarget) { // Return failure if trying to analyze a target we're not tracking @@ -513,6 +541,30 @@ double CBlockPolicyEstimator::estimatePriority(int confTarget) return priStats.EstimateMedianVal(confTarget, SUFFICIENT_PRITXS, MIN_SUCCESS_PCT, true, nBestSeenHeight); } +double CBlockPolicyEstimator::estimateSmartPriority(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool) +{ + if (answerFoundAtTarget) + *answerFoundAtTarget = confTarget; + // Return failure if trying to analyze a target we're not tracking + if (confTarget <= 0 || (unsigned int)confTarget > priStats.GetMaxConfirms()) + return -1; + + // If mempool is limiting txs, no priority txs are allowed + CAmount minPoolFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(); + if (minPoolFee > 0) + return INF_PRIORITY; + + double median = -1; + while (median < 0 && (unsigned int)confTarget <= priStats.GetMaxConfirms()) { + median = priStats.EstimateMedianVal(confTarget++, SUFFICIENT_PRITXS, MIN_SUCCESS_PCT, true, nBestSeenHeight); + } + + if (answerFoundAtTarget) + *answerFoundAtTarget = confTarget - 1; + + return median; +} + void CBlockPolicyEstimator::Write(CAutoFile& fileout) { fileout << nBestSeenHeight; diff --git a/src/policy/fees.h b/src/policy/fees.h index 15577d128a..7a293267d4 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -15,6 +15,7 @@ class CAutoFile; class CFeeRate; class CTxMemPoolEntry; +class CTxMemPool; /** \class CBlockPolicyEstimator * The BlockPolicyEstimator is used for estimating the fee or priority needed @@ -182,8 +183,8 @@ static const unsigned int MAX_BLOCK_CONFIRMS = 25; /** Decay of .998 is a half-life of 346 blocks or about 2.4 days */ static const double DEFAULT_DECAY = .998; -/** Require greater than 85% of X fee transactions to be confirmed within Y blocks for X to be big enough */ -static const double MIN_SUCCESS_PCT = .85; +/** Require greater than 95% of X fee transactions to be confirmed within Y blocks for X to be big enough */ +static const double MIN_SUCCESS_PCT = .95; static const double UNLIKELY_PCT = .5; /** Require an avg of 1 tx in the combined fee bucket per block to have stat significance */ @@ -242,9 +243,21 @@ public: /** Return a fee estimate */ CFeeRate estimateFee(int confTarget); + /** Estimate fee rate needed to get be included in a block within + * confTarget blocks. If no answer can be given at confTarget, return an + * estimate at the lowest target where one can be given. + */ + CFeeRate estimateSmartFee(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool); + /** Return a priority estimate */ double estimatePriority(int confTarget); + /** Estimate priority needed to get be included in a block within + * confTarget blocks. If no answer can be given at confTarget, return an + * estimate at the lowest target where one can be given. + */ + double estimateSmartPriority(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool); + /** Write estimation data to a file */ void Write(CAutoFile& fileout); diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 4c96fbf5a5..019df72279 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -23,9 +23,6 @@ * 2. P2SH scripts with a crazy number of expensive * CHECKSIG/CHECKMULTISIG operations * - * Check transaction inputs, and make sure any - * pay-to-script-hash transactions are evaluating IsStandard scripts - * * Why bother? To avoid denial-of-service attacks; an attacker * can submit a standard HASH... OP_EQUAL transaction, * which will get accepted into blocks. The redemption @@ -50,7 +47,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) if (m < 1 || m > n) return false; } else if (whichType == TX_NULL_DATA && - (!GetBoolArg("-datacarrier", true) || scriptPubKey.size() > nMaxDatacarrierBytes)) + (!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) return false; return whichType != TX_NONSTANDARD; diff --git a/src/policy/policy.h b/src/policy/policy.h index 1551aecde8..726864f190 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -1,10 +1,10 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef BITCOIN_POLICY_H -#define BITCOIN_POLICY_H +#ifndef BITCOIN_POLICY_POLICY_H +#define BITCOIN_POLICY_POLICY_H #include "consensus/consensus.h" #include "script/interpreter.h" @@ -18,13 +18,15 @@ class CCoinsViewCache; static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000; static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0; /** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/ -static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 50000; +static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 0; /** The maximum size for transactions we're willing to relay/mine */ static const unsigned int MAX_STANDARD_TX_SIZE = 100000; /** Maximum number of signature check operations in an IsStandard() P2SH script */ static const unsigned int MAX_P2SH_SIGOPS = 15; /** The maximum number of sigops we're willing to relay/mine in a single tx */ static const unsigned int MAX_STANDARD_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; +/** Default for -maxmempool, maximum megabytes of mempool memory usage */ +static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300; /** * Standard script verification flags that standard transactions will comply * with. However scripts violating these flags may still be present in valid @@ -37,11 +39,15 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY SCRIPT_VERIFY_NULLDUMMY | SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS | SCRIPT_VERIFY_CLEANSTACK | - SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; + SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY | + SCRIPT_VERIFY_LOW_S; /** For convenience, standard but not mandatory verify flags. */ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; +/** Used as the flags parameter to CheckFinalTx() in non-consensus code */ +static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_MEDIAN_TIME_PAST; + bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); /** * Check for standard transaction types @@ -55,4 +61,4 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason); */ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs); -#endif // BITCOIN_POLICY_H +#endif // BITCOIN_POLICY_POLICY_H diff --git a/src/pow.cpp b/src/pow.cpp index bb53ad204b..7392defe64 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -52,6 +52,9 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params) { + if (params.fPowNoRetargeting) + return pindexLast->nBits; + // Limit adjustment step int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime; LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan); @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/prevector.h b/src/prevector.h new file mode 100644 index 0000000000..8992e305b3 --- /dev/null +++ b/src/prevector.h @@ -0,0 +1,486 @@ +#ifndef _BITCOIN_PREVECTOR_H_ +#define _BITCOIN_PREVECTOR_H_ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +#include <iterator> + +#pragma pack(push, 1) +/** Implements a drop-in replacement for std::vector<T> which stores up to N + * elements directly (without heap allocation). The types Size and Diff are + * used to store element counts, and can be any unsigned + signed type. + * + * Storage layout is either: + * - Direct allocation: + * - Size _size: the number of used elements (between 0 and N) + * - T direct[N]: an array of N elements of type T + * (only the first _size are initialized). + * - Indirect allocation: + * - Size _size: the number of used elements plus N + 1 + * - Size capacity: the number of allocated elements + * - T* indirect: a pointer to an array of capacity elements of type T + * (only the first _size are initialized). + * + * The data type T must be movable by memmove/realloc(). Once we switch to C++, + * move constructors can be used instead. + */ +template<unsigned int N, typename T, typename Size = uint32_t, typename Diff = int32_t> +class prevector { +public: + typedef Size size_type; + typedef Diff difference_type; + typedef T value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + + class iterator { + T* ptr; + public: + typedef Diff difference_type; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef std::random_access_iterator_tag iterator_category; + iterator(T* ptr_) : ptr(ptr_) {} + T& operator*() const { return *ptr; } + T* operator->() const { return ptr; } + T& operator[](size_type pos) { return ptr[pos]; } + const T& operator[](size_type pos) const { return ptr[pos]; } + iterator& operator++() { ptr++; return *this; } + iterator& operator--() { ptr--; return *this; } + iterator operator++(int) { iterator copy(*this); ++(*this); return copy; } + iterator operator--(int) { iterator copy(*this); --(*this); return copy; } + difference_type friend operator-(iterator a, iterator b) { return (&(*a) - &(*b)); } + iterator operator+(size_type n) { return iterator(ptr + n); } + iterator& operator+=(size_type n) { ptr += n; return *this; } + iterator operator-(size_type n) { return iterator(ptr - n); } + iterator& operator-=(size_type n) { ptr -= n; return *this; } + bool operator==(iterator x) const { return ptr == x.ptr; } + bool operator!=(iterator x) const { return ptr != x.ptr; } + bool operator>=(iterator x) const { return ptr >= x.ptr; } + bool operator<=(iterator x) const { return ptr <= x.ptr; } + bool operator>(iterator x) const { return ptr > x.ptr; } + bool operator<(iterator x) const { return ptr < x.ptr; } + }; + + class reverse_iterator { + T* ptr; + public: + typedef Diff difference_type; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef std::bidirectional_iterator_tag iterator_category; + reverse_iterator(T* ptr_) : ptr(ptr_) {} + T& operator*() { return *ptr; } + const T& operator*() const { return *ptr; } + T* operator->() { return ptr; } + const T* operator->() const { return ptr; } + reverse_iterator& operator--() { ptr++; return *this; } + reverse_iterator& operator++() { ptr--; return *this; } + reverse_iterator operator++(int) { reverse_iterator copy(*this); ++(*this); return copy; } + reverse_iterator operator--(int) { reverse_iterator copy(*this); --(*this); return copy; } + bool operator==(reverse_iterator x) const { return ptr == x.ptr; } + bool operator!=(reverse_iterator x) const { return ptr != x.ptr; } + }; + + class const_iterator { + const T* ptr; + public: + typedef Diff difference_type; + typedef const T value_type; + typedef const T* pointer; + typedef const T& reference; + typedef std::random_access_iterator_tag iterator_category; + const_iterator(const T* ptr_) : ptr(ptr_) {} + const_iterator(iterator x) : ptr(&(*x)) {} + const T& operator*() const { return *ptr; } + const T* operator->() const { return ptr; } + const T& operator[](size_type pos) const { return ptr[pos]; } + const_iterator& operator++() { ptr++; return *this; } + const_iterator& operator--() { ptr--; return *this; } + const_iterator operator++(int) { const_iterator copy(*this); ++(*this); return copy; } + const_iterator operator--(int) { const_iterator copy(*this); --(*this); return copy; } + difference_type friend operator-(const_iterator a, const_iterator b) { return (&(*a) - &(*b)); } + const_iterator operator+(size_type n) { return const_iterator(ptr + n); } + const_iterator& operator+=(size_type n) { ptr += n; return *this; } + const_iterator operator-(size_type n) { return const_iterator(ptr - n); } + const_iterator& operator-=(size_type n) { ptr -= n; return *this; } + bool operator==(const_iterator x) const { return ptr == x.ptr; } + bool operator!=(const_iterator x) const { return ptr != x.ptr; } + bool operator>=(const_iterator x) const { return ptr >= x.ptr; } + bool operator<=(const_iterator x) const { return ptr <= x.ptr; } + bool operator>(const_iterator x) const { return ptr > x.ptr; } + bool operator<(const_iterator x) const { return ptr < x.ptr; } + }; + + class const_reverse_iterator { + const T* ptr; + public: + typedef Diff difference_type; + typedef const T value_type; + typedef const T* pointer; + typedef const T& reference; + typedef std::bidirectional_iterator_tag iterator_category; + const_reverse_iterator(T* ptr_) : ptr(ptr_) {} + const_reverse_iterator(reverse_iterator x) : ptr(&(*x)) {} + const T& operator*() const { return *ptr; } + const T* operator->() const { return ptr; } + const_reverse_iterator& operator--() { ptr++; return *this; } + const_reverse_iterator& operator++() { ptr--; return *this; } + const_reverse_iterator operator++(int) { const_reverse_iterator copy(*this); ++(*this); return copy; } + const_reverse_iterator operator--(int) { const_reverse_iterator copy(*this); --(*this); return copy; } + bool operator==(const_reverse_iterator x) const { return ptr == x.ptr; } + bool operator!=(const_reverse_iterator x) const { return ptr != x.ptr; } + }; + +private: + size_type _size; + union direct_or_indirect { + char direct[sizeof(T) * N]; + struct { + size_type capacity; + char* indirect; + }; + } _union; + + T* direct_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.direct) + pos; } + const T* direct_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.direct) + pos; } + T* indirect_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.indirect) + pos; } + const T* indirect_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.indirect) + pos; } + bool is_direct() const { return _size <= N; } + + void change_capacity(size_type new_capacity) { + if (new_capacity <= N) { + if (!is_direct()) { + T* indirect = indirect_ptr(0); + T* src = indirect; + T* dst = direct_ptr(0); + memcpy(dst, src, size() * sizeof(T)); + free(indirect); + _size -= N + 1; + } + } else { + if (!is_direct()) { + _union.indirect = static_cast<char*>(realloc(_union.indirect, ((size_t)sizeof(T)) * new_capacity)); + _union.capacity = new_capacity; + } else { + char* new_indirect = static_cast<char*>(malloc(((size_t)sizeof(T)) * new_capacity)); + T* src = direct_ptr(0); + T* dst = reinterpret_cast<T*>(new_indirect); + memcpy(dst, src, size() * sizeof(T)); + _union.indirect = new_indirect; + _union.capacity = new_capacity; + _size += N + 1; + } + } + } + + T* item_ptr(difference_type pos) { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); } + const T* item_ptr(difference_type pos) const { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); } + +public: + void assign(size_type n, const T& val) { + clear(); + if (capacity() < n) { + change_capacity(n); + } + while (size() < n) { + _size++; + new(static_cast<void*>(item_ptr(size() - 1))) T(val); + } + } + + template<typename InputIterator> + void assign(InputIterator first, InputIterator last) { + size_type n = last - first; + clear(); + if (capacity() < n) { + change_capacity(n); + } + while (first != last) { + _size++; + new(static_cast<void*>(item_ptr(size() - 1))) T(*first); + ++first; + } + } + + prevector() : _size(0) {} + + explicit prevector(size_type n) : _size(0) { + resize(n); + } + + explicit prevector(size_type n, const T& val = T()) : _size(0) { + change_capacity(n); + while (size() < n) { + _size++; + new(static_cast<void*>(item_ptr(size() - 1))) T(val); + } + } + + template<typename InputIterator> + prevector(InputIterator first, InputIterator last) : _size(0) { + size_type n = last - first; + change_capacity(n); + while (first != last) { + _size++; + new(static_cast<void*>(item_ptr(size() - 1))) T(*first); + ++first; + } + } + + prevector(const prevector<N, T, Size, Diff>& other) : _size(0) { + change_capacity(other.size()); + const_iterator it = other.begin(); + while (it != other.end()) { + _size++; + new(static_cast<void*>(item_ptr(size() - 1))) T(*it); + ++it; + } + } + + prevector& operator=(const prevector<N, T, Size, Diff>& other) { + if (&other == this) { + return *this; + } + resize(0); + change_capacity(other.size()); + const_iterator it = other.begin(); + while (it != other.end()) { + _size++; + new(static_cast<void*>(item_ptr(size() - 1))) T(*it); + ++it; + } + return *this; + } + + size_type size() const { + return is_direct() ? _size : _size - N - 1; + } + + bool empty() const { + return size() == 0; + } + + iterator begin() { return iterator(item_ptr(0)); } + const_iterator begin() const { return const_iterator(item_ptr(0)); } + iterator end() { return iterator(item_ptr(size())); } + const_iterator end() const { return const_iterator(item_ptr(size())); } + + reverse_iterator rbegin() { return reverse_iterator(item_ptr(size() - 1)); } + const_reverse_iterator rbegin() const { return const_reverse_iterator(item_ptr(size() - 1)); } + reverse_iterator rend() { return reverse_iterator(item_ptr(-1)); } + const_reverse_iterator rend() const { return const_reverse_iterator(item_ptr(-1)); } + + size_t capacity() const { + if (is_direct()) { + return N; + } else { + return _union.capacity; + } + } + + T& operator[](size_type pos) { + return *item_ptr(pos); + } + + const T& operator[](size_type pos) const { + return *item_ptr(pos); + } + + void resize(size_type new_size) { + while (size() > new_size) { + item_ptr(size() - 1)->~T(); + _size--; + } + if (new_size > capacity()) { + change_capacity(new_size); + } + while (size() < new_size) { + _size++; + new(static_cast<void*>(item_ptr(size() - 1))) T(); + } + } + + void reserve(size_type new_capacity) { + if (new_capacity > capacity()) { + change_capacity(new_capacity); + } + } + + void shrink_to_fit() { + change_capacity(size()); + } + + void clear() { + resize(0); + } + + iterator insert(iterator pos, const T& value) { + size_type p = pos - begin(); + size_type new_size = size() + 1; + if (capacity() < new_size) { + change_capacity(new_size + (new_size >> 1)); + } + memmove(item_ptr(p + 1), item_ptr(p), (size() - p) * sizeof(T)); + _size++; + new(static_cast<void*>(item_ptr(p))) T(value); + return iterator(item_ptr(p)); + } + + void insert(iterator pos, size_type count, const T& value) { + size_type p = pos - begin(); + size_type new_size = size() + count; + if (capacity() < new_size) { + change_capacity(new_size + (new_size >> 1)); + } + memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T)); + _size += count; + for (size_type i = 0; i < count; i++) { + new(static_cast<void*>(item_ptr(p + i))) T(value); + } + } + + template<typename InputIterator> + void insert(iterator pos, InputIterator first, InputIterator last) { + size_type p = pos - begin(); + difference_type count = last - first; + size_type new_size = size() + count; + if (capacity() < new_size) { + change_capacity(new_size + (new_size >> 1)); + } + memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T)); + _size += count; + while (first != last) { + new(static_cast<void*>(item_ptr(p))) T(*first); + ++p; + ++first; + } + } + + iterator erase(iterator pos) { + (*pos).~T(); + memmove(&(*pos), &(*pos) + 1, ((char*)&(*end())) - ((char*)(1 + &(*pos)))); + _size--; + return pos; + } + + iterator erase(iterator first, iterator last) { + iterator p = first; + char* endp = (char*)&(*end()); + while (p != last) { + (*p).~T(); + _size--; + ++p; + } + memmove(&(*first), &(*last), endp - ((char*)(&(*last)))); + return first; + } + + void push_back(const T& value) { + size_type new_size = size() + 1; + if (capacity() < new_size) { + change_capacity(new_size + (new_size >> 1)); + } + new(item_ptr(size())) T(value); + _size++; + } + + void pop_back() { + _size--; + } + + T& front() { + return *item_ptr(0); + } + + const T& front() const { + return *item_ptr(0); + } + + T& back() { + return *item_ptr(size() - 1); + } + + const T& back() const { + return *item_ptr(size() - 1); + } + + void swap(prevector<N, T, Size, Diff>& other) { + if (_size & other._size & 1) { + std::swap(_union.capacity, other._union.capacity); + std::swap(_union.indirect, other._union.indirect); + } else { + std::swap(_union, other._union); + } + std::swap(_size, other._size); + } + + ~prevector() { + clear(); + if (!is_direct()) { + free(_union.indirect); + _union.indirect = NULL; + } + } + + bool operator==(const prevector<N, T, Size, Diff>& other) const { + if (other.size() != size()) { + return false; + } + const_iterator b1 = begin(); + const_iterator b2 = other.begin(); + const_iterator e1 = end(); + while (b1 != e1) { + if ((*b1) != (*b2)) { + return false; + } + ++b1; + ++b2; + } + return true; + } + + bool operator!=(const prevector<N, T, Size, Diff>& other) const { + return !(*this == other); + } + + bool operator<(const prevector<N, T, Size, Diff>& other) const { + if (size() < other.size()) { + return true; + } + if (size() > other.size()) { + return false; + } + const_iterator b1 = begin(); + const_iterator b2 = other.begin(); + const_iterator e1 = end(); + while (b1 != e1) { + if ((*b1) < (*b2)) { + return true; + } + if ((*b2) < (*b1)) { + return false; + } + ++b1; + ++b2; + } + return false; + } + + size_t allocated_memory() const { + if (is_direct()) { + return 0; + } else { + return ((size_t)(sizeof(T))) * _union.capacity; + } + } +}; +#pragma pack(pop) + +#endif diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 7a58074d24..59e949d71a 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,69 +15,6 @@ uint256 CBlockHeader::GetHash() const return SerializeHash(*this); } -uint256 CBlock::ComputeMerkleRoot(bool* fMutated) const -{ - /* WARNING! If you're reading this because you're learning about crypto - and/or designing a new system that will use merkle trees, keep in mind - 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. - */ - std::vector<uint256> vMerkleTree; - vMerkleTree.reserve(vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes. - for (std::vector<CTransaction>::const_iterator it(vtx.begin()); it != vtx.end(); ++it) - vMerkleTree.push_back(it->GetHash()); - 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() ? uint256() : vMerkleTree.back()); -} - std::string CBlock::ToString() const { std::stringstream s; diff --git a/src/primitives/block.h b/src/primitives/block.h index 86106098f5..0e93399c08 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -21,7 +21,7 @@ class CBlockHeader { public: // header - static const int32_t CURRENT_VERSION=3; + static const int32_t CURRENT_VERSION=4; int32_t nVersion; uint256 hashPrevBlock; uint256 hashMerkleRoot; @@ -118,12 +118,6 @@ public: return block; } - // Build the merkle tree for this block and return the merkle root. - // If non-NULL, *mutated is set to whether mutation was detected in the merkle - // tree (a duplication of transactions in the block leading to an identical - // merkle root). - uint256 ComputeMerkleRoot(bool* mutated = NULL) const; - std::string ToString() const; }; diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 46d3cbbe2e..aea96d8a12 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 2a457cdae7..8bd6d00e2e 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -74,7 +74,7 @@ public: template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(prevout); - READWRITE(scriptSig); + READWRITE(*(CScriptBase*)(&scriptSig)); READWRITE(nSequence); } @@ -119,7 +119,7 @@ public: template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(nValue); - READWRITE(scriptPubKey); + READWRITE(*(CScriptBase*)(&scriptPubKey)); } void SetNull() @@ -143,8 +143,8 @@ public: // to spend something, then we consider it dust. // A typical spendable txout is 34 bytes big, and will // need a CTxIn of at least 148 bytes to spend: - // so dust is a spendable txout less than 546 satoshis - // with default minRelayTxFee. + // so dust is a spendable txout less than + // 546*minRelayTxFee/1000 (in satoshis) if (scriptPubKey.IsUnspendable()) return 0; diff --git a/src/protocol.cpp b/src/protocol.cpp index dd855aa33a..c1c7c0b96b 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,13 +12,67 @@ # include <arpa/inet.h> #endif +namespace NetMsgType { +const char *VERSION="version"; +const char *VERACK="verack"; +const char *ADDR="addr"; +const char *INV="inv"; +const char *GETDATA="getdata"; +const char *MERKLEBLOCK="merkleblock"; +const char *GETBLOCKS="getblocks"; +const char *GETHEADERS="getheaders"; +const char *TX="tx"; +const char *HEADERS="headers"; +const char *BLOCK="block"; +const char *GETADDR="getaddr"; +const char *MEMPOOL="mempool"; +const char *PING="ping"; +const char *PONG="pong"; +const char *ALERT="alert"; +const char *NOTFOUND="notfound"; +const char *FILTERLOAD="filterload"; +const char *FILTERADD="filteradd"; +const char *FILTERCLEAR="filterclear"; +const char *REJECT="reject"; +const char *SENDHEADERS="sendheaders"; +}; + static const char* ppszTypeName[] = { - "ERROR", - "tx", - "block", - "filtered block" + "ERROR", // Should never occur + NetMsgType::TX, + NetMsgType::BLOCK, + "filtered block" // Should never occur +}; + +/** All known message types. Keep this in the same order as the list of + * messages above and in protocol.h. + */ +const static std::string allNetMessageTypes[] = { + NetMsgType::VERSION, + NetMsgType::VERACK, + NetMsgType::ADDR, + NetMsgType::INV, + NetMsgType::GETDATA, + NetMsgType::MERKLEBLOCK, + NetMsgType::GETBLOCKS, + NetMsgType::GETHEADERS, + NetMsgType::TX, + NetMsgType::HEADERS, + NetMsgType::BLOCK, + NetMsgType::GETADDR, + NetMsgType::MEMPOOL, + NetMsgType::PING, + NetMsgType::PONG, + NetMsgType::ALERT, + NetMsgType::NOTFOUND, + NetMsgType::FILTERLOAD, + NetMsgType::FILTERADD, + NetMsgType::FILTERCLEAR, + NetMsgType::REJECT, + NetMsgType::SENDHEADERS }; +const static std::vector<std::string> allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes)); CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn) { @@ -140,3 +194,8 @@ std::string CInv::ToString() const { return strprintf("%s %s", GetCommand(), hash.ToString()); } + +const std::vector<std::string> &getAllNetMessageTypes() +{ + return allNetMessageTypesVec; +} diff --git a/src/protocol.h b/src/protocol.h index 50aeaf44ba..c8b8d20ead 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -65,6 +65,165 @@ public: unsigned int nChecksum; }; +/** + * Bitcoin protocol message types. When adding new message types, don't forget + * to update allNetMessageTypes in protocol.cpp. + */ +namespace NetMsgType { + +/** + * The version message provides information about the transmitting node to the + * receiving node at the beginning of a connection. + * @see https://bitcoin.org/en/developer-reference#version + */ +extern const char *VERSION; +/** + * The verack message acknowledges a previously-received version message, + * informing the connecting node that it can begin to send other messages. + * @see https://bitcoin.org/en/developer-reference#verack + */ +extern const char *VERACK; +/** + * The addr (IP address) message relays connection information for peers on the + * network. + * @see https://bitcoin.org/en/developer-reference#addr + */ +extern const char *ADDR; +/** + * The inv message (inventory message) transmits one or more inventories of + * objects known to the transmitting peer. + * @see https://bitcoin.org/en/developer-reference#inv + */ +extern const char *INV; +/** + * The getdata message requests one or more data objects from another node. + * @see https://bitcoin.org/en/developer-reference#getdata + */ +extern const char *GETDATA; +/** + * The merkleblock message is a reply to a getdata message which requested a + * block using the inventory type MSG_MERKLEBLOCK. + * @since protocol version 70001 as described by BIP37. + * @see https://bitcoin.org/en/developer-reference#merkleblock + */ +extern const char *MERKLEBLOCK; +/** + * The getblocks message requests an inv message that provides block header + * hashes starting from a particular point in the block chain. + * @see https://bitcoin.org/en/developer-reference#getblocks + */ +extern const char *GETBLOCKS; +/** + * The getheaders message requests a headers message that provides block + * headers starting from a particular point in the block chain. + * @since protocol version 31800. + * @see https://bitcoin.org/en/developer-reference#getheaders + */ +extern const char *GETHEADERS; +/** + * The tx message transmits a single transaction. + * @see https://bitcoin.org/en/developer-reference#tx + */ +extern const char *TX; +/** + * The headers message sends one or more block headers to a node which + * previously requested certain headers with a getheaders message. + * @since protocol version 31800. + * @see https://bitcoin.org/en/developer-reference#headers + */ +extern const char *HEADERS; +/** + * The block message transmits a single serialized block. + * @see https://bitcoin.org/en/developer-reference#block + */ +extern const char *BLOCK; +/** + * The getaddr message requests an addr message from the receiving node, + * preferably one with lots of IP addresses of other receiving nodes. + * @see https://bitcoin.org/en/developer-reference#getaddr + */ +extern const char *GETADDR; +/** + * The mempool message requests the TXIDs of transactions that the receiving + * node has verified as valid but which have not yet appeared in a block. + * @since protocol version 60002. + * @see https://bitcoin.org/en/developer-reference#mempool + */ +extern const char *MEMPOOL; +/** + * The ping message is sent periodically to help confirm that the receiving + * peer is still connected. + * @see https://bitcoin.org/en/developer-reference#ping + */ +extern const char *PING; +/** + * The pong message replies to a ping message, proving to the pinging node that + * the ponging node is still alive. + * @since protocol version 60001 as described by BIP31. + * @see https://bitcoin.org/en/developer-reference#pong + */ +extern const char *PONG; +/** + * The alert message warns nodes of problems that may affect them or the rest + * of the network. + * @since protocol version 311. + * @see https://bitcoin.org/en/developer-reference#alert + */ +extern const char *ALERT; +/** + * The notfound message is a reply to a getdata message which requested an + * object the receiving node does not have available for relay. + * @ince protocol version 70001. + * @see https://bitcoin.org/en/developer-reference#notfound + */ +extern const char *NOTFOUND; +/** + * The filterload message tells the receiving peer to filter all relayed + * transactions and requested merkle blocks through the provided filter. + * @since protocol version 70001 as described by BIP37. + * Only available with service bit NODE_BLOOM since protocol version + * 70011 as described by BIP111. + * @see https://bitcoin.org/en/developer-reference#filterload + */ +extern const char *FILTERLOAD; +/** + * The filteradd message tells the receiving peer to add a single element to a + * previously-set bloom filter, such as a new public key. + * @since protocol version 70001 as described by BIP37. + * Only available with service bit NODE_BLOOM since protocol version + * 70011 as described by BIP111. + * @see https://bitcoin.org/en/developer-reference#filteradd + */ +extern const char *FILTERADD; +/** + * The filterclear message tells the receiving peer to remove a previously-set + * bloom filter. + * @since protocol version 70001 as described by BIP37. + * Only available with service bit NODE_BLOOM since protocol version + * 70011 as described by BIP111. + * @see https://bitcoin.org/en/developer-reference#filterclear + */ +extern const char *FILTERCLEAR; +/** + * The reject message informs the receiving node that one of its previous + * messages has been rejected. + * @since protocol version 70002 as described by BIP61. + * @see https://bitcoin.org/en/developer-reference#reject + */ +extern const char *REJECT; +/** + * Indicates that a node prefers to receive new block announcements via a + * "headers" message rather than an "inv". + * @since protocol version 70012 as described by BIP130. + * @see https://bitcoin.org/en/developer-reference#sendheaders + */ +extern const char *SENDHEADERS; + +}; + +/* Get a vector of all valid message types (see above) */ +const std::vector<std::string> &getAllNetMessageTypes(); + /** nServices flags */ enum { // NODE_NETWORK means that the node is capable of serving the block chain. It is currently diff --git a/src/pubkey.cpp b/src/pubkey.cpp index bdab137600..db06a89285 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -1,22 +1,187 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "pubkey.h" -#include "eccryptoverify.h" +#include <secp256k1.h> +#include <secp256k1_recovery.h> -#include "ecwrapper.h" +namespace +{ +/* Global secp256k1_context object used for verification. */ +secp256k1_context* secp256k1_context_verify = NULL; +} + +/** This function is taken from the libsecp256k1 distribution and implements + * DER parsing for ECDSA signatures, while supporting an arbitrary subset of + * format violations. + * + * Supported violations include negative integers, excessive padding, garbage + * at the end, and overly long length descriptors. This is safe to use in + * Bitcoin because since the activation of BIP66, signatures are verified to be + * strict DER before being passed to this module, and we know it supports all + * violations present in the blockchain before that point. + */ +static int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { + size_t rpos, rlen, spos, slen; + size_t pos = 0; + size_t lenbyte; + unsigned char tmpsig[64] = {0}; + int overflow = 0; + + /* Hack to initialize sig with a correctly-parsed but invalid signature. */ + secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); + + /* Sequence tag byte */ + if (pos == inputlen || input[pos] != 0x30) { + return 0; + } + pos++; + + /* Sequence length bytes */ + if (pos == inputlen) { + return 0; + } + lenbyte = input[pos++]; + if (lenbyte & 0x80) { + lenbyte -= 0x80; + if (pos + lenbyte > inputlen) { + return 0; + } + pos += lenbyte; + } + + /* Integer tag byte for R */ + if (pos == inputlen || input[pos] != 0x02) { + return 0; + } + pos++; + + /* Integer length for R */ + if (pos == inputlen) { + return 0; + } + lenbyte = input[pos++]; + if (lenbyte & 0x80) { + lenbyte -= 0x80; + if (pos + lenbyte > inputlen) { + return 0; + } + while (lenbyte > 0 && input[pos] == 0) { + pos++; + lenbyte--; + } + if (lenbyte >= sizeof(size_t)) { + return 0; + } + rlen = 0; + while (lenbyte > 0) { + rlen = (rlen << 8) + input[pos]; + pos++; + lenbyte--; + } + } else { + rlen = lenbyte; + } + if (rlen > inputlen - pos) { + return 0; + } + rpos = pos; + pos += rlen; + + /* Integer tag byte for S */ + if (pos == inputlen || input[pos] != 0x02) { + return 0; + } + pos++; + + /* Integer length for S */ + if (pos == inputlen) { + return 0; + } + lenbyte = input[pos++]; + if (lenbyte & 0x80) { + lenbyte -= 0x80; + if (pos + lenbyte > inputlen) { + return 0; + } + while (lenbyte > 0 && input[pos] == 0) { + pos++; + lenbyte--; + } + if (lenbyte >= sizeof(size_t)) { + return 0; + } + slen = 0; + while (lenbyte > 0) { + slen = (slen << 8) + input[pos]; + pos++; + lenbyte--; + } + } else { + slen = lenbyte; + } + if (slen > inputlen - pos) { + return 0; + } + spos = pos; + pos += slen; + + /* Ignore leading zeroes in R */ + while (rlen > 0 && input[rpos] == 0) { + rlen--; + rpos++; + } + /* Copy R value */ + if (rlen > 32) { + overflow = 1; + } else { + memcpy(tmpsig + 32 - rlen, input + rpos, rlen); + } + + /* Ignore leading zeroes in S */ + while (slen > 0 && input[spos] == 0) { + slen--; + spos++; + } + /* Copy S value */ + if (slen > 32) { + overflow = 1; + } else { + memcpy(tmpsig + 64 - slen, input + spos, slen); + } + + if (!overflow) { + overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); + } + if (overflow) { + /* Overwrite the result again with a correctly-parsed but invalid + signature if parsing failed. */ + memset(tmpsig, 0, 64); + secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); + } + return 1; +} bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const { if (!IsValid()) return false; - CECKey key; - if (!key.SetPubKey(begin(), size())) + secp256k1_pubkey pubkey; + secp256k1_ecdsa_signature sig; + if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) { return false; - if (!key.Verify(hash, vchSig)) + } + if (vchSig.size() == 0) { return false; - return true; + } + if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, &vchSig[0], vchSig.size())) { + return false; + } + /* libsecp256k1's ECDSA verification requires lower-S signatures, which have + * not historically been enforced in Bitcoin, so normalize them first. */ + secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, &sig, &sig); + return secp256k1_ecdsa_verify(secp256k1_context_verify, &sig, hash.begin(), &pubkey); } bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) { @@ -24,33 +189,39 @@ bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned cha return false; int recid = (vchSig[0] - 27) & 3; bool fComp = ((vchSig[0] - 27) & 4) != 0; - CECKey key; - if (!key.Recover(hash, &vchSig[1], recid)) + secp256k1_pubkey pubkey; + secp256k1_ecdsa_recoverable_signature sig; + if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid)) { return false; - std::vector<unsigned char> pubkey; - key.GetPubKey(pubkey, fComp); - Set(pubkey.begin(), pubkey.end()); + } + if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig, hash.begin())) { + return false; + } + unsigned char pub[65]; + size_t publen = 65; + secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); + Set(pub, pub + publen); return true; } bool CPubKey::IsFullyValid() const { if (!IsValid()) return false; - CECKey key; - if (!key.SetPubKey(begin(), size())) - return false; - return true; + secp256k1_pubkey pubkey; + return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size()); } bool CPubKey::Decompress() { if (!IsValid()) return false; - CECKey key; - if (!key.SetPubKey(begin(), size())) + secp256k1_pubkey pubkey; + if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) { return false; - std::vector<unsigned char> pubkey; - key.GetPubKey(pubkey, false); - Set(pubkey.begin(), pubkey.end()); + } + unsigned char pub[65]; + size_t publen = 65; + secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED); + Set(pub, pub + publen); return true; } @@ -61,13 +232,18 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChi unsigned char out[64]; BIP32Hash(cc, nChild, *begin(), begin()+1, out); memcpy(ccChild.begin(), out+32, 32); - 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()); - return ret; + secp256k1_pubkey pubkey; + if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) { + return false; + } + if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &pubkey, out)) { + return false; + } + unsigned char pub[33]; + size_t publen = 33; + secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED); + pubkeyChild.Set(pub, pub + publen); + return true; } void CExtPubKey::Encode(unsigned char code[74]) const { @@ -95,3 +271,33 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const { out.nChild = nChild; return pubkey.Derive(out.pubkey, out.chaincode, nChild, chaincode); } + +/* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) { + secp256k1_ecdsa_signature sig; + if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, &vchSig[0], vchSig.size())) { + return false; + } + return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, NULL, &sig)); +} + +/* static */ int ECCVerifyHandle::refcount = 0; + +ECCVerifyHandle::ECCVerifyHandle() +{ + if (refcount == 0) { + assert(secp256k1_context_verify == NULL); + secp256k1_context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); + assert(secp256k1_context_verify != NULL); + } + refcount++; +} + +ECCVerifyHandle::~ECCVerifyHandle() +{ + refcount--; + if (refcount == 0) { + assert(secp256k1_context_verify != NULL); + secp256k1_context_destroy(secp256k1_context_verify); + secp256k1_context_verify = NULL; + } +} diff --git a/src/pubkey.h b/src/pubkey.h index cce9c826e5..e1a17b6582 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -177,6 +177,11 @@ public: */ bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const; + /** + * Check whether a signature is normalized (lower-S). + */ + static bool CheckLowS(const std::vector<unsigned char>& vchSig); + //! Recover a public key from a compact signature. bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig); @@ -205,4 +210,15 @@ struct CExtPubKey { bool Derive(CExtPubKey& out, unsigned int nChild) const; }; +/** Users of this module must hold an ECCVerifyHandle. The constructor and + * destructor of these are not allowed to run in parallel, though. */ +class ECCVerifyHandle +{ + static int refcount; + +public: + ECCVerifyHandle(); + ~ECCVerifyHandle(); +}; + #endif // BITCOIN_PUBKEY_H diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 8bd1586446..135f15ffa8 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index 92e6cab9ac..c22566d473 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index c5ac07cfc2..71ed3618e4 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -218,7 +218,7 @@ QVariant AddressTableModel::data(const QModelIndex &index, int role) const QFont font; if(index.column() == Address) { - font = GUIUtil::bitcoinAddressFont(); + font = GUIUtil::fixedPitchFont(); } return font; } diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 2b7475c4e2..d04b95ebae 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 441814ff07..680751bb6a 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index d4d832825a..727b5a1ada 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp index 33792af5ba..d95106b5ac 100644 --- a/src/qt/bantablemodel.cpp +++ b/src/qt/bantablemodel.cpp @@ -103,7 +103,7 @@ int BanTableModel::rowCount(const QModelIndex &parent) const int BanTableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return columns.length();; + return columns.length(); } QVariant BanTableModel::data(const QModelIndex &index, int role) const @@ -178,4 +178,4 @@ bool BanTableModel::shouldShow() if (priv->size() > 0) return true; return false; -}
\ No newline at end of file +} diff --git a/src/qt/bantablemodel.h b/src/qt/bantablemodel.h index c21dd04e31..fe9600ac0b 100644 --- a/src/qt/bantablemodel.h +++ b/src/qt/bantablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index ea7f86d18e..dcf752cc32 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -201,8 +201,10 @@ public: /// Create payment server void createPaymentServer(); #endif + /// parameter interaction/setup based on rules + void parameterSetup(); /// Create options model - void createOptionsModel(); + void createOptionsModel(bool resetSettings); /// Create main window void createWindow(const NetworkStyle *networkStyle); /// Create splash screen @@ -309,14 +311,8 @@ BitcoinApplication::BitcoinApplication(int &argc, char **argv): // UI per-platform customization // This must be done inside the BitcoinApplication constructor, or after it, because // PlatformStyle::instantiate requires a QApplication -#if defined(Q_OS_MAC) - std::string platformName = "macosx"; -#elif defined(Q_OS_WIN) - std::string platformName = "windows"; -#else - std::string platformName = "other"; -#endif - platformName = GetArg("-uiplatform", platformName); + std::string platformName; + platformName = GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM); platformStyle = PlatformStyle::instantiate(QString::fromStdString(platformName)); if (!platformStyle) // Fall back to "other" if specified name not found platformStyle = PlatformStyle::instantiate("other"); @@ -352,9 +348,9 @@ void BitcoinApplication::createPaymentServer() } #endif -void BitcoinApplication::createOptionsModel() +void BitcoinApplication::createOptionsModel(bool resetSettings) { - optionsModel = new OptionsModel(); + optionsModel = new OptionsModel(NULL, resetSettings); } void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) @@ -397,6 +393,12 @@ void BitcoinApplication::startThread() coreThread->start(); } +void BitcoinApplication::parameterSetup() +{ + InitLogging(); + InitParameterInteraction(); +} + void BitcoinApplication::requestInitialize() { qDebug() << __func__ << ": Requesting initialize"; @@ -563,7 +565,7 @@ int main(int argc, char *argv[]) // Show help message immediately after parsing command-line options (for "-lang") and setting locale, // but before showing splash screen. - if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version")) + if (mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) { HelpMessageDialog help(NULL, mapArgs.count("-version")); help.showOrPrint(); @@ -597,8 +599,10 @@ int main(int argc, char *argv[]) // - Needs to be done before createOptionsModel // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause) - if (!SelectParamsFromCommandLine()) { - QMessageBox::critical(0, QObject::tr("Bitcoin Core"), QObject::tr("Error: Invalid combination of -regtest and -testnet.")); + try { + SelectParams(ChainNameFromCommandLine()); + } catch(std::exception &e) { + QMessageBox::critical(0, QObject::tr("Bitcoin Core"), QObject::tr("Error: %1").arg(e.what())); return 1; } #ifdef ENABLE_WALLET @@ -642,13 +646,15 @@ int main(int argc, char *argv[]) // Install qDebug() message handler to route to debug.log qInstallMessageHandler(DebugMessageHandler); #endif + // Allow parameter interaction before we create the options model + app.parameterSetup(); // Load GUI settings from QSettings - app.createOptionsModel(); + app.createOptionsModel(mapArgs.count("-resetguisettings") != 0); // Subscribe to global signals from core uiInterface.InitMessage.connect(InitMessage); - if (GetBoolArg("-splash", true) && !GetBoolArg("-min", false)) + if (GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !GetBoolArg("-min", false)) app.createSplashScreen(networkStyle.data()); try diff --git a/src/qt/bitcoin_locale.qrc b/src/qt/bitcoin_locale.qrc index b70a107397..a8a0253b07 100644 --- a/src/qt/bitcoin_locale.qrc +++ b/src/qt/bitcoin_locale.qrc @@ -1,36 +1,40 @@ <!DOCTYPE RCC><RCC version="1.0"> <qresource prefix="/translations"> - <file alias="ach">locale/bitcoin_ach.qm</file> <file alias="af_ZA">locale/bitcoin_af_ZA.qm</file> <file alias="ar">locale/bitcoin_ar.qm</file> <file alias="be_BY">locale/bitcoin_be_BY.qm</file> + <file alias="bg_BG">locale/bitcoin_bg_BG.qm</file> <file alias="bg">locale/bitcoin_bg.qm</file> <file alias="bs">locale/bitcoin_bs.qm</file> <file alias="ca_ES">locale/bitcoin_ca_ES.qm</file> <file alias="ca">locale/bitcoin_ca.qm</file> <file alias="ca@valencia">locale/bitcoin_ca@valencia.qm</file> - <file alias="cmn">locale/bitcoin_cmn.qm</file> + <file alias="cs_CZ">locale/bitcoin_cs_CZ.qm</file> <file alias="cs">locale/bitcoin_cs.qm</file> <file alias="cy">locale/bitcoin_cy.qm</file> <file alias="da">locale/bitcoin_da.qm</file> <file alias="de">locale/bitcoin_de.qm</file> <file alias="el_GR">locale/bitcoin_el_GR.qm</file> + <file alias="el">locale/bitcoin_el.qm</file> + <file alias="en_GB">locale/bitcoin_en_GB.qm</file> <file alias="en">locale/bitcoin_en.qm</file> <file alias="eo">locale/bitcoin_eo.qm</file> <file alias="es_CL">locale/bitcoin_es_CL.qm</file> <file alias="es_DO">locale/bitcoin_es_DO.qm</file> + <file alias="es_ES">locale/bitcoin_es_ES.qm</file> <file alias="es_MX">locale/bitcoin_es_MX.qm</file> <file alias="es">locale/bitcoin_es.qm</file> <file alias="es_UY">locale/bitcoin_es_UY.qm</file> + <file alias="es_VE">locale/bitcoin_es_VE.qm</file> <file alias="et">locale/bitcoin_et.qm</file> <file alias="eu_ES">locale/bitcoin_eu_ES.qm</file> <file alias="fa_IR">locale/bitcoin_fa_IR.qm</file> <file alias="fa">locale/bitcoin_fa.qm</file> <file alias="fi">locale/bitcoin_fi.qm</file> <file alias="fr_CA">locale/bitcoin_fr_CA.qm</file> + <file alias="fr_FR">locale/bitcoin_fr_FR.qm</file> <file alias="fr">locale/bitcoin_fr.qm</file> <file alias="gl">locale/bitcoin_gl.qm</file> - <file alias="gu_IN">locale/bitcoin_gu_IN.qm</file> <file alias="he">locale/bitcoin_he.qm</file> <file alias="hi_IN">locale/bitcoin_hi_IN.qm</file> <file alias="hr">locale/bitcoin_hr.qm</file> @@ -45,6 +49,7 @@ <file alias="la">locale/bitcoin_la.qm</file> <file alias="lt">locale/bitcoin_lt.qm</file> <file alias="lv_LV">locale/bitcoin_lv_LV.qm</file> + <file alias="mk_MK">locale/bitcoin_mk_MK.qm</file> <file alias="mn">locale/bitcoin_mn.qm</file> <file alias="ms_MY">locale/bitcoin_ms_MY.qm</file> <file alias="nb">locale/bitcoin_nb.qm</file> @@ -54,14 +59,15 @@ <file alias="pt_BR">locale/bitcoin_pt_BR.qm</file> <file alias="pt_PT">locale/bitcoin_pt_PT.qm</file> <file alias="ro_RO">locale/bitcoin_ro_RO.qm</file> + <file alias="ru_RU">locale/bitcoin_ru_RU.qm</file> <file alias="ru">locale/bitcoin_ru.qm</file> - <file alias="sah">locale/bitcoin_sah.qm</file> <file alias="sk">locale/bitcoin_sk.qm</file> <file alias="sl_SI">locale/bitcoin_sl_SI.qm</file> <file alias="sq">locale/bitcoin_sq.qm</file> <file alias="sr">locale/bitcoin_sr.qm</file> <file alias="sv">locale/bitcoin_sv.qm</file> <file alias="th_TH">locale/bitcoin_th_TH.qm</file> + <file alias="tr_TR">locale/bitcoin_tr_TR.qm</file> <file alias="tr">locale/bitcoin_tr.qm</file> <file alias="uk">locale/bitcoin_uk.qm</file> <file alias="ur_PK">locale/bitcoin_ur_PK.qm</file> @@ -69,7 +75,7 @@ <file alias="vi">locale/bitcoin_vi.qm</file> <file alias="vi_VN">locale/bitcoin_vi_VN.qm</file> <file alias="zh_CN">locale/bitcoin_zh_CN.qm</file> - <file alias="zh_HK">locale/bitcoin_zh_HK.qm</file> + <file alias="zh">locale/bitcoin_zh.qm</file> <file alias="zh_TW">locale/bitcoin_zh_TW.qm</file> </qresource> </RCC> diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index d19b9fd4af..73eb35a54e 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h index 3703b1f8d7..2f03a3d171 100644 --- a/src/qt/bitcoinamountfield.h +++ b/src/qt/bitcoinamountfield.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index d930d15953..701c96d06f 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -44,6 +44,7 @@ #include <QProgressBar> #include <QProgressDialog> #include <QSettings> +#include <QShortcut> #include <QStackedWidget> #include <QStatusBar> #include <QStyle> @@ -58,6 +59,16 @@ #include <QUrlQuery> #endif +const std::string BitcoinGUI::DEFAULT_UIPLATFORM = +#if defined(Q_OS_MAC) + "macosx" +#elif defined(Q_OS_WIN) + "windows" +#else + "other" +#endif + ; + const QString BitcoinGUI::DEFAULT_WALLET = "~Default"; BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent) : @@ -364,6 +375,9 @@ void BitcoinGUI::createActions() connect(openAction, SIGNAL(triggered()), this, SLOT(openClicked())); } #endif // ENABLE_WALLET + + new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_C), this, SLOT(showDebugWindowActivateConsole())); + new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_D), this, SLOT(showDebugWindow())); } void BitcoinGUI::createMenuBar() @@ -439,8 +453,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) setNumConnections(clientModel->getNumConnections()); connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); - setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate()); - connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime))); + setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate(), clientModel->getVerificationProgress(NULL)); + connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(setNumBlocks(int,QDateTime,double))); // Receive and report messages from client model connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int))); @@ -597,6 +611,12 @@ void BitcoinGUI::showDebugWindow() rpcConsole->activateWindow(); } +void BitcoinGUI::showDebugWindowActivateConsole() +{ + rpcConsole->setTabFocus(RPCConsole::TAB_CONSOLE); + showDebugWindow(); +} + void BitcoinGUI::showHelpMessageClicked() { helpMessageDialog->show(); @@ -662,7 +682,7 @@ void BitcoinGUI::setNumConnections(int count) labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count)); } -void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate) +void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress) { if(!clientModel) return; @@ -739,7 +759,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate) progressBarLabel->setVisible(true); progressBar->setFormat(tr("%1 behind").arg(timeBehindText)); progressBar->setMaximum(1000000000); - progressBar->setValue(clientModel->getVerificationProgress() * 1000000000.0 + 0.5); + progressBar->setValue(nVerificationProgress * 1000000000.0 + 0.5); progressBar->setVisible(true); tooltip = tr("Catching up...") + QString("<br>") + tooltip; diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 717f2bd12d..871ca1ba34 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -48,6 +48,7 @@ class BitcoinGUI : public QMainWindow public: static const QString DEFAULT_WALLET; + static const std::string DEFAULT_UIPLATFORM; explicit BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent = 0); ~BitcoinGUI(); @@ -149,7 +150,7 @@ public Q_SLOTS: /** Set number of connections shown in the UI */ void setNumConnections(int count); /** Set number of blocks and last block date shown in the UI */ - void setNumBlocks(int count, const QDateTime& blockDate); + void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress); /** Notify the user of an event from the core network or transaction handling code. @param[in] title the message box / notification title @@ -198,6 +199,8 @@ private Q_SLOTS: void aboutClicked(); /** Show debug window */ void showDebugWindow(); + /** Show debug window and set focus to the console */ + void showDebugWindowActivateConsole(); /** Show help message dialog */ void showHelpMessageClicked(); #ifndef Q_OS_MAC diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 3cde2657cf..6b5f243668 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -13,6 +13,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "(1 = keep tx meta data e.g. account owner and payment request information, 2 " "= drop tx meta data)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"-maxtxfee is set very high! Fees this large could be paid on a single " +"transaction."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"-paytxfee is set very high! This is the transaction fee you will pay if you " +"send a transaction."), +QT_TRANSLATE_NOOP("bitcoin-core", "" "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"), @@ -42,10 +48,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Distributed under the MIT software license, see the accompanying file " "COPYING or <http://www.opensource.org/licenses/mit-license.php>."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Error: Listening for incoming connections failed (listen returned error %s)"), +"Do not keep transactions in the mempool longer than <n> hours (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Error: Unsupported argument -socks found. Setting SOCKS version isn't " -"possible anymore, only SOCKS5 proxies are supported."), +"Error reading wallet.dat! All keys read correctly, but transaction data or " +"address book entries might be missing or incorrect."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Error: Listening for incoming connections failed (listen returned error %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Execute command when a relevant alert is received or we see a really long " "fork (%s in cmd is replaced by message)"), @@ -56,8 +64,11 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Execute command when the best block changes (%s in cmd is replaced by block " "hash)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Fees (in %s/kB) smaller than this are considered zero fee for relaying " -"(default: %s)"), +"Fees (in %s/kB) smaller than this are considered zero fee for relaying, " +"mining and transaction creation (default: %s)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Fees (in %s/kB) smaller than this are considered zero fee for transaction " +"creation (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "How thorough the block verification of -checkblocks is (0-4, default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -113,6 +124,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Set the number of threads for coin generation if enabled (-1 = all cores, " "default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Support filtering of blocks and transaction with bloom filters (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "The block database contains a block which appears to be from the future. " "This may be due to your computer's date and time being set incorrectly. Only " "rebuild the block database if you are sure that your computer's date and " @@ -127,35 +140,39 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software " "written by Eric Young and UPnP software written by Thomas Bernard."), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Total length of network version string (%i) exceeds maximum length (%i). " +"Reduce the number or size of uacomments."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = " +"no limit (default: %d)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Unable to bind to %s on this computer. Bitcoin Core is probably already " "running."), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Unsupported argument -socks found. Setting SOCKS version isn't possible " +"anymore, only SOCKS5 proxies are supported."), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Use UPnP to map the listening port (default: 1 when listening and no -proxy)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: " "%s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Username and hashed password for JSON-RPC connections. The field <userpw> " +"comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is " +"included in share/rpcuser. This option can be specified multiple times"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "WARNING: abnormally high number of blocks generated, %d blocks received in " "the last %d hours (%d expected)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "WARNING: check your network connection, %d blocks received in the last %d " "hours (%d expected)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Warning: -maxtxfee is set very high! Fees this large could be paid on a " -"single transaction."), -QT_TRANSLATE_NOOP("bitcoin-core", "" -"Warning: -paytxfee is set very high! This is the transaction fee you will " -"pay if you send a transaction."), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Warning: The network does not appear to fully agree! Some miners appear to " "be experiencing issues."), QT_TRANSLATE_NOOP("bitcoin-core", "" "Warning: We do not appear to fully agree with our peers! You may need to " "upgrade, or other nodes may need to upgrade."), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Warning: error reading wallet.dat! All keys read correctly, but transaction " -"data or address book entries might be missing or incorrect."), -QT_TRANSLATE_NOOP("bitcoin-core", "" "Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as " "wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect " "you should restore from a backup."), @@ -170,7 +187,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "mode. This will redownload the entire blockchain"), QT_TRANSLATE_NOOP("bitcoin-core", "(default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "(default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "(default: 1)"), +QT_TRANSLATE_NOOP("bitcoin-core", "-maxmempool must be at least %d MB"), 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)"), @@ -179,14 +196,15 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Activating best chain..."), QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"), QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"), QT_TRANSLATE_NOOP("bitcoin-core", "Always query for peer addresses via DNS lookup (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet.dat"), +QT_TRANSLATE_NOOP("bitcoin-core", "Always relay transactions received from whitelisted peers (default: %d)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet.dat on startup"), +QT_TRANSLATE_NOOP("bitcoin-core", "Automatically create Tor hidden service (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Block creation options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"), QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -whitebind address: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"), -QT_TRANSLATE_NOOP("bitcoin-core", "Choose data directory on startup (default: 0)"), QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node(s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Connect through SOCKS5 proxy"), QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"), @@ -212,13 +230,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error reading from database, shutting down.") QT_TRANSLATE_NOOP("bitcoin-core", "Error"), QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occurred, see debug.log for details"), QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"), -QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unsupported argument -tor found, use -onion."), QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."), QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in %s/kB) to add to transactions you send (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: %u, 0 = all)"), QT_TRANSLATE_NOOP("bitcoin-core", "Importing..."), -QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000??.dat file"), +QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000??.dat file on startup"), QT_TRANSLATE_NOOP("bitcoin-core", "Include IP addresses in debug output (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Incorrect or no genesis block found. Wrong datadir for network?"), QT_TRANSLATE_NOOP("bitcoin-core", "Information"), @@ -233,6 +250,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s' ( QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable transactions in memory (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Keep the transaction memory pool below <n> megabytes (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..."), @@ -258,20 +276,17 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Receive and display P2P network alerts (defau QT_TRANSLATE_NOOP("bitcoin-core", "Reducing -maxconnections from %d to %d, because of system limitations."), QT_TRANSLATE_NOOP("bitcoin-core", "Relay and mine data carrier transactions (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Relay non-P2SH multisig (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions"), +QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions on startup"), QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."), QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"), QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"), QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Set SSL root certificates for payment request (default: -system-)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Set language, for example \"de_DE\" (default: system locale)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set minimum block size in bytes (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Show all debugging options (usage: --help -help-debug)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Show splash screen on startup (default: 1)"), 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: %s)"), @@ -281,22 +296,25 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)"), QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"), QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized"), QT_TRANSLATE_NOOP("bitcoin-core", "The transaction amount is too small to pay the fee"), QT_TRANSLATE_NOOP("bitcoin-core", "This help message"), QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."), QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Tor control port password (default: empty)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Tor control port to use if onion listening enabled (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amount too small"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large for fee policy"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large"), -QT_TRANSLATE_NOOP("bitcoin-core", "UI Options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Unable to start HTTP server. See debug log for details."), QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"), -QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format"), +QT_TRANSLATE_NOOP("bitcoin-core", "Unsupported argument -benchmark ignored, use -debug=bench."), +QT_TRANSLATE_NOOP("bitcoin-core", "Unsupported argument -debugnet ignored, use -debug=net."), +QT_TRANSLATE_NOOP("bitcoin-core", "Unsupported argument -tor found, use -onion."), +QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format on startup"), QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"), +QT_TRANSLATE_NOOP("bitcoin-core", "User Agent comment (%s) contains unsafe characters."), QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"), QT_TRANSLATE_NOOP("bitcoin-core", "Verifying blocks..."), QT_TRANSLATE_NOOP("bitcoin-core", "Verifying wallet..."), @@ -305,11 +323,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart Bitcoi QT_TRANSLATE_NOOP("bitcoin-core", "Wallet options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Warning"), QT_TRANSLATE_NOOP("bitcoin-core", "Warning: This version is obsolete; upgrade required!"), -QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -benchmark ignored, use -debug=bench."), -QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -debugnet ignored, use -debug=net."), +QT_TRANSLATE_NOOP("bitcoin-core", "Whether to operate in a blocks only mode (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "You need to rebuild the database using -reindex to change -txindex"), QT_TRANSLATE_NOOP("bitcoin-core", "Zapping all transactions from wallet..."), QT_TRANSLATE_NOOP("bitcoin-core", "ZeroMQ notification options:"), -QT_TRANSLATE_NOOP("bitcoin-core", "on startup"), QT_TRANSLATE_NOOP("bitcoin-core", "wallet.dat corrupt, salvage failed"), }; diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp index 425b45d918..6490057897 100644 --- a/src/qt/bitcoinunits.cpp +++ b/src/qt/bitcoinunits.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -111,13 +111,6 @@ QString BitcoinUnits::format(int unit, const CAmount& nIn, bool fPlus, Separator } -// TODO: Review all remaining calls to BitcoinUnits::formatWithUnit to -// TODO: determine whether the output is used in a plain text context -// TODO: or an HTML context (and replace with -// TODO: BtcoinUnits::formatHtmlWithUnit in the latter case). Hopefully -// TODO: there aren't instances where the result could be used in -// TODO: either context. - // NOTE: Using formatWithUnit in an HTML context risks wrapping // quantities at the thousands separator. More subtly, it also results // in a standard space rather than a thin space, due to a bug in Qt's diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h index 1871c33a78..fda067b0b8 100644 --- a/src/qt/bitcoinunits.h +++ b/src/qt/bitcoinunits.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -88,6 +88,7 @@ public: static QString format(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); //! Format as string (with unit) static QString formatWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); + //! Format as HTML string (with unit) static QString formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); //! Parse string to coin amount static bool parse(int unit, const QString &value, CAmount *val_out); diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 0900a35cc4..b4ac696393 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -13,6 +13,7 @@ #include "checkpoints.h" #include "clientversion.h" #include "net.h" +#include "txmempool.h" #include "ui_interface.h" #include "util.h" @@ -21,17 +22,16 @@ #include <QDebug> #include <QTimer> +class CBlockIndex; + static const int64_t nClientStartupTime = GetTime(); +static int64_t nLastBlockTipUpdateNotification = 0; ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : QObject(parent), optionsModel(optionsModel), peerTableModel(0), banTableModel(0), - cachedNumBlocks(0), - cachedBlockDate(QDateTime()), - cachedReindexing(0), - cachedImporting(0), pollTimer(0) { peerTableModel = new PeerTableModel(this); @@ -88,40 +88,32 @@ QDateTime ClientModel::getLastBlockDate() const return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network } -double ClientModel::getVerificationProgress() const +long ClientModel::getMempoolSize() const { - LOCK(cs_main); - return Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip()); + return mempool.size(); } -void ClientModel::updateTimer() +size_t ClientModel::getMempoolDynamicUsage() const { - // Get required lock upfront. This avoids the GUI from getting stuck on - // periodical polls if the core is holding the locks for a longer time - - // for example, during a wallet rescan. - TRY_LOCK(cs_main, lockMain); - if (!lockMain) - return; - - // Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change. - // Periodically check and update with a timer. - int newNumBlocks = getNumBlocks(); - QDateTime newBlockDate = getLastBlockDate(); - - // check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state - if (cachedNumBlocks != newNumBlocks || - cachedBlockDate != newBlockDate || - cachedReindexing != fReindex || - cachedImporting != fImporting) - { - cachedNumBlocks = newNumBlocks; - cachedBlockDate = newBlockDate; - cachedReindexing = fReindex; - cachedImporting = fImporting; + return mempool.DynamicMemoryUsage(); +} - Q_EMIT numBlocksChanged(newNumBlocks, newBlockDate); +double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const +{ + CBlockIndex *tip = const_cast<CBlockIndex *>(tipIn); + if (!tip) + { + LOCK(cs_main); + tip = chainActive.Tip(); } + return Checkpoints::GuessVerificationProgress(Params().Checkpoints(), tip); +} +void ClientModel::updateTimer() +{ + // no locking required at this point + // the following calls will aquire the required lock + Q_EMIT mempoolSizeChanged(getMempoolSize(), getMempoolDynamicUsage()); Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent()); } @@ -166,7 +158,7 @@ enum BlockSource ClientModel::getBlockSource() const QString ClientModel::getStatusBarWarnings() const { - return QString::fromStdString(GetWarnings("statusbar")); + return QString::fromStdString(GetWarnings("gui")); } OptionsModel *ClientModel::getOptionsModel() @@ -249,6 +241,26 @@ static void BannedListChanged(ClientModel *clientmodel) QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection); } +static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex) +{ + // lock free async UI updates in case we have a new block tip + // during initial sync, only update the UI if the last update + // was > 250ms (MODEL_UPDATE_DELAY) ago + int64_t now = 0; + if (initialSync) + now = GetTimeMillis(); + + // if we are in-sync, update the UI regardless of last update time + if (!initialSync || now - nLastBlockTipUpdateNotification > MODEL_UPDATE_DELAY) { + //pass a async signal to the UI thread + QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection, + Q_ARG(int, pIndex->nHeight), + Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())), + Q_ARG(double, clientmodel->getVerificationProgress(pIndex))); + nLastBlockTipUpdateNotification = now; + } +} + void ClientModel::subscribeToCoreSignals() { // Connect signals to client @@ -256,6 +268,7 @@ void ClientModel::subscribeToCoreSignals() uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1)); uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2)); uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this)); + uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2)); } void ClientModel::unsubscribeFromCoreSignals() @@ -265,4 +278,5 @@ void ClientModel::unsubscribeFromCoreSignals() uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1)); uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2)); uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this)); + uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2)); } diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 627bdf862d..62c9f71ac7 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,6 +15,7 @@ class PeerTableModel; class TransactionTableModel; class CWallet; +class CBlockIndex; QT_BEGIN_NAMESPACE class QTimer; @@ -51,10 +52,15 @@ public: int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const; int getNumBlocks() const; + //! Return number of transactions in the mempool + long getMempoolSize() const; + //! Return the dynamic memory usage of the mempool + size_t getMempoolDynamicUsage() const; + quint64 getTotalBytesRecv() const; quint64 getTotalBytesSent() const; - double getVerificationProgress() const; + double getVerificationProgress(const CBlockIndex *tip) const; QDateTime getLastBlockDate() const; //! Return true if core is doing initial block download @@ -76,11 +82,6 @@ private: PeerTableModel *peerTableModel; BanTableModel *banTableModel; - int cachedNumBlocks; - QDateTime cachedBlockDate; - bool cachedReindexing; - bool cachedImporting; - QTimer *pollTimer; void subscribeToCoreSignals(); @@ -88,7 +89,8 @@ private: Q_SIGNALS: void numConnectionsChanged(int count); - void numBlocksChanged(int count, const QDateTime& blockDate); + void numBlocksChanged(int count, const QDateTime& blockDate, double nVerificationProgress); + void mempoolSizeChanged(long count, size_t mempoolSizeInBytes); void alertsChanged(const QString &warnings); void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 51008ad2de..a5c2b6d421 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -130,7 +130,7 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget ui->treeWidget->setColumnWidth(COLUMN_DATE, 110); ui->treeWidget->setColumnWidth(COLUMN_CONFIRMATIONS, 100); ui->treeWidget->setColumnWidth(COLUMN_PRIORITY, 100); - ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transacton hash in this column, but don't show it + ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transaction hash in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_VOUT_INDEX, true); // store vout index in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_AMOUNT_INT64, true); // store amount int64 in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_PRIORITY_INT64, true); // store priority int64 in this column, but don't show it @@ -411,7 +411,7 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) // todo: this is a temporary qt5 fix: when clicking a parent node in tree mode, the parent node // including all children are partially selected. But the parent node should be fully selected // as well as the children. Children should never be partially selected in the first place. - // Please remove this ugly fix, once the bug is solved upstream. + // Should be fixed in Qt5.4 and above. https://bugreports.qt.io/browse/QTBUG-43473 #if QT_VERSION >= 0x050000 else if (column == COLUMN_CHECKBOX && item->childCount() > 0) { @@ -538,7 +538,7 @@ 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); + double mempoolEstimatePriority = mempool.estimateSmartPriority(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(dPriority, mempoolEstimatePriority); @@ -549,11 +549,12 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // Fee nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool); + if (nPayFee > 0 && coinControl->nMinimumTotalFee > nPayFee) + nPayFee = coinControl->nMinimumTotalFee; - // Allow free? - double dPriorityNeeded = mempoolEstimatePriority; - if (dPriorityNeeded <= 0) - dPriorityNeeded = AllowFreeThreshold(); // not enough data, back to hard-coded + + // Allow free? (require at least hard-coded threshold and default to that if no estimate) + double dPriorityNeeded = std::max(mempoolEstimatePriority, AllowFreeThreshold()); fAllowFree = (dPriority >= dPriorityNeeded); if (fSendFreeTransactions) @@ -567,7 +568,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) nChange -= nPayFee; // Never create dust outputs; if we would, just add the dust to the fee. - if (nChange > 0 && nChange < CENT) + if (nChange > 0 && nChange < MIN_CHANGE) { CTxOut txout(nChange, (CScript)std::vector<unsigned char>(24, 0)); if (txout.IsDust(::minRelayTxFee)) @@ -621,7 +622,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 && !(payTxFee.GetFeePerK() > 0 && fPayAtLeastCustomFee && nBytes < 1000)) + if (nPayFee > 0 && (coinControl->nMinimumTotalFee < nPayFee)) { l3->setText(ASYMP_UTF8 + l3->text()); l4->setText(ASYMP_UTF8 + l4->text()); @@ -636,21 +637,22 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // tool tips QString toolTip1 = tr("This label turns red if the transaction size is greater than 1000 bytes.") + "<br /><br />"; - toolTip1 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CWallet::minTxFee.GetFeePerK())) + "<br /><br />"; + toolTip1 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, CWallet::GetRequiredFee(1000))) + "<br /><br />"; toolTip1 += tr("Can vary +/- 1 byte per input."); QString toolTip2 = tr("Transactions with higher priority are more likely to get included into a block.") + "<br /><br />"; toolTip2 += tr("This label turns red if the priority is smaller than \"medium\".") + "<br /><br />"; - toolTip2 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CWallet::minTxFee.GetFeePerK())); + toolTip2 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, CWallet::GetRequiredFee(1000))); - QString toolTip3 = tr("This label turns red if any recipient receives an amount smaller than %1.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, ::minRelayTxFee.GetFee(546))); + QString toolTip3 = tr("This label turns red if any recipient receives an amount smaller than the current dust threshold."); // how many satoshis the estimated fee can vary per byte we guess wrong 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; + dFeeVary = (double)std::max(CWallet::GetRequiredFee(1000), payTxFee.GetFeePerK()) / 1000; + else { + dFeeVary = (double)std::max(CWallet::GetRequiredFee(1000), mempool.estimateSmartFee(nTxConfirmTarget).GetFeePerK()) / 1000; + } QString toolTip4 = tr("Can vary +/- %1 satoshi(s) per input.").arg(dFeeVary); l3->setToolTip(toolTip4); @@ -686,7 +688,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); + double mempoolEstimatePriority = mempool.estimateSmartPriority(nTxConfirmTarget); std::map<QString, std::vector<COutput> > mapCoins; model->listCoins(mapCoins); diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 8ff1eac709..1a467eb2ff 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/coincontroltreewidget.cpp b/src/qt/coincontroltreewidget.cpp index 5dcbf0c3f1..f86bc0851f 100644 --- a/src/qt/coincontroltreewidget.cpp +++ b/src/qt/coincontroltreewidget.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h index d59fce2d41..ddb67ece72 100644 --- a/src/qt/editaddressdialog.h +++ b/src/qt/editaddressdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index 4117da57f5..2471470363 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -23,7 +23,7 @@ <attribute name="title"> <string>&Information</string> </attribute> - <layout class="QGridLayout" name="gridLayout" columnstretch="0,1"> + <layout class="QGridLayout" name="gridLayout" columnstretch="0,1,0"> <property name="horizontalSpacing"> <number>12</number> </property> @@ -47,7 +47,7 @@ </property> </widget> </item> - <item row="1" column="1"> + <item row="1" column="1" colspan="2"> <widget class="QLabel" name="clientName"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -70,7 +70,7 @@ </property> </widget> </item> - <item row="2" column="1"> + <item row="2" column="1" colspan="2"> <widget class="QLabel" name="clientVersion"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -96,7 +96,7 @@ </property> </widget> </item> - <item row="3" column="1"> + <item row="3" column="1" colspan="2"> <widget class="QLabel" name="clientUserAgent"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -122,7 +122,7 @@ </property> </widget> </item> - <item row="4" column="1"> + <item row="4" column="1" colspan="2"> <widget class="QLabel" name="openSSLVersion"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -148,7 +148,7 @@ </property> </widget> </item> - <item row="5" column="1"> + <item row="5" column="1" colspan="2"> <widget class="QLabel" name="berkeleyDBVersion"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -171,7 +171,7 @@ </property> </widget> </item> - <item row="6" column="1"> + <item row="6" column="1" colspan="2"> <widget class="QLabel" name="buildDate"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -194,7 +194,7 @@ </property> </widget> </item> - <item row="7" column="1"> + <item row="7" column="1" colspan="2"> <widget class="QLabel" name="startupTime"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -210,19 +210,6 @@ </property> </widget> </item> - <item row="8" column="0"> - <widget class="QLabel" name="label_11"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="text"> - <string>Network</string> - </property> - </widget> - </item> <item row="9" column="0"> <widget class="QLabel" name="label_8"> <property name="text"> @@ -230,7 +217,7 @@ </property> </widget> </item> - <item row="9" column="1"> + <item row="9" column="1" colspan="2"> <widget class="QLabel" name="networkName"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -253,7 +240,7 @@ </property> </widget> </item> - <item row="10" column="1"> + <item row="10" column="1" colspan="2"> <widget class="QLabel" name="numberOfConnections"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -289,7 +276,7 @@ </property> </widget> </item> - <item row="12" column="1"> + <item row="12" column="1" colspan="2"> <widget class="QLabel" name="numberOfBlocks"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -306,13 +293,13 @@ </widget> </item> <item row="13" column="0"> - <widget class="QLabel" name="label_2"> + <widget class="QLabel" name="labelLastBlockTime"> <property name="text"> <string>Last block time</string> </property> </widget> </item> - <item row="13" column="1"> + <item row="13" column="1" colspan="2"> <widget class="QLabel" name="lastBlockTime"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -329,20 +316,43 @@ </widget> </item> <item row="14" column="0"> - <spacer name="verticalSpacer_2"> - <property name="orientation"> - <enum>Qt::Vertical</enum> + <widget class="QLabel" name="labelMempoolTitle"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>20</height> - </size> + <property name="text"> + <string>Memory Pool</string> </property> - </spacer> + </widget> </item> <item row="15" column="0"> - <widget class="QLabel" name="labelDebugLogfile"> + <widget class="QLabel" name="labelNumberOfTransactions"> + <property name="text"> + <string>Current number of transactions</string> + </property> + </widget> + </item> + <item row="15" column="1"> + <widget class="QLabel" name="mempoolNumberTxs"> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="text"> + <string>N/A</string> + </property> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="8" column="0"> + <widget class="QLabel" name="labelNetwork"> <property name="font"> <font> <weight>75</weight> @@ -350,24 +360,74 @@ </font> </property> <property name="text"> - <string>Debug log file</string> + <string>Network</string> </property> </widget> </item> <item row="16" column="0"> - <widget class="QPushButton" name="openDebugLogfileButton"> - <property name="toolTip"> - <string>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</string> + <widget class="QLabel" name="labelMemoryUsage"> + <property name="text"> + <string>Memory usage</string> + </property> + </widget> + </item> + <item row="16" column="1"> + <widget class="QLabel" name="mempoolSize"> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> </property> <property name="text"> - <string>&Open</string> + <string>N/A</string> </property> - <property name="autoDefault"> - <bool>false</bool> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> </property> </widget> </item> - <item row="17" column="0"> + <item row="14" column="2" rowspan="3"> + <layout class="QVBoxLayout" name="verticalLayoutDebugButton"> + <property name="spacing"> + <number>3</number> + </property> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="labelDebugLogfile"> + <property name="text"> + <string>Debug log file</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="openDebugLogfileButton"> + <property name="toolTip"> + <string>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</string> + </property> + <property name="text"> + <string>&Open</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </item> + <item row="18" column="0"> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -1117,7 +1177,7 @@ <item row="12" column="0"> <widget class="QLabel" name="label_18"> <property name="text"> - <string>Bytes Sent</string> + <string>Sent</string> </property> </widget> </item> @@ -1140,7 +1200,7 @@ <item row="13" column="0"> <widget class="QLabel" name="label_20"> <property name="text"> - <string>Bytes Received</string> + <string>Received</string> </property> </widget> </item> diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 7d3e48ff32..5ceffcd70a 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -14,6 +14,8 @@ static const int MAX_PASSPHRASE_SIZE = 1024; /* BitcoinGUI -- Size of icons in status bar */ static const int STATUSBAR_ICONSIZE = 16; +static const bool DEFAULT_SPLASHSCREEN = true; + /* Invalid field background style */ #define STYLE_INVALID "background:#FF8080" diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 8917f77f22..ff4320b36a 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -62,6 +62,10 @@ #include <QUrlQuery> #endif +#if QT_VERSION >= 0x50200 +#include <QFontDatabase> +#endif + #if BOOST_FILESYSTEM_VERSION >= 3 static boost::filesystem::detail::utf8_codecvt_facet utf8; #endif @@ -88,8 +92,11 @@ QString dateTimeStr(qint64 nTime) return dateTimeStr(QDateTime::fromTime_t((qint32)nTime)); } -QFont bitcoinAddressFont() +QFont fixedPitchFont() { +#if QT_VERSION >= 0x50200 + return QFontDatabase::systemFont(QFontDatabase::FixedFont); +#else QFont font("Monospace"); #if QT_VERSION >= 0x040800 font.setStyleHint(QFont::Monospace); @@ -97,13 +104,14 @@ QFont bitcoinAddressFont() font.setStyleHint(QFont::TypeWriter); #endif return font; +#endif } void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) { parent->setFocusProxy(widget); - widget->setFont(bitcoinAddressFont()); + widget->setFont(fixedPitchFont()); #if QT_VERSION >= 0x040700 // We don't want translators to use own addresses in translations // and this is the only place, where this address is supplied. @@ -217,7 +225,7 @@ QString formatBitcoinURI(const SendCoinsRecipient &info) if (!info.message.isEmpty()) { - QString msg(QUrl::toPercentEncoding(info.message));; + QString msg(QUrl::toPercentEncoding(info.message)); ret += QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg); paramCount++; } @@ -581,12 +589,12 @@ TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* t #ifdef WIN32 boost::filesystem::path static StartupShortcutPath() { - if (GetBoolArg("-testnet", false)) + std::string chain = ChainNameFromCommandLine(); + if (chain == CBaseChainParams::MAIN) + return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk"; + if (chain == CBaseChainParams::TESTNET) // Remove this special case when CBaseChainParams::TESTNET = "testnet4" return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (testnet).lnk"; - else if (GetBoolArg("-regtest", false)) - return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (regtest).lnk"; - - return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk"; + return GetSpecialFolderPath(CSIDL_STARTUP) / strprintf("Bitcoin (%s).lnk", chain); } bool GetStartOnSystemStartup() @@ -681,7 +689,10 @@ boost::filesystem::path static GetAutostartDir() boost::filesystem::path static GetAutostartFilePath() { - return GetAutostartDir() / "bitcoin.desktop"; + std::string chain = ChainNameFromCommandLine(); + if (chain == CBaseChainParams::MAIN) + return GetAutostartDir() / "bitcoin.desktop"; + return GetAutostartDir() / strprintf("bitcoin-%s.lnk", chain); } bool GetStartOnSystemStartup() @@ -719,15 +730,14 @@ bool SetStartOnSystemStartup(bool fAutoStart) boost::filesystem::ofstream optionFile(GetAutostartFilePath(), std::ios_base::out|std::ios_base::trunc); if (!optionFile.good()) return false; + std::string chain = ChainNameFromCommandLine(); // Write a bitcoin.desktop file to the autostart directory: optionFile << "[Desktop Entry]\n"; optionFile << "Type=Application\n"; - if (GetBoolArg("-testnet", false)) - optionFile << "Name=Bitcoin (testnet)\n"; - else if (GetBoolArg("-regtest", false)) - optionFile << "Name=Bitcoin (regtest)\n"; - else + if (chain == CBaseChainParams::MAIN) optionFile << "Name=Bitcoin\n"; + else + optionFile << strprintf("Name=Bitcoin (%s)\n", chain); optionFile << "Exec=" << pszExePath << strprintf(" -min -testnet=%d -regtest=%d\n", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false)); optionFile << "Terminal=false\n"; optionFile << "Hidden=false\n"; @@ -896,6 +906,9 @@ QString formatServicesStr(quint64 mask) case NODE_GETUTXO: strList.append("GETUTXO"); break; + case NODE_BLOOM: + strList.append("BLOOM"); + break; default: strList.append(QString("%1[%2]").arg("UNKNOWN").arg(check)); } diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 0ac3db6327..9267e0a6c9 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -37,8 +37,8 @@ namespace GUIUtil QString dateTimeStr(const QDateTime &datetime); QString dateTimeStr(qint64 nTime); - // Render Bitcoin addresses in monospace font - QFont bitcoinAddressFont(); + // Return a monospace font + QFont fixedPitchFont(); // Set up widgets for address and amounts void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent); diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 4ab87e0f32..f324c6dc5a 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,9 +15,15 @@ #include <QSettings> #include <QMessageBox> -/* Minimum free space (in bytes) needed for data directory */ +#include <cmath> + static const uint64_t GB_BYTES = 1000000000LL; -static const uint64_t BLOCK_CHAIN_SIZE = 20LL * GB_BYTES; +/* Minimum free space (in GB) needed for data directory */ +static const uint64_t BLOCK_CHAIN_SIZE = 80; +/* Minimum free space (in GB) needed for data directory when pruned; Does not include prune target */ +static const uint64_t CHAIN_STATE_SIZE = 2; +/* Total required space (in GB) depending on user choice (prune, not prune) */ +static uint64_t requiredSpace; /* Check free space asynchronously to prevent hanging the UI thread. @@ -112,7 +118,11 @@ Intro::Intro(QWidget *parent) : signalled(false) { ui->setupUi(this); - ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(BLOCK_CHAIN_SIZE/GB_BYTES)); + uint64_t pruneTarget = std::max<int64_t>(0, GetArg("-prune", 0)); + requiredSpace = BLOCK_CHAIN_SIZE; + if (pruneTarget) + requiredSpace = CHAIN_STATE_SIZE + std::ceil(pruneTarget * 1024 * 1024.0 / GB_BYTES); + ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(requiredSpace)); startThread(); } @@ -162,7 +172,7 @@ void Intro::pickDataDirectory() /* 2) Allow QSettings to override default dir */ dataDir = settings.value("strDataDir", dataDir).toString(); - if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", false)) + if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR)) { /* If current default data directory does not exist, let the user choose one */ Intro intro; @@ -216,9 +226,9 @@ void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable ui->freeSpace->setText(""); } else { QString freeString = tr("%n GB of free space available", "", bytesAvailable/GB_BYTES); - if(bytesAvailable < BLOCK_CHAIN_SIZE) + if(bytesAvailable < requiredSpace * GB_BYTES) { - freeString += " " + tr("(of %n GB needed)", "", BLOCK_CHAIN_SIZE/GB_BYTES); + freeString += " " + tr("(of %n GB needed)", "", requiredSpace); ui->freeSpace->setStyleSheet("QLabel { color: #800000 }"); } else { ui->freeSpace->setStyleSheet(""); diff --git a/src/qt/intro.h b/src/qt/intro.h index 50783f7225..9e2e96dc9e 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,6 +9,8 @@ #include <QMutex> #include <QThread> +static const bool DEFAULT_CHOOSE_DATADIR = false; + class FreespaceChecker; namespace Ui { diff --git a/src/qt/locale/bitcoin_ach.ts b/src/qt/locale/bitcoin_ach.ts deleted file mode 100644 index ddb9fb85ce..0000000000 --- a/src/qt/locale/bitcoin_ach.ts +++ /dev/null @@ -1,110 +0,0 @@ -<TS language="ach" version="2.0"> -<context> - <name>AddressBookPage</name> - </context> -<context> - <name>AddressTableModel</name> - </context> -<context> - <name>AskPassphraseDialog</name> - </context> -<context> - <name>BitcoinGUI</name> - </context> -<context> - <name>ClientModel</name> - </context> -<context> - <name>CoinControlDialog</name> - </context> -<context> - <name>EditAddressDialog</name> - </context> -<context> - <name>FreespaceChecker</name> - </context> -<context> - <name>HelpMessageDialog</name> - </context> -<context> - <name>Intro</name> - </context> -<context> - <name>OpenURIDialog</name> - </context> -<context> - <name>OptionsDialog</name> - </context> -<context> - <name>OverviewPage</name> - </context> -<context> - <name>PaymentServer</name> - </context> -<context> - <name>PeerTableModel</name> - </context> -<context> - <name>QObject</name> - </context> -<context> - <name>QRImageWidget</name> - </context> -<context> - <name>RPCConsole</name> - </context> -<context> - <name>ReceiveCoinsDialog</name> - </context> -<context> - <name>ReceiveRequestDialog</name> - </context> -<context> - <name>RecentRequestsTableModel</name> - </context> -<context> - <name>SendCoinsDialog</name> - </context> -<context> - <name>SendCoinsEntry</name> - </context> -<context> - <name>ShutdownWindow</name> - </context> -<context> - <name>SignVerifyMessageDialog</name> - </context> -<context> - <name>SplashScreen</name> - </context> -<context> - <name>TrafficGraphWidget</name> - </context> -<context> - <name>TransactionDesc</name> - </context> -<context> - <name>TransactionDescDialog</name> - </context> -<context> - <name>TransactionTableModel</name> - </context> -<context> - <name>TransactionView</name> - </context> -<context> - <name>UnitDisplayStatusBarControl</name> - </context> -<context> - <name>WalletFrame</name> - </context> -<context> - <name>WalletModel</name> - </context> -<context> - <name>WalletView</name> - </context> -<context> - <name>bitcoin-core</name> - </context> -</TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_af_ZA.ts b/src/qt/locale/bitcoin_af_ZA.ts index 3767a4c830..d77aa77f8e 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.0"> +<TS language="af_ZA" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -101,6 +101,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Synchronizing with network...</source> @@ -212,6 +215,14 @@ <context> <name>EditAddressDialog</name> <message> + <source>&Label</source> + <translation>&Etiket</translation> + </message> + <message> + <source>&Address</source> + <translation>&Adres</translation> + </message> + <message> <source>New receiving address</source> <translation>Nuwe ontvangende adres</translation> </message> @@ -258,6 +269,10 @@ <source>Options</source> <translation>Opsies</translation> </message> + <message> + <source>W&allet</source> + <translation>&Beursie</translation> + </message> </context> <context> <name>OverviewPage</name> @@ -292,6 +307,14 @@ <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>&Bedrag:</translation> + </message> + <message> + <source>&Message:</source> + <translation>&Boodskap:</translation> + </message> + <message> <source>Copy amount</source> <translation>Kopieer bedrag</translation> </message> @@ -345,10 +368,18 @@ <translation>Stuur Munstukke</translation> </message> <message> + <source>Insufficient funds!</source> + <translation>Onvoldoende fondse</translation> + </message> + <message> <source>Amount:</source> <translation>Bedrag:</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Transaksie fooi:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Stuur aan vele ontvangers op eens</translation> </message> @@ -372,6 +403,10 @@ <context> <name>SendCoinsEntry</name> <message> + <source>A&mount:</source> + <translation>&Bedrag:</translation> + </message> + <message> <source>Message:</source> <translation>Boodskap:</translation> </message> @@ -451,6 +486,10 @@ <translation>Transaksie ID</translation> </message> <message> + <source>Transaction</source> + <translation>Transaksie</translation> + </message> + <message> <source>Amount</source> <translation>Bedrag</translation> </message> @@ -631,10 +670,6 @@ <translation>Opsies:</translation> </message> <message> - <source>Use the test network</source> - <translation>Gebruik die toets netwerk</translation> - </message> - <message> <source>Error: Disk space is low!</source> <translation>Fout: Hardeskyf spasie is baie laag!</translation> </message> diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index e56083fa2c..88ce05bbd5 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -1,4 +1,4 @@ -<TS language="ar" version="2.0"> +<TS language="ar" version="2.1"> <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> @@ -164,6 +168,10 @@ <translation>هل أنت متأكد من رغبتك في تشفير محفظتك ؟</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>بتكوين سوف يغلق الآن لإنهاء عملية التشفير. تذكر أن التشفير لا يستطيع حماية محفظتك تمامًا من السرقة من خلال البرمجيات الخبيثة التي تصيب جهازك </translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> <translation>هام: أي نسخة إحتياطية سابقة قمت بها لمحفظتك يجب استبدالها بأخرى حديثة، مشفرة. لأسباب أمنية، النسخ الاحتياطية السابقة لملفات المحفظة الغير مشفرة تصبح عديمة الفائدة مع بداية استخدام المحفظة المشفرة الجديدة.</translation> </message> @@ -180,6 +188,10 @@ <translation>أدخل عبارة مرور جديدة إلى المحفظة. الرجاء استخدام عبارة مرور تتكون من10 حروف عشوائية على الاقل, أو أكثر من 7 كلمات</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>أدخل كلمة المرور القديمة والجديدة للمحفظة.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>فشل تشفير المحفظة</translation> </message> @@ -209,6 +221,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -323,6 +338,10 @@ <translation>محفظة</translation> </message> <message> + <source>&Send</source> + <translation>&ارسل</translation> + </message> + <message> <source>&Receive</source> <translation>&استقبل</translation> </message> @@ -367,6 +386,10 @@ <translation>حول bitcoin core</translation> </message> <message> + <source>%1 and %2</source> + <translation>%1 و %2</translation> + </message> + <message> <source>Error</source> <translation>خطأ</translation> </message> @@ -768,6 +791,10 @@ </context> <context> <name>PaymentServer</name> + <message> + <source>Bad response from server %1</source> + <translation>استجابة سيئة من الملقم %1</translation> + </message> </context> <context> <name>PeerTableModel</name> @@ -779,6 +806,14 @@ <translation>المبلغ</translation> </message> <message> + <source>%1 h</source> + <translation>%1 ساعة</translation> + </message> + <message> + <source>%1 m</source> + <translation>%1 دقيقة</translation> + </message> + <message> <source>N/A</source> <translation>غير معروف</translation> </message> @@ -821,6 +856,10 @@ <translation>المعلومات</translation> </message> <message> + <source>Debug window</source> + <translation>نافذة المعالجة</translation> + </message> + <message> <source>General</source> <translation>عام</translation> </message> @@ -897,12 +936,32 @@ <translation>استخدم اسهم الاعلى و الاسفل للتنقل بين السجلات و <b>Ctrl-L</b> لمسح الشاشة</translation> </message> <message> - <source>Unknown</source> - <translation>غير معرف</translation> + <source>%1 B</source> + <translation>%1 بايت</translation> + </message> + <message> + <source>%1 KB</source> + <translation>%1 كيلو بايت</translation> </message> <message> - <source>Fetching...</source> - <translation>جاري الجلب...</translation> + <source>%1 MB</source> + <translation>%1 ميقا بايت</translation> + </message> + <message> + <source>%1 GB</source> + <translation>%1 قيقا بايت</translation> + </message> + <message> + <source>Yes</source> + <translation>نعم</translation> + </message> + <message> + <source>No</source> + <translation>لا</translation> + </message> + <message> + <source>Unknown</source> + <translation>غير معرف</translation> </message> </context> <context> @@ -1061,6 +1120,10 @@ <translation>تعديل :</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>رسوم المعاملة:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>إرسال إلى عدة مستلمين في وقت واحد</translation> </message> @@ -1093,6 +1156,10 @@ <translation>تأكيد الإرسال Coins</translation> </message> <message> + <source>%1 to %2</source> + <translation>%1 الى %2</translation> + </message> + <message> <source>Copy quantity</source> <translation>نسخ الكمية </translation> </message> @@ -1117,10 +1184,6 @@ <translation>نسخ التعديل</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>مجموع المبلغ %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>أو</translation> </message> @@ -1133,6 +1196,10 @@ <translation>القيمة تتجاوز رصيدك</translation> </message> <message> + <source>The total exceeds your balance when the %1 transaction fee is included.</source> + <translation>المجموع يتجاوز رصيدك عندما يتم اضافة %1 رسوم العملية</translation> + </message> + <message> <source>(no label)</source> <translation>(لا وصف)</translation> </message> @@ -1140,6 +1207,10 @@ <context> <name>SendCoinsEntry</name> <message> + <source>A&mount:</source> + <translation>&القيمة</translation> + </message> + <message> <source>Pay &To:</source> <translation>ادفع &الى :</translation> </message> @@ -1167,6 +1238,10 @@ <source>Message:</source> <translation>الرسائل</translation> </message> + <message> + <source>Pay To:</source> + <translation>ادفع &الى :</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -1287,10 +1362,22 @@ <context> <name>TransactionDesc</name> <message> + <source>Open until %1</source> + <translation>مفتوح حتى %1</translation> + </message> + <message> <source>conflicted</source> <translation>يتعارض</translation> </message> <message> + <source>%1/offline</source> + <translation>%1 غير متواجد</translation> + </message> + <message> + <source>%1/unconfirmed</source> + <translation>غير مؤكدة/%1</translation> + </message> + <message> <source>%1 confirmations</source> <translation>تأكيد %1</translation> </message> @@ -1401,6 +1488,10 @@ <translation>النوع</translation> </message> <message> + <source>Open until %1</source> + <translation>مفتوح حتى %1</translation> + </message> + <message> <source>This block was not received by any other nodes and will probably not be accepted!</source> <translation>لم يتم تلقى هذه الكتلة (Block) من قبل أي العقد الأخرى وربما لن تكون مقبولة!</translation> </message> @@ -1417,6 +1508,10 @@ <translation>وصف</translation> </message> <message> + <source>Conflicted</source> + <translation>يتعارض</translation> + </message> + <message> <source>Received with</source> <translation>استقبل مع</translation> </message> @@ -1631,10 +1726,6 @@ <translation>حدد مجلد المعلومات</translation> </message> <message> - <source>Use the test network</source> - <translation>استخدم التحقق من الشبكه</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>قبول الاتصالات من خارج</translation> </message> @@ -1683,10 +1774,6 @@ <translation>تحذير</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>تحديث المحفظة للنسخة الاخيرة</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 5f7f6f89bf..2709ff37e5 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.0"> +<TS language="be_BY" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -795,7 +798,7 @@ <source>command-line options</source> <translation>опцыі каманднага радка</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -840,6 +843,10 @@ <source>MB</source> <translation>Мб</translation> </message> + <message> + <source>W&allet</source> + <translation>Гаманец</translation> + </message> </context> <context> <name>OverviewPage</name> @@ -866,10 +873,22 @@ </context> <context> <name>RPCConsole</name> + <message> + <source>&Information</source> + <translation>Інфармацыя</translation> + </message> + <message> + <source>Debug window</source> + <translation>Вакно адладкі</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>&Колькасць:</translation> + </message> + <message> <source>&Label:</source> <translation>Метка:</translation> </message> @@ -885,6 +904,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>Капіяваць адрас</translation> + </message> + <message> <source>Address</source> <translation>Адрас</translation> </message> @@ -931,6 +954,10 @@ <translation>Даслаць Манеты</translation> </message> <message> + <source>Insufficient funds!</source> + <translation>Недастаткова сродкаў</translation> + </message> + <message> <source>Quantity:</source> <translation>Колькасць:</translation> </message> @@ -1042,6 +1069,14 @@ <translation>Alt+P</translation> </message> <message> + <source>Message:</source> + <translation>Паведамленне:</translation> + </message> + <message> + <source>Pay To:</source> + <translation>Заплаціць да:</translation> + </message> + <message> <source>Memo:</source> <translation>Памятка:</translation> </message> @@ -1373,10 +1408,6 @@ <translation>Запусціць у фоне як дэман і прымаць каманды</translation> </message> <message> - <source>Use the test network</source> - <translation>Ужываць тэставае сеціва</translation> - </message> - <message> <source>Do you want to rebuild the block database now?</source> <translation>Ці жадаеце вы перабудаваць зараз базу звестак блокаў?</translation> </message> @@ -1397,10 +1428,6 @@ <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> @@ -1429,10 +1456,6 @@ <translation>Опцыі гаманца:</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Імпартаванне блокаў з вонкавага blk000??.dat файла</translation> - </message> - <message> <source>Activating best chain...</source> <translation>Актывацыя лепшага ланцуга...</translation> </message> @@ -1453,10 +1476,6 @@ <translation>Памылка подпісу транзакцыі</translation> </message> <message> - <source>Start minimized</source> - <translation>Стартаваць ммінімізаванай</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Гэта эксперыментальная праграма.</translation> </message> @@ -1485,18 +1504,6 @@ <translation>Выканаць каманду калі лепшы блок зменіцца (%s замяняецца на хэш блока)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Абнавіць гаманец на новы фармат</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Перасканаваць ланцуг блокаў дзеля пошуку адсутных транзакцый</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Ужываць OpenSSL (https) для JSON-RPC злучэнняў</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 e2821dbdef..ecd10e5461 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -1,4 +1,4 @@ -<TS language="bg" version="2.0"> +<TS language="bg" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -168,6 +168,10 @@ <translation>Наистина ли желаете да шифрирате портфейла си?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Биткоин сега ще се затоври за да завърши процеса на криптиране. Запомнете, че криптирането на вашия портефейл не може напълно да предпази вашите монети от кражба чрез зловреден софтуер, инфектирал вашия компютър</translation> + </message> + <message> <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> <translation>ВАЖНО: Всички стари запазвания, които сте направили на Вашият портфейл трябва да замените с запазване на новополучения, шифриран портфейл. От съображения за сигурност, предишните запазвания на нешифрирани портфейли ще станат неизползваеми веднага, щом започнете да използвате новият, шифриран портфейл.</translation> </message> @@ -209,6 +213,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -411,6 +418,10 @@ <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> @@ -435,6 +446,36 @@ <translation>Зарежда блокове...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Дата: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Сума: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Тип: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Етикет: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Адрес: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Изходяща транзакция</translation> </message> @@ -633,6 +674,10 @@ <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>yes</source> <translation>да</translation> </message> @@ -761,7 +806,7 @@ <source>command-line options</source> <translation>Списък с налични команди</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -819,6 +864,10 @@ <translation>Мегабайта</translation> </message> <message> + <source>Number of script &verification threads</source> + <translation>Брой на скриптове и &нишки за потвърждение</translation> + </message> + <message> <source>Accept connections from outside</source> <translation>Приемай връзки отвън</translation> </message> @@ -847,6 +896,10 @@ <translation>&Мрежа</translation> </message> <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Автоматично стартиране на Bitcoin Core след влизане в системата.</translation> + </message> + <message> <source>W&allet</source> <translation>По&ртфейл</translation> </message> @@ -855,6 +908,10 @@ <translation>Експерт</translation> </message> <message> + <source>Enable coin &control features</source> + <translation>Позволяване на монетите и &техните възможности</translation> + </message> + <message> <source>&Spend unconfirmed change</source> <translation>&Похарчете непотвърденото ресто</translation> </message> @@ -1045,12 +1102,20 @@ <translation>Файл за справяне със заявки</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Заявката за плащане е изтекла.</translation> + </message> + <message> + <source>Invalid payment request.</source> + <translation>Невалидна заявка за плащане.</translation> + </message> + <message> <source>Refund from %1</source> <translation>Възстановяване на сума от %1</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Дос защита на заявката за плащане</translation> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>Заявката за плащане %1 е твърде голям (%2 байта, позволени %3 байта).</translation> </message> <message> <source>Error communicating with %1: %2</source> @@ -1225,10 +1290,6 @@ <translation>Услуги</translation> </message> <message> - <source>Starting Height</source> - <translation>Стартова височина</translation> - </message> - <message> <source>Connection Time</source> <translation>Продължителност на връзката</translation> </message> @@ -1241,14 +1302,6 @@ <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> @@ -1337,12 +1390,16 @@ <translation>Изходящи</translation> </message> <message> - <source>Unknown</source> - <translation>Неизвестен</translation> + <source>Yes</source> + <translation>Да</translation> </message> <message> - <source>Fetching...</source> - <translation>Прихващане...</translation> + <source>No</source> + <translation>Не</translation> + </message> + <message> + <source>Unknown</source> + <translation>Неизвестен</translation> </message> </context> <context> @@ -1545,6 +1602,10 @@ <translation>за килобайт</translation> </message> <message> + <source>Hide</source> + <translation>Скрий</translation> + </message> + <message> <source>total at least</source> <translation>Крайна сума поне</translation> </message> @@ -1633,10 +1694,6 @@ <translation>Копирай рестото</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Пълна сума %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>или</translation> </message> @@ -1657,8 +1714,8 @@ <translation>Грешка при създаването на транзакция!</translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Платете минималната такса от %1</translation> + <source>Payment request expired.</source> + <translation>Заявката за плащане е изтекла.</translation> </message> <message> <source>Warning: Invalid Bitcoin address</source> @@ -1939,6 +1996,10 @@ <translation>собствен адрес</translation> </message> <message> + <source>watch-only</source> + <translation>само гледане</translation> + </message> + <message> <source>label</source> <translation>име</translation> </message> @@ -2101,6 +2162,10 @@ <translation>Емитирани</translation> </message> <message> + <source>watch-only</source> + <translation>само гледане</translation> + </message> + <message> <source>(n/a)</source> <translation>(n/a)</translation> </message> @@ -2208,6 +2273,10 @@ <translation>Изнасяне историята на транзакциите</translation> </message> <message> + <source>Watch-only</source> + <translation>само гледане</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Грешка при изнасянето</translation> </message> @@ -2327,26 +2396,14 @@ <translation>Въведете Ваш публичен адрес</translation> </message> <message> - <source>Use the test network</source> - <translation>Използвайте тестовата мрежа</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Приемайте връзки отвън.(по подразбиране:1 в противен случай -proxy или -connect)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Внимание: -paytxfee е с мното голяма зададена стойност! Това е транзакционната такса, която ще платите ако направите транзакция.</translation> - </message> - <message> <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> <translation>Сложете в бял списък пиъри,свързващи се от дадената интернет маска или айпи адрес.Може да бъде заложено неколкократно.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(по подразбиране 1)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> може да бъде:</translation> </message> @@ -2391,14 +2448,6 @@ <translation>Заложете броя на нишки за генерация на монети ако е включено(-1 = всички ядра, по подразбиране: %d)</translation> </message> <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Внимание: -maxtxfee има много висока стойност! Толкова високи такси могат да бъдат заплатени на една транзакция.</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Изберете директория при стартиране на програмата.( настройка по подразбиране:0)</translation> - </message> - <message> <source>Connect through SOCKS5 proxy</source> <translation>Свързване чрез SOCKS5 прокси</translation> </message> @@ -2411,6 +2460,10 @@ <translation>Информация</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Невалидна сума за -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Невалидна сума за -minrelaytxfee=<amount>: '%s'</translation> </message> @@ -2423,14 +2476,6 @@ <translation>Изпрати локализиращата или дебъг информацията към конзолата, вместо файлът debug.log</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Задаване на език,например "de_DE" (по подразбиране: system locale)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Стартирай минимизирано</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Това е експериментален софтуер.</translation> </message> @@ -2455,26 +2500,10 @@ <translation>Предупреждение</translation> </message> <message> - <source>on startup</source> - <translation>по време на стартирането</translation> - </message> - <message> <source>Password for JSON-RPC connections</source> <translation>Парола за JSON-RPC връзките</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Обновяване на портфейла до най-новия формат</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Повторно сканиране на блок-връзка за липсващи портфейлни транзакции</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Използвайте OpenSSL (https) за JSON-RPC връзките</translation> - </message> - <message> <source>This help message</source> <translation>Това помощно съобщение</translation> </message> diff --git a/src/qt/locale/bitcoin_cmn.ts b/src/qt/locale/bitcoin_bg_BG.ts index 37c937b864..353f6d7715 100644 --- a/src/qt/locale/bitcoin_cmn.ts +++ b/src/qt/locale/bitcoin_bg_BG.ts @@ -1,9 +1,25 @@ -<TS language="cmn" version="2.0"> +<TS language="bg_BG" version="2.1"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Клик с десен бутон на мишката за промяна на адрес или етикет</translation> + </message> + <message> <source>Create a new address</source> - <translation>创建新地址</translation> + <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> </context> <context> @@ -13,7 +29,18 @@ <name>AskPassphraseDialog</name> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> + <message> + <source>Bitcoin Core</source> + <translation>Биткойн ядро</translation> + </message> + <message> + <source>&About Bitcoin Core</source> + <translation>За Биткойн ядрото</translation> + </message> </context> <context> <name>ClientModel</name> @@ -29,9 +56,21 @@ </context> <context> <name>HelpMessageDialog</name> + <message> + <source>Bitcoin Core</source> + <translation>Биткойн ядро</translation> + </message> + <message> + <source>About Bitcoin Core</source> + <translation>За Биткойн ядрото</translation> + </message> </context> <context> <name>Intro</name> + <message> + <source>Bitcoin Core</source> + <translation>Биткойн ядро</translation> + </message> </context> <context> <name>OpenURIDialog</name> @@ -80,6 +119,10 @@ </context> <context> <name>SplashScreen</name> + <message> + <source>Bitcoin Core</source> + <translation>Биткойн ядро</translation> + </message> </context> <context> <name>TrafficGraphWidget</name> diff --git a/src/qt/locale/bitcoin_bs.ts b/src/qt/locale/bitcoin_bs.ts index 86526022fe..a186842201 100644 --- a/src/qt/locale/bitcoin_bs.ts +++ b/src/qt/locale/bitcoin_bs.ts @@ -1,4 +1,4 @@ -<TS language="bs" version="2.0"> +<TS language="bs" version="2.1"> <context> <name>AddressBookPage</name> </context> @@ -9,6 +9,9 @@ <name>AskPassphraseDialog</name> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Bitcoin</source> diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index ceb71469cb..38e770f182 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -1,4 +1,4 @@ -<TS language="ca" version="2.0"> +<TS language="ca" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP / Màscara de xarxa</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Bandejat fins</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -871,6 +882,34 @@ <source>command-line options</source> <translation>Opcions de la línia d'ordres</translation> </message> + <message> + <source>UI Options:</source> + <translation>Opcions d'interfície d'usuari:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Trieu el directori de dades a l'inici (per defecte: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Defineix la llengua, per exemple «de_DE» (per defecte: la definida pel sistema)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Inicia minimitzat</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Defineix els certificats arrel SSL per a la sol·licitud de pagament (per defecte: els del sistema)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Mostra la pantalla de benvinguda a l'inici (per defecte: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Reinicialitza tots els canvis de configuració fets des de la interfície gràfica</translation> + </message> </context> <context> <name>Intro</name> @@ -1069,6 +1108,18 @@ <translation>Port del proxy (per exemple 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Utilitzat per arribar als iguals mitjançant:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Mostra si el proxy SOCKS5 per defecte proporcionat s'utilitza per arribar als iguals mitjançant aquest tipus de xarxa.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor:</translation> + </message> + <message> <source>&Window</source> <translation>&Finestra</translation> </message> @@ -1287,10 +1338,6 @@ <translation>La sol·licitud de pagament %1 és massa gran (%2 bytes, permès %3 bytes).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Protecció de DoS per a la sol·licitud de pagament</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Error en comunicar amb %1: %2</translation> </message> @@ -1459,10 +1506,18 @@ <translation>&Iguals</translation> </message> <message> + <source>Banned peers</source> + <translation>Iguals bandejats</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Seleccioneu un igual per mostrar informació detallada.</translation> </message> <message> + <source>Whitelisted</source> + <translation>A la llista blanca</translation> + </message> + <message> <source>Direction</source> <translation>Direcció</translation> </message> @@ -1471,20 +1526,24 @@ <translation>Versió</translation> </message> <message> - <source>User Agent</source> - <translation>Agent d'usuari</translation> + <source>Starting Block</source> + <translation>Bloc d'inici</translation> </message> <message> - <source>Services</source> - <translation>Serveis</translation> + <source>Synced Headers</source> + <translation>Capçaleres sincronitzades</translation> </message> <message> - <source>Starting Height</source> - <translation>Alçada inicial</translation> + <source>Synced Blocks</source> + <translation>Blocs sincronitzats</translation> </message> <message> - <source>Sync Height</source> - <translation>Sincronitza l'alçada</translation> + <source>User Agent</source> + <translation>Agent d'usuari</translation> + </message> + <message> + <source>Services</source> + <translation>Serveis</translation> </message> <message> <source>Ban Score</source> @@ -1503,16 +1562,16 @@ <translation>Darrera recepció</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Bytes enviats</translation> + <source>Ping Time</source> + <translation>Temps de ping</translation> </message> <message> - <source>Bytes Received</source> - <translation>Bytes rebuts</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>La duració d'un ping més destacat actualment.</translation> </message> <message> - <source>Ping Time</source> - <translation>Temps de ping</translation> + <source>Ping Wait</source> + <translation>Espera de ping</translation> </message> <message> <source>Time Offset</source> @@ -1563,6 +1622,34 @@ <translation>Neteja la consola</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>&Desconnecta el node</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Bandeja el node durant</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &hora</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &dia</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &setmana</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &any</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>&Desbandeja el node</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Us donem la benviguda a la consola RPC del Bitcoin Core.</translation> </message> @@ -1591,6 +1678,10 @@ <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(id del node: %1)</translation> + </message> + <message> <source>via %1</source> <translation>a través de %1</translation> </message> @@ -1607,12 +1698,16 @@ <translation>Sortint</translation> </message> <message> - <source>Unknown</source> - <translation>Desconegut</translation> + <source>Yes</source> + <translation>Sí</translation> </message> <message> - <source>Fetching...</source> - <translation>S'està obtenint...</translation> + <source>No</source> + <translation>No</translation> + </message> + <message> + <source>Unknown</source> + <translation>Desconegut</translation> </message> </context> <context> @@ -1979,8 +2074,8 @@ <translation>Copia el canvi</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Import total %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Import total %1</translation> </message> <message> <source>or</source> @@ -2014,15 +2109,15 @@ <source>Payment request expired.</source> <translation>La sol·licitud de pagament ha vençut.</translation> </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>Paga només la comissió necessària de %1</translation> + </message> <message numerus="yes"> <source>Estimated to begin confirmation within %n block(s).</source> <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Paga només la comissió mínima de %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation> </message> @@ -2801,12 +2896,16 @@ <translation>Accepta la línia d'ordres i ordres JSON-RPC </translation> </message> <message> - <source>Run in the background as a daemon and accept commands</source> - <translation>Executa en segon pla com a programa dimoni i accepta ordres</translation> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Comissions totals màximes (en %s) per utilitzar en una única transacció de moneder; definir-ne una massa baixa pot interrompre les transaccions més grans (per defecte: %s)</translation> </message> <message> - <source>Use the test network</source> - <translation>Utilitza la xarxa de prova</translation> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Comissió (en %s/kB) per afegir a les transaccions que envieu (per defecte: %s)</translation> + </message> + <message> + <source>Run in the background as a daemon and accept commands</source> + <translation>Executa en segon pla com a programa dimoni i accepta ordres</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2829,14 +2928,6 @@ <translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Redueix els requeriments d'emmagatzemament podant (suprimint) els blocs antics. Aquest mode inhabilita l'ús de moneders i és incompatible amb -tindex. Avís: Revertir aquesta configuració comporta tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, >%u = mida objectiu en MiB per utilitzar els fitxers de blocs)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <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> @@ -2857,10 +2948,6 @@ <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Avís: el -paytxfee és molt elevat! Aquesta és la comissió de transacció que pagareu si envieu una transacció.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Avís: la xarxa no sembla que hi estigui plenament d'acord. Alguns miners sembla que estan experimentant problemes.</translation> </message> @@ -2869,10 +2956,6 @@ <translation>Avís: sembla que no estem plenament d'acord amb els nostres iguals! Podria caler que actualitzar l'aplicació, o potser que ho facin altres nodes.</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>Avís: error en llegir el fitxer wallet.dat! Totes les claus es llegeixen correctament, però hi ha dades de transaccions o entrades de la llibreta d'adreces absents o bé son incorrectes.</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>Avís: el fitxer wallet.dat és corrupte, dades rescatades! L'arxiu wallet.dat original ha estat desat com wallet.{estampa_temporal}.bak al directori %s; si el teu balanç o transaccions son incorrectes hauries de restaurar-lo de un backup.</translation> </message> @@ -2881,18 +2964,10 @@ <translation>Afegeix a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(per defecte: 1)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> pot ser:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Intenta recuperar les claus privades d'un fitxer wallet.dat corrupte</translation> - </message> - <message> <source>Block creation options:</source> <translation>Opcions de la creació de blocs:</translation> </message> @@ -2937,10 +3012,6 @@ <translation>Error en obrir la base de dades de blocs</translation> </message> <message> - <source>Error: A fatal internal error occured, see debug.log for details</source> - <translation>Error: s'ha produït un error intern fatal. Consulteu debug.log per a més detalls</translation> - </message> - <message> <source>Error: Disk space is low!</source> <translation>Error: Espai al disc baix!</translation> </message> @@ -2949,10 +3020,6 @@ <translation>Ha fallat escoltar a qualsevol port. Feu servir -listen=0 si voleu fer això.</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> - <message> <source>Importing...</source> <translation>S'està important...</translation> </message> @@ -3021,10 +3088,6 @@ <translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <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> @@ -3053,18 +3116,10 @@ <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>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>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencin a confirmar-se en una mitja de n blocs (per defecte: %u)</translation> </message> @@ -3077,10 +3132,6 @@ <translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meves (per defecte: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>Poda configurada per sota el mínim de %d MB. Feu servir un nombre superior.</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation> </message> @@ -3105,37 +3156,6 @@ <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>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>Per utilitzar bitcoind, o l'opció de serviddor de bitcoin-qt, heu de definir una rpcpassword en el fitxer de configuració: -%s -Es recomana que utilitzeu la contrasenya aleatòria següent: -rpcuser=bitcoinrpc -rpcpassword=%s -(no cal que recordeu la contrasenya) -El nom d'usuari i la contrasenya NO han de ser els mateixos. -Si el fitxer no existeix, creeu-ne un amb permisos de lectura només per al seu propietari. -Es recomana definir alertnotify per tal de ser notificat de qualsevol problema; -per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Avís: s'ha especificat un -maxtxfee molt alt! Comissions tan grans podrien pagar-se en una única transacció.</translation> - </message> - <message> - <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> - <translation>Avís: comproveu que la data i hora del vostre ordinador 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> @@ -3156,18 +3176,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>S'està activant la millor cadena...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>No es pot executar amb un moneder en mode poda.</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Tria el directori de dades a l'inici (per defecte: 0)</translation> - </message> - <message> <source>Connect through SOCKS5 proxy</source> <translation>Connecta a través del proxy SOCKS5</translation> </message> @@ -3176,10 +3188,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <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> @@ -3188,14 +3196,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Error en llegir la base de dades, tancant.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Error: s'ha trobat un argument -tor no acceptat. Feu servir -onion.</translation> - </message> - <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> @@ -3236,18 +3236,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Opcions de transmissió del node:</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> - <message> <source>RPC server options:</source> <translation>Opcions del servidor RPC:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation> </message> @@ -3264,22 +3256,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Envia les transaccions com a transaccions de comissió zero sempre que sigui possible (per defecte: %u) </translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Mostra totes les opcions de depuració (ús: --help --help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostra la finestra de benvinguda a l'inici (per defecte: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Redueix el fitxer debug.log durant l'inici del client (per defecte: 1 quan no -debug)</translation> </message> @@ -3288,10 +3268,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Ha fallat la signatura de la transacció</translation> </message> <message> - <source>Start minimized</source> - <translation>Inicia minimitzat</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation> </message> @@ -3316,18 +3292,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>La transacció és massa gran</translation> </message> <message> - <source>UI Options:</source> - <translation>Opcions d'interfície:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>No s'ha pogut vincular a %s en aquest ordinador (la vinculació ha retornat l'error %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Utilitza UPnP per a mapejar els ports d'escolta (per defecte: 1 quan s'escolta)</translation> - </message> - <message> <source>Username for JSON-RPC connections</source> <translation>Nom d'usuari per a connexions JSON-RPC</translation> </message> @@ -3340,22 +3308,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Avís</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> <message> - <source>on startup</source> - <translation>a l'inici de l'aplicació</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>El fitxer wallet.data és corrupte. El rescat de les dades ha fallat</translation> </message> @@ -3368,18 +3324,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Executa l'ordre quan el millor bloc canviï (%s en cmd es reemplaça per un resum de bloc)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Actualitza el moneder a l'últim format</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Utilitza OpenSSL (https) per a connexions JSON-RPC</translation> - </message> - <message> <source>This help message</source> <translation>Aquest misatge d'ajuda</translation> </message> @@ -3424,10 +3368,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>(per defecte: %s)</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Xifrats acceptables (per defecte: %s)</translation> - </message> - <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> <translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation> </message> @@ -3488,14 +3428,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Retransmet multisig no P2SH (per defecte: %u)</translation> </message> <message> - <source>Server certificate file (default: %s)</source> - <translation>Fitxer de certificat del servidor (per defecte: %s)</translation> - </message> - <message> - <source>Server private key (default: %s)</source> - <translation>Clau privada del servidor (per defecte: %s)</translation> - </message> - <message> <source>Set key pool size to <n> (default: %u)</source> <translation>Defineix la mida clau disponible a <n> (per defecte: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index b77845cfb2..2c41ec78d4 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -1,4 +1,4 @@ -<TS language="ca@valencia" version="2.0"> +<TS language="ca@valencia" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -431,6 +434,10 @@ <translation>No hi ha cap font de bloc disponible...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Proccessats %n bloc de l'historial de transaccions.</numerusform><numerusform>Proccessats %n blocs de l'historial de transaccions.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation> </message> @@ -867,7 +874,7 @@ <source>command-line options</source> <translation>Opcions de la línia d'ordes</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -1065,6 +1072,10 @@ <translation>Port del proxy (per exemple 9050)</translation> </message> <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor:</translation> + </message> + <message> <source>&Window</source> <translation>&Finestra</translation> </message> @@ -1283,10 +1294,6 @@ <translation>La sol·licitud de pagament %1 és massa gran (%2 bytes, permés %3 bytes).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Protecció de DoS per a la sol·licitud de pagament</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Error en comunicar amb %1: %2</translation> </message> @@ -1475,14 +1482,6 @@ <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> @@ -1499,14 +1498,6 @@ <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> @@ -1603,12 +1594,16 @@ <translation>Eixint</translation> </message> <message> - <source>Unknown</source> - <translation>Desconegut</translation> + <source>Yes</source> + <translation>Sí</translation> </message> <message> - <source>Fetching...</source> - <translation>S'està obtenint...</translation> + <source>No</source> + <translation>No</translation> + </message> + <message> + <source>Unknown</source> + <translation>Desconegut</translation> </message> </context> <context> @@ -1975,10 +1970,6 @@ <translation>Copia el canvi</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Import total %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>o</translation> </message> @@ -2015,10 +2006,6 @@ <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Paga només la comissió mínima de %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation> </message> @@ -2801,10 +2788,6 @@ <translation>Executa en segon pla com a programa dimoni i accepta ordes</translation> </message> <message> - <source>Use the test network</source> - <translation>Utilitza la xarxa de prova</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Accepta connexions de fora (per defecte: 1 si no -proxy o -connect)</translation> </message> @@ -2825,14 +2808,6 @@ <translation>Executa una orde quan una transacció del moneder canvie (%s en cmd es canvia per TxID)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Redueix els requeriments d'emmagatzemament podant (suprimint) els blocs antics. Este mode inhabilita l'ús de moneders i és incompatible amb -tindex. Avís: Revertir esta configuració comporta tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, >%u = mida objectiu en MiB per utilitzar els fitxers de blocs)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <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> @@ -2853,10 +2828,6 @@ <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Avís: el -paytxfee és molt elevat! Esta és la comissió de transacció que pagareu si envieu una transacció.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Avís: la xarxa no pareix que hi estiga plenament d'acord. Alguns miners pareix que estan experimentant problemes.</translation> </message> @@ -2865,10 +2836,6 @@ <translation>Avís: pareix que no estem plenament d'acord amb els nostres iguals! Podria caldre que actualitzar l'aplicació, o potser que ho facen altres nodes.</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>Avís: error en llegir el fitxer wallet.dat! Totes les claus es lligen correctament, però hi ha dades de transaccions o entrades de la llibreta d'adreces absents o bé son incorrectes.</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>Avís: el fitxer wallet.dat és corrupte, dades rescatades! L'arxiu wallet.dat original ha estat guardat com wallet.{estampa_temporal}.bak al directori %s; si el teu balanç o transaccions son incorrectes hauries de restaurar-lo de un backup.</translation> </message> @@ -2877,18 +2844,10 @@ <translation>Afig a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(per defecte: 1)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> pot ser:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Intenta recuperar les claus privades d'un fitxer wallet.dat corrupte</translation> - </message> - <message> <source>Block creation options:</source> <translation>Opcions de la creació de blocs:</translation> </message> @@ -2933,10 +2892,6 @@ <translation>Error en obrir la base de dades de blocs</translation> </message> <message> - <source>Error: A fatal internal error occured, see debug.log for details</source> - <translation>Error: s'ha produït un error intern fatal. Consulteu debug.log per a més detalls</translation> - </message> - <message> <source>Error: Disk space is low!</source> <translation>Error: Espai al disc baix!</translation> </message> @@ -2945,10 +2900,6 @@ <translation>Ha fallat escoltar a qualsevol port. Feu servir -listen=0 si voleu fer això.</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> - <message> <source>Importing...</source> <translation>S'està important...</translation> </message> @@ -3017,10 +2968,6 @@ <translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <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> @@ -3049,18 +2996,10 @@ <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>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>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencen a confirmar-se en una mitja de n blocs (per defecte: %u)</translation> </message> @@ -3073,10 +3012,6 @@ <translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meues (per defecte: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>Poda configurada per sota el mínim de %d MB. Feu servir un nombre superior.</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation> </message> @@ -3101,37 +3036,6 @@ <translation>Este producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit <https://www.openssl.org/> i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation> </message> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>Per utilitzar bitcoind, o l'opció de serviddor de bitcoin-qt, heu de definir una rpcpassword en el fitxer de configuració: -%s -Es recomana que utilitzeu la contrasenya aleatòria següent: -rpcuser=bitcoinrpc -rpcpassword=%s -(no cal que recordeu la contrasenya) -El nom d'usuari i la contrasenya NO han de ser els mateixos. -Si el fitxer no existeix, creeu-ne un amb permisos de lectura només per al seu propietari. -Es recomana definir alertnotify per tal de ser notificat de qualsevol problema; -per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Avís: s'ha especificat un -maxtxfee molt alt! Comissions tan grans podrien pagar-se en una única transacció.</translation> - </message> - <message> - <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> - <translation>Avís: comproveu que la data i hora del vostre ordinador siguen correctes! Si el vostre rellotge no és correcte, el Bitcoin Core no funcionarà correctament.</translation> - </message> - <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> @@ -3152,18 +3056,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>S'està activant la millor cadena...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>No es pot executar amb un moneder en mode poda.</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Tria el directori de dades a l'inici (per defecte: 0)</translation> - </message> - <message> <source>Connect through SOCKS5 proxy</source> <translation>Connecta a través del proxy SOCKS5</translation> </message> @@ -3172,10 +3068,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <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> @@ -3184,14 +3076,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Error en llegir la base de dades, tancant.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Error: s'ha trobat un argument -tor no acceptat. Feu servir -onion.</translation> - </message> - <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> @@ -3232,18 +3116,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Opcions de transmissió del node:</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> - <message> <source>RPC server options:</source> <translation>Opcions del servidor RPC:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation> </message> @@ -3260,22 +3136,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Envia les transaccions com a transaccions de comissió zero sempre que siga possible (per defecte: %u) </translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Mostra totes les opcions de depuració (ús: --help --help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostra la finestra de benvinguda a l'inici (per defecte: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Redueix el fitxer debug.log durant l'inici del client (per defecte: 1 quan no -debug)</translation> </message> @@ -3284,10 +3148,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Ha fallat la signatura de la transacció</translation> </message> <message> - <source>Start minimized</source> - <translation>Inicia minimitzat</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation> </message> @@ -3312,18 +3172,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>La transacció és massa gran</translation> </message> <message> - <source>UI Options:</source> - <translation>Opcions d'interfície:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>No s'ha pogut vincular a %s en 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> - <translation>Utilitza UPnP per a mapejar els ports d'escolta (per defecte: 1 quan s'escolta)</translation> - </message> - <message> <source>Username for JSON-RPC connections</source> <translation>Nom d'usuari per a connexions JSON-RPC</translation> </message> @@ -3336,22 +3188,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Avís</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> <message> - <source>on startup</source> - <translation>a l'inici de l'aplicació</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>El fitxer wallet.data és corrupte. El rescat de les dades ha fallat</translation> </message> @@ -3364,18 +3204,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Executa l'orde quan el millor bloc canvie (%s en cmd es reemplaça per un resum de bloc)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Actualitza el moneder a l'últim format</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Utilitza OpenSSL (https) per a connexions JSON-RPC</translation> - </message> - <message> <source>This help message</source> <translation>Este misatge d'ajuda</translation> </message> @@ -3420,10 +3248,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>(per defecte: %s)</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Xifrats acceptables (per defecte: %s)</translation> - </message> - <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> <translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation> </message> @@ -3484,14 +3308,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Retransmet multisig no P2SH (per defecte: %u)</translation> </message> <message> - <source>Server certificate file (default: %s)</source> - <translation>Fitxer de certificat del servidor (per defecte: %s)</translation> - </message> - <message> - <source>Server private key (default: %s)</source> - <translation>Clau privada del servidor (per defecte: %s)</translation> - </message> - <message> <source>Set key pool size to <n> (default: %u)</source> <translation>Defineix la mida clau disponible a <n> (per defecte: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index 898b7f33b3..e6a932ebee 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.0"> +<TS language="ca_ES" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP / Màscara de xarxa</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Bandejat fins</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -871,6 +882,34 @@ <source>command-line options</source> <translation>Opcions de la línia d'ordres</translation> </message> + <message> + <source>UI Options:</source> + <translation>Opcions d'interfície d'usuari:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Trieu el directori de dades a l'inici (per defecte: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Defineix la llengua, per exemple «de_DE» (per defecte: la definida pel sistema)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Inicia minimitzat</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Defineix els certificats arrel SSL per a la sol·licitud de pagament (per defecte: els del sistema)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Mostra la pantalla de benvinguda a l'inici (per defecte: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Reinicialitza tots els canvis de configuració fets des de la interfície gràfica</translation> + </message> </context> <context> <name>Intro</name> @@ -1069,6 +1108,18 @@ <translation>Port del proxy (per exemple 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Utilitzat per arribar als iguals mitjançant:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Mostra si el proxy SOCKS5 per defecte proporcionat s'utilitza per arribar als iguals mitjançant aquest tipus de xarxa.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor:</translation> + </message> + <message> <source>&Window</source> <translation>&Finestra</translation> </message> @@ -1287,10 +1338,6 @@ <translation>La sol·licitud de pagament %1 és massa gran (%2 bytes, permès %3 bytes).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Protecció de DoS per a la sol·licitud de pagament</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Error en comunicar amb %1: %2</translation> </message> @@ -1459,10 +1506,18 @@ <translation>&Iguals</translation> </message> <message> + <source>Banned peers</source> + <translation>Iguals bandejats</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Seleccioneu un igual per mostrar informació detallada.</translation> </message> <message> + <source>Whitelisted</source> + <translation>A la llista blanca</translation> + </message> + <message> <source>Direction</source> <translation>Direcció</translation> </message> @@ -1471,20 +1526,24 @@ <translation>Versió</translation> </message> <message> - <source>User Agent</source> - <translation>Agent d'usuari</translation> + <source>Starting Block</source> + <translation>Bloc d'inici</translation> </message> <message> - <source>Services</source> - <translation>Serveis</translation> + <source>Synced Headers</source> + <translation>Capçaleres sincronitzades</translation> </message> <message> - <source>Starting Height</source> - <translation>Alçada inicial</translation> + <source>Synced Blocks</source> + <translation>Blocs sincronitzats</translation> </message> <message> - <source>Sync Height</source> - <translation>Sincronitza l'alçada</translation> + <source>User Agent</source> + <translation>Agent d'usuari</translation> + </message> + <message> + <source>Services</source> + <translation>Serveis</translation> </message> <message> <source>Ban Score</source> @@ -1503,16 +1562,16 @@ <translation>Darrera recepció</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Bytes enviats</translation> + <source>Ping Time</source> + <translation>Temps de ping</translation> </message> <message> - <source>Bytes Received</source> - <translation>Bytes rebuts</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>La duració d'un ping més destacat actualment.</translation> </message> <message> - <source>Ping Time</source> - <translation>Temps de ping</translation> + <source>Ping Wait</source> + <translation>Espera de ping</translation> </message> <message> <source>Time Offset</source> @@ -1563,6 +1622,34 @@ <translation>Neteja la consola</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>&Desconnecta el node</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Bandeja el node durant</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &hora</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &dia</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &setmana</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &any</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>&Desbandeja el node</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Us donem la benviguda a la consola RPC del Bitcoin Core.</translation> </message> @@ -1591,6 +1678,10 @@ <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(id del node: %1)</translation> + </message> + <message> <source>via %1</source> <translation>a través de %1</translation> </message> @@ -1607,12 +1698,16 @@ <translation>Sortint</translation> </message> <message> - <source>Unknown</source> - <translation>Desconegut</translation> + <source>Yes</source> + <translation>Sí</translation> </message> <message> - <source>Fetching...</source> - <translation>S'està obtenint...</translation> + <source>No</source> + <translation>No</translation> + </message> + <message> + <source>Unknown</source> + <translation>Desconegut</translation> </message> </context> <context> @@ -1979,8 +2074,8 @@ <translation>Copia el canvi</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Import total %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Import total %1</translation> </message> <message> <source>or</source> @@ -2014,15 +2109,15 @@ <source>Payment request expired.</source> <translation>La sol·licitud de pagament ha vençut.</translation> </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>Paga només la comissió necessària de %1</translation> + </message> <message numerus="yes"> <source>Estimated to begin confirmation within %n block(s).</source> <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Paga només la comissió mínima de %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation> </message> @@ -2801,12 +2896,16 @@ <translation>Accepta la línia d'ordres i ordres JSON-RPC </translation> </message> <message> - <source>Run in the background as a daemon and accept commands</source> - <translation>Executa en segon pla com a programa dimoni i accepta ordres</translation> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Comissions totals màximes (en %s) per utilitzar en una única transacció de moneder; definir-ne una massa baixa pot interrompre les transaccions més grans (per defecte: %s)</translation> </message> <message> - <source>Use the test network</source> - <translation>Utilitza la xarxa de prova</translation> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Comissió (en %s/kB) per afegir a les transaccions que envieu (per defecte: %s)</translation> + </message> + <message> + <source>Run in the background as a daemon and accept commands</source> + <translation>Executa en segon pla com a programa dimoni i accepta ordres</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2829,14 +2928,6 @@ <translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Redueix els requeriments d'emmagatzemament podant (suprimint) els blocs antics. Aquest mode inhabilita l'ús de moneders i és incompatible amb -tindex. Avís: Revertir aquesta configuració comporta tornar a baixar la cadena de blocs sencera. (per defecte: 0 = inhabilita la poda de blocs, >%u = mida objectiu en MiB per utilitzar els fitxers de blocs)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <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> @@ -2857,10 +2948,6 @@ <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Avís: el -paytxfee és molt elevat! Aquesta és la comissió de transacció que pagareu si envieu una transacció.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Avís: la xarxa no sembla que hi estigui plenament d'acord. Alguns miners sembla que estan experimentant problemes.</translation> </message> @@ -2869,10 +2956,6 @@ <translation>Avís: sembla que no estem plenament d'acord amb els nostres iguals! Podria caler que actualitzar l'aplicació, o potser que ho facin altres nodes.</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>Avís: error en llegir el fitxer wallet.dat! Totes les claus es llegeixen correctament, però hi ha dades de transaccions o entrades de la llibreta d'adreces absents o bé son incorrectes.</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>Avís: el fitxer wallet.dat és corrupte, dades rescatades! L'arxiu wallet.dat original ha estat desat com wallet.{estampa_temporal}.bak al directori %s; si el teu balanç o transaccions son incorrectes hauries de restaurar-lo de un backup.</translation> </message> @@ -2881,18 +2964,10 @@ <translation>Afegeix a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(per defecte: 1)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> pot ser:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Intenta recuperar les claus privades d'un fitxer wallet.dat corrupte</translation> - </message> - <message> <source>Block creation options:</source> <translation>Opcions de la creació de blocs:</translation> </message> @@ -2937,10 +3012,6 @@ <translation>Error en obrir la base de dades de blocs</translation> </message> <message> - <source>Error: A fatal internal error occured, see debug.log for details</source> - <translation>Error: s'ha produït un error intern fatal. Consulteu debug.log per a més detalls</translation> - </message> - <message> <source>Error: Disk space is low!</source> <translation>Error: Espai al disc baix!</translation> </message> @@ -2949,10 +3020,6 @@ <translation>Ha fallat escoltar a qualsevol port. Feu servir -listen=0 si voleu fer això.</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> - <message> <source>Importing...</source> <translation>S'està important...</translation> </message> @@ -3021,10 +3088,6 @@ <translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <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> @@ -3053,18 +3116,10 @@ <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>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>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencin a confirmar-se en una mitja de n blocs (per defecte: %u)</translation> </message> @@ -3077,10 +3132,6 @@ <translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meves (per defecte: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>Poda configurada per sota el mínim de %d MB. Feu servir un nombre superior.</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation> </message> @@ -3105,37 +3156,6 @@ <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>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>Per utilitzar bitcoind, o l'opció de serviddor de bitcoin-qt, heu de definir una rpcpassword en el fitxer de configuració: -%s -Es recomana que utilitzeu la contrasenya aleatòria següent: -rpcuser=bitcoinrpc -rpcpassword=%s -(no cal que recordeu la contrasenya) -El nom d'usuari i la contrasenya NO han de ser els mateixos. -Si el fitxer no existeix, creeu-ne un amb permisos de lectura només per al seu propietari. -Es recomana definir alertnotify per tal de ser notificat de qualsevol problema; -per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Avís: s'ha especificat un -maxtxfee molt alt! Comissions tan grans podrien pagar-se en una única transacció.</translation> - </message> - <message> - <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> - <translation>Avís: comproveu que la data i hora del vostre ordinador 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> @@ -3156,18 +3176,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>S'està activant la millor cadena...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>No es pot executar amb un moneder en mode poda.</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>No es pot resoldre l'adreça -whitebind: «%s»</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Tria el directori de dades a l'inici (per defecte: 0)</translation> - </message> - <message> <source>Connect through SOCKS5 proxy</source> <translation>Connecta a través del proxy SOCKS5</translation> </message> @@ -3176,10 +3188,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <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> @@ -3188,14 +3196,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Error en llegir la base de dades, tancant.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Error: s'ha trobat un argument -tor no acceptat. Feu servir -onion.</translation> - </message> - <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> @@ -3236,18 +3236,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Opcions de transmissió del node:</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> - <message> <source>RPC server options:</source> <translation>Opcions del servidor RPC:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation> </message> @@ -3264,22 +3256,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Envia les transaccions com a transaccions de comissió zero sempre que sigui possible (per defecte: %u) </translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Mostra totes les opcions de depuració (ús: --help --help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostra la finestra de benvinguda a l'inici (per defecte: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Redueix el fitxer debug.log durant l'inici del client (per defecte: 1 quan no -debug)</translation> </message> @@ -3288,10 +3268,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Ha fallat la signatura de la transacció</translation> </message> <message> - <source>Start minimized</source> - <translation>Inicia minimitzat</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation> </message> @@ -3316,18 +3292,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>La transacció és massa gran</translation> </message> <message> - <source>UI Options:</source> - <translation>Opcions d'interfície:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>No s'ha pogut vincular a %s en aquest ordinador (la vinculació ha retornat l'error %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Utilitza UPnP per a mapejar els ports d'escolta (per defecte: 1 quan s'escolta)</translation> - </message> - <message> <source>Username for JSON-RPC connections</source> <translation>Nom d'usuari per a connexions JSON-RPC</translation> </message> @@ -3340,22 +3308,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Avís</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> <message> - <source>on startup</source> - <translation>a l'inici de l'aplicació</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>El fitxer wallet.data és corrupte. El rescat de les dades ha fallat</translation> </message> @@ -3368,18 +3324,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Executa l'ordre quan el millor bloc canviï (%s en cmd es reemplaça per un resum de bloc)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Actualitza el moneder a l'últim format</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Utilitza OpenSSL (https) per a connexions JSON-RPC</translation> - </message> - <message> <source>This help message</source> <translation>Aquest misatge d'ajuda</translation> </message> @@ -3424,10 +3368,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>(per defecte: %s)</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Xifrats acceptables (per defecte: %s)</translation> - </message> - <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> <translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation> </message> @@ -3488,14 +3428,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr <translation>Retransmet multisig no P2SH (per defecte: %u)</translation> </message> <message> - <source>Server certificate file (default: %s)</source> - <translation>Fitxer de certificat del servidor (per defecte: %s)</translation> - </message> - <message> - <source>Server private key (default: %s)</source> - <translation>Clau privada del servidor (per defecte: %s)</translation> - </message> - <message> <source>Set key pool size to <n> (default: %u)</source> <translation>Defineix la mida clau disponible a <n> (per defecte: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index 6e7ffec27f..ef1903edd1 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -1,4 +1,4 @@ -<TS language="cs" version="2.0"> +<TS language="cs" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -871,7 +874,7 @@ <source>command-line options</source> <translation>možnosti příkazové řádky</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -1069,6 +1072,10 @@ <translation>Port proxy (např. 9050)</translation> </message> <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Použít samostatnou SOCKS5 proxy ke spojení s protějšky přes skryté služby v Toru:</translation> + </message> + <message> <source>&Window</source> <translation>O&kno</translation> </message> @@ -1287,10 +1294,6 @@ <translation>Platební požadavek %1 je moc velký (%2 bajtů, povoleno %3 bajtů).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>DoS ochrana platebního požadavku</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Chyba při komunikaci s %1: %2</translation> </message> @@ -1479,14 +1482,6 @@ <translation>Služby</translation> </message> <message> - <source>Starting Height</source> - <translation>Prvotní výška</translation> - </message> - <message> - <source>Sync Height</source> - <translation>Aktuální výška</translation> - </message> - <message> <source>Ban Score</source> <translation>Skóre pro klatbu</translation> </message> @@ -1503,14 +1498,6 @@ <translation>Poslední příjem</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Bajtů odesláno</translation> - </message> - <message> - <source>Bytes Received</source> - <translation>Bajtů přijato</translation> - </message> - <message> <source>Ping Time</source> <translation>Odezva</translation> </message> @@ -1607,12 +1594,16 @@ <translation>Ven</translation> </message> <message> - <source>Unknown</source> - <translation>Neznámá</translation> + <source>Yes</source> + <translation>Ano</translation> </message> <message> - <source>Fetching...</source> - <translation>Stahuji...</translation> + <source>No</source> + <translation>Ne</translation> + </message> + <message> + <source>Unknown</source> + <translation>Neznámá</translation> </message> </context> <context> @@ -1979,10 +1970,6 @@ <translation>Kopíruj drobné</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Celková částka %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>nebo</translation> </message> @@ -2019,10 +2006,6 @@ <translation><numerusform>Potvrzování by podle odhadu mělo začít během %n bloku.</numerusform><numerusform>Potvrzování by podle odhadu mělo začít během %n bloků.</numerusform><numerusform>Potvrzování by podle odhadu mělo začít během %n bloků.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Zaplatit pouze minimální poplatek %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>Adresa příjemce je neplatná – překontroluj ji prosím.</translation> </message> @@ -2805,10 +2788,6 @@ <translation>Běžet na pozadí jako démon a akceptovat příkazy</translation> </message> <message> - <source>Use the test network</source> - <translation>Použít testovací síť (testnet)</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Přijímat spojení zvenčí (výchozí: 1, pokud není zadáno -proxy nebo -connect)</translation> </message> @@ -2829,14 +2808,6 @@ <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>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Horní hranice pro celkový poplatek za jednu transakci z peněženky; příliš nízká hodnota může zmařit velké transakce (výchozí: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Omezit nároky na úložný prostor prořezáváním (mazáním) starých bloků. V tomto režimu chybí peněženka a rovněž tento režim není slučitelný s -txindex. Upozornění: opětovná změna tohoto nastavení bude vyžadovat nové stažení celého řetězce bloků. (výchozí: 0 = bloky neprořezávat, >%u = cílová velikost souborů s bloky, v MiB)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <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> @@ -2857,10 +2828,6 @@ <translation>UPOZORNĚNÍ: zkontroluj své spojení do sítě – bylo přijato %d bloků za posledních %d hodin (očekáváno %d)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Upozornění: -paytxfee je nastaveno velmi vysoko! Toto je transakční poplatek, který zaplatíš za každou poslanou transakci.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Upozornění: Síť podle všeho není v konzistentním stavu. Někteří těžaři jsou zřejmě v potížích.</translation> </message> @@ -2869,10 +2836,6 @@ <translation>Upozornění: Nesouhlasím zcela se svými protějšky! Možná potřebuji aktualizovat nebo ostatní uzly potřebují aktualizovat.</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>Upozornění: nastala chyba při čtení souboru wallet.dat! Všechny klíče se přečetly správně, ale data o transakcích nebo záznamy v adresáři mohou chybět či být nesprávné.</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>Upozornění: soubor wallet.dat je poškozený, data jsou však zachráněna! Původní soubor wallet.dat je uložený jako wallet.{timestamp}.bak v %s. Pokud je stav tvého účtu nebo transakce nesprávné, zřejmě bys měl obnovit zálohu.</translation> </message> @@ -2881,18 +2844,10 @@ <translation>Umístit na bílou listinu protějšky připojující se z dané podsítě či IP adresy. Lze zadat i vícekrát.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(výchozí: 1)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> může být:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Pokusit se zachránit soukromé klíče z poškozeného souboru wallet.dat</translation> - </message> - <message> <source>Block creation options:</source> <translation>Možnosti vytváření bloku:</translation> </message> @@ -2937,10 +2892,6 @@ <translation>Chyba při otevírání databáze bloků</translation> </message> <message> - <source>Error: A fatal internal error occured, see debug.log for details</source> - <translation>Chyba: Stala se fatální vnitřní chyba. detaily viz v debug.log</translation> - </message> - <message> <source>Error: Disk space is low!</source> <translation>Problém: Na disku je málo místa!</translation> </message> @@ -2949,10 +2900,6 @@ <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>If <category> is not supplied, output all debugging information.</source> - <translation>Pokud není <category> zadána, bude tisknout veškeré ladicí informace.</translation> - </message> - <message> <source>Importing...</source> <translation>Importuji...</translation> </message> @@ -3021,18 +2968,10 @@ <translation>Je třeba přestavět databázi použitím -reindex, aby bylo možné změnit -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importovat bloky z externího souboru 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>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> <message> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation>Při nastavování naslouchací RPC adresy %s a portu %u nastala chyba: %s</translation> - </message> - <message> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> <translation>Obsadit zadanou adresu a protějšky, které se na ní připojí, umístit na bílou listinu. Pro zápis IPv6 adresy použij notaci [adresa]:port</translation> </message> @@ -3057,18 +2996,10 @@ <translation>Chyba: Nelze naslouchat příchozí spojení (listen vrátil chybu %s)</translation> </message> <message> - <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> - <translation>Chyba: 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 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> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Poplatky (v BTC/kB) menší než tato hodnota jsou považovány za nulové pro účely přeposílání transakcí (výchozí: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Pokud paytxfee není nastaveno, platit dostatečný poplatek na to, aby začaly být transakce potvrzovány v průměru během n bloků (výchozí: %u)</translation> </message> @@ -3081,10 +3012,6 @@ <translation>Maximální velikost dat v transakcích nesoucích data, se kterou jsme ochotni je ještě přeposílat a těžit (výchozí: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>Prořezávání je nastaveno pod minimum %d MB. Použij prosím nějaké vyšší číslo.</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Při nedostatku adres získat další protějšky z DNS (výchozí: 1, pokud není použito -connect)</translation> </message> @@ -3109,38 +3036,6 @@ <translation>Tento produkt zahrnuje programy vyvinuté OpenSSL Projektem pro použití v OpenSSL Toolkitu <https://www.openssl.org/> a kryptografický program od Erika Younga a program UPnP od Thomase Bernarda.</translation> </message> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>K používání bitcoind nebo volby -server u bitcoin-qt musíš nastavit rpcpassword v konfiguračním souboru: -%s -Je vhodné použít následující náhodné heslo: -rpcuser=bitcoinrpc -rpcpassword=%s -(není potřeba si ho pamatovat) -rpcuser a rpcpassword NESMÍ být stejné. -Pokud konfigurační soubor ještě neexistuje, vytvoř ho tak, aby ho mohl číst pouze vlastník. -Je také doporučeno si nastavit alertnotify, abys byl upozorněn na případné problémy; -například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Upozornění: -maxtxfee je nastaveno velmi vysoko! Takto vysoký poplatek může být zaplacen v jednotlivé transakci.</translation> - </message> - <message> - <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> - <translation>Upozornění: Zkontroluj, že máš v počítači správně nastavený datum a čas! Pokud jsou nastaveny špatně, Bitcoin Core nebude fungovat správně.</translation> - </message> - <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> @@ -3161,18 +3056,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aktivuji nejlepší řetězec...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>V prořezávacím režimu se s pěněženkou nemůžu spustit.</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Nemohu přeložit -whitebind adresu: '%s'</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Zvolit adresář pro data při startu (výchozí: 0)</translation> - </message> - <message> <source>Connect through SOCKS5 proxy</source> <translation>Připojit se přes SOCKS5 proxy</translation> </message> @@ -3181,10 +3068,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Copyright (C) 2009-%i Vývojáři Bitcoin Core</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Nejde mi přečíst hodnotu -rpcbind %s jako síťovou adresu</translation> - </message> - <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Chyba při načítání wallet.dat: peněženka vyžaduje novější verzi Bitcoin Core</translation> </message> @@ -3193,14 +3076,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Chyba při čtení z databáze, ukončuji se.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Chyba: Argument -tor již není podporovaný, použij -onion.</translation> - </message> - <message> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation>Poplatek (v BTC/kB), který se přidá ke každé odeslané transakci (výchozí: %s)</translation> - </message> - <message> <source>Information</source> <translation>Informace</translation> </message> @@ -3241,18 +3116,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Možnosti přeposílání:</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> - <message> <source>RPC server options:</source> <translation>Možnosti RPC serveru:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>Podpora RPC pro perzistentní HTTP spojení (výchozí: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Při startu znovu vytvořit index řetězce bloků z aktuálních blk000??.dat souborů</translation> </message> @@ -3269,22 +3136,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Posílat transakce pokud možno bez poplatků (výchozí: %u)</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Nastavit kořenové SSL certifikáty pro platební požadavky (výchozí: -system-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Nastavit jazyk, například „de_DE“ (výchozí: systémové nastavení)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Zobrazit všechny možnosti ladění (užití: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Zobrazit startovací obrazovku (výchozí: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Při spuštění klienta zmenšit soubor debug.log (výchozí: 1, pokud není zadáno -debug)</translation> </message> @@ -3293,10 +3148,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Nepodařilo se podepsat transakci</translation> </message> <message> - <source>Start minimized</source> - <translation>Nastartovat minimalizovaně</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>Částka v transakci je příliš malá na pokrytí poplatku</translation> </message> @@ -3321,18 +3172,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transakce je příliš velká</translation> </message> <message> - <source>UI Options:</source> - <translation>Možnosti UI:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Nedaří se mi připojit na %s na tomhle počítači (operace bind vrátila chybu %s)</translation> </message> <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> - <message> <source>Username for JSON-RPC connections</source> <translation>Uživatelské jméno pro JSON-RPC spojení</translation> </message> @@ -3345,22 +3188,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Upozornění</translation> </message> <message> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation>Upozornění: Nepodporovaný argument -benchmark se ignoruje, použij -debug=bench.</translation> - </message> - <message> - <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> - <translation>Upozornění: Nepodporovaný argument -debugnet se ignoruje, použij -debug=net.</translation> - </message> - <message> <source>Zapping all transactions from wallet...</source> <translation>Vymazat všechny transakce z peněženky...</translation> </message> <message> - <source>on startup</source> - <translation>při startu</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>Soubor wallet.dat je poškozen, jeho záchrana se nezdařila</translation> </message> @@ -3373,18 +3204,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Spustit příkaz, když se změní nejlepší blok (%s se v příkazu nahradí hashem bloku)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Převést peněženku na nejnovější formát</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Použít OpenSSL (https) pro JSON-RPC spojení</translation> - </message> - <message> <source>This help message</source> <translation>Tato nápověda</translation> </message> @@ -3429,10 +3248,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(výchozí: %s)</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Akceptovatelné šifry (výchozí: %s)</translation> - </message> - <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> <translation>Vždy získávat adresy dalších protějšků přes DNS (výchozí: %u)</translation> </message> @@ -3493,14 +3308,6 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Přeposílat ne-P2SH multisig (výchozí: %u)</translation> </message> <message> - <source>Server certificate file (default: %s)</source> - <translation>Soubor se serverovým certifikátem (výchozí: %s)</translation> - </message> - <message> - <source>Server private key (default: %s)</source> - <translation>Soubor se serverovým soukromým klíčem (výchozí: %s)</translation> - </message> - <message> <source>Set key pool size to <n> (default: %u)</source> <translation>Nastavit zásobník klíčů na velikost <n> (výchozí: %u)</translation> </message> @@ -3521,6 +3328,10 @@ například: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Zadej časový limit spojení v milivteřinách (minimum: 1, výchozí: %d)</translation> </message> <message> + <source>Specify pid file (default: %s)</source> + <translation>PID soubor (výchozí: %s)</translation> + </message> + <message> <source>Spend unconfirmed change when sending transactions (default: %u)</source> <translation>Utrácet i ještě nepotvrzené drobné při posílání transakcí (výchozí: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_cs_CZ.ts b/src/qt/locale/bitcoin_cs_CZ.ts new file mode 100644 index 0000000000..cc0c791154 --- /dev/null +++ b/src/qt/locale/bitcoin_cs_CZ.ts @@ -0,0 +1,645 @@ +<TS language="cs_CZ" version="2.1"> +<context> + <name>AddressBookPage</name> + <message> + <source>Create a new address</source> + <translation>Vytvořit novou adresu</translation> + </message> + <message> + <source>Copy the currently selected address to the system clipboard</source> + <translation>Kopírovat aktuálně vybrané adresy do schránky</translation> + </message> + <message> + <source>&Delete</source> + <translation>&Odstranit</translation> + </message> + <message> + <source>Comma separated file (*.csv)</source> + <translation>Textový soubor oddělený středníkem (*.csv)</translation> + </message> + </context> +<context> + <name>AddressTableModel</name> + <message> + <source>Label</source> + <translation>Popis</translation> + </message> + <message> + <source>Address</source> + <translation>Adresa</translation> + </message> + <message> + <source>(no label)</source> + <translation>(bez popisu)</translation> + </message> +</context> +<context> + <name>AskPassphraseDialog</name> + <message> + <source>Enter passphrase</source> + <translation>Zadej heslo</translation> + </message> + <message> + <source>New passphrase</source> + <translation>Nové heslo</translation> + </message> + <message> + <source>Repeat new passphrase</source> + <translation>Zopakujte nové heslo</translation> + </message> + <message> + <source>Encrypt wallet</source> + <translation>Zašifrovat peněženku</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to unlock the wallet.</source> + <translation>Tato operace vyžaduje heslo k odemknutí peněženky.</translation> + </message> + <message> + <source>Unlock wallet</source> + <translation>Odemknout peněženku</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to decrypt the wallet.</source> + <translation>Tato operace vyžaduje heslo k dešifrování peněženky.</translation> + </message> + <message> + <source>Decrypt wallet</source> + <translation>Dešifrovat peněženku</translation> + </message> + <message> + <source>Change passphrase</source> + <translation>Změnit heslo</translation> + </message> + <message> + <source>Confirm wallet encryption</source> + <translation>Potvrďte zašifrování peněženky</translation> + </message> + <message> + <source>Wallet encrypted</source> + <translation>Peněženka zašifrována</translation> + </message> + <message> + <source>Wallet encryption failed</source> + <translation>Zašifrování peněženky selhalo</translation> + </message> + <message> + <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> + <translation>Šifrování peněženky selhalo vinou vnitřní chyby. Vaše peněženka nebyla zašifrována.</translation> + </message> + <message> + <source>The supplied passphrases do not match.</source> + <translation>Zadaná hesla nejsou shodná.</translation> + </message> + <message> + <source>Wallet unlock failed</source> + <translation>Odemčení peněženky selhalo</translation> + </message> + <message> + <source>The passphrase entered for the wallet decryption was incorrect.</source> + <translation>Heslo zadané k dešifrování peněženky nebylo správné</translation> + </message> + <message> + <source>Wallet decryption failed</source> + <translation>Deěifrování peněženky selhalo</translation> + </message> + </context> +<context> + <name>BanTableModel</name> + </context> +<context> + <name>BitcoinGUI</name> + <message> + <source>Synchronizing with network...</source> + <translation>Synchronizuji se sítí...</translation> + </message> + <message> + <source>&Overview</source> + <translation>&Přehled</translation> + </message> + <message> + <source>Show general overview of wallet</source> + <translation>Zobrazit základní přehled o peněžence</translation> + </message> + <message> + <source>&Transactions</source> + <translation>&Transakce</translation> + </message> + <message> + <source>Browse transaction history</source> + <translation>Procházení historií transakcí</translation> + </message> + <message> + <source>Quit application</source> + <translation>Ukončit aplikaci</translation> + </message> + <message> + <source>&Options...</source> + <translation>&Možnosti...</translation> + </message> + <message> + <source>Change the passphrase used for wallet encryption</source> + <translation>Změnit heslo k šifrování peněženky</translation> + </message> + <message> + <source>Bitcoin</source> + <translation>Bitcoin</translation> + </message> + <message> + <source>&File</source> + <translation>&Soubor</translation> + </message> + <message> + <source>&Settings</source> + <translation>&Nastavení</translation> + </message> + <message> + <source>&Help</source> + <translation>Nápo&věda</translation> + </message> + <message> + <source>Tabs toolbar</source> + <translation>Panely</translation> + </message> + <message> + <source>Up to date</source> + <translation>Aktuální</translation> + </message> + <message> + <source>Catching up...</source> + <translation>Zachytávám...</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Odeslané transakce</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Příchozí transakce</translation> + </message> + <message> + <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> + <translation>Peněženka je <b>zašifrována</b> a momentálně <b>odemčená</b></translation> + </message> + <message> + <source>Wallet is <b>encrypted</b> and currently <b>locked</b></source> + <translation>Peněženka je <b>zašifrována</b> a momentálně <b>uzamčená</b></translation> + </message> +</context> +<context> + <name>ClientModel</name> + </context> +<context> + <name>CoinControlDialog</name> + <message> + <source>Amount:</source> + <translation>Množství:</translation> + </message> + <message> + <source>Amount</source> + <translation>Množství</translation> + </message> + <message> + <source>Date</source> + <translation>Datum</translation> + </message> + <message> + <source>Confirmed</source> + <translation>Potvrzeno</translation> + </message> + <message> + <source>Copy address</source> + <translation>Kopírovat sdresu</translation> + </message> + <message> + <source>Copy label</source> + <translation>Kopírovat popis</translation> + </message> + <message> + <source>(no label)</source> + <translation>(bez popisu)</translation> + </message> + </context> +<context> + <name>EditAddressDialog</name> + <message> + <source>Edit Address</source> + <translation>Upravit adresu</translation> + </message> + <message> + <source>&Label</source> + <translation>&Popisek</translation> + </message> + <message> + <source>&Address</source> + <translation>&Adresa</translation> + </message> + <message> + <source>New receiving address</source> + <translation>Nová adresa pro příjem</translation> + </message> + <message> + <source>New sending address</source> + <translation>Nová adresa k odeslání</translation> + </message> + <message> + <source>Edit receiving address</source> + <translation>Upravit adresu pro příjem</translation> + </message> + <message> + <source>Edit sending address</source> + <translation>Upravit adresu k odeslání</translation> + </message> + <message> + <source>The entered address "%1" is already in the address book.</source> + <translation>Zadaná adresa "%1" se již v seznamu adres nachází.</translation> + </message> + <message> + <source>Could not unlock wallet.</source> + <translation>Nemohu odemknout peněženku</translation> + </message> + <message> + <source>New key generation failed.</source> + <translation>Generování nového klíče selhalo.</translation> + </message> +</context> +<context> + <name>FreespaceChecker</name> + </context> +<context> + <name>HelpMessageDialog</name> + <message> + <source>Usage:</source> + <translation>Použití:</translation> + </message> + </context> +<context> + <name>Intro</name> + </context> +<context> + <name>OpenURIDialog</name> + </context> +<context> + <name>OptionsDialog</name> + <message> + <source>Options</source> + <translation>Možnosti</translation> + </message> + <message> + <source>Map port using &UPnP</source> + <translation>Mapovat port pomocí &UPnP</translation> + </message> + <message> + <source>&Minimize to the tray instead of the taskbar</source> + <translation>&Minimalizovat do systémové lišty (tray) namísto do hlavního panelu</translation> + </message> + <message> + <source>M&inimize on close</source> + <translation>M&inimalizovat při zavření</translation> + </message> + </context> +<context> + <name>OverviewPage</name> + </context> +<context> + <name>PaymentServer</name> + </context> +<context> + <name>PeerTableModel</name> + </context> +<context> + <name>QObject</name> + <message> + <source>Amount</source> + <translation>Množství</translation> + </message> + </context> +<context> + <name>QRImageWidget</name> + </context> +<context> + <name>RPCConsole</name> + <message> + <source>Name</source> + <translation>Jméno</translation> + </message> + </context> +<context> + <name>ReceiveCoinsDialog</name> + <message> + <source>&Label:</source> + <translation>&Popisek:</translation> + </message> + <message> + <source>&Message:</source> + <translation>Zpráva:</translation> + </message> + <message> + <source>Copy label</source> + <translation>Kopírovat popis</translation> + </message> + </context> +<context> + <name>ReceiveRequestDialog</name> + <message> + <source>Address</source> + <translation>Adresa</translation> + </message> + <message> + <source>Amount</source> + <translation>Množství</translation> + </message> + <message> + <source>Label</source> + <translation>Popis</translation> + </message> + <message> + <source>Message</source> + <translation>Zpráva</translation> + </message> + </context> +<context> + <name>RecentRequestsTableModel</name> + <message> + <source>Date</source> + <translation>Datum</translation> + </message> + <message> + <source>Label</source> + <translation>Popis</translation> + </message> + <message> + <source>Message</source> + <translation>Zpráva</translation> + </message> + <message> + <source>Amount</source> + <translation>Množství</translation> + </message> + <message> + <source>(no label)</source> + <translation>(bez popisu)</translation> + </message> + </context> +<context> + <name>SendCoinsDialog</name> + <message> + <source>Amount:</source> + <translation>Množství:</translation> + </message> + <message> + <source>Balance:</source> + <translation>Zůstatek:</translation> + </message> + <message> + <source>The amount to pay must be larger than 0.</source> + <translation>Částka k zaplacení musí být větší než 0.</translation> + </message> + <message> + <source>(no label)</source> + <translation>(bez popisu)</translation> + </message> + </context> +<context> + <name>SendCoinsEntry</name> + <message> + <source>&Label:</source> + <translation>&Popisek:</translation> + </message> + <message> + <source>Message:</source> + <translation>Zpráva:</translation> + </message> + </context> +<context> + <name>ShutdownWindow</name> + </context> +<context> + <name>SignVerifyMessageDialog</name> + </context> +<context> + <name>SplashScreen</name> + <message> + <source>[testnet]</source> + <translation>[testnet]</translation> + </message> +</context> +<context> + <name>TrafficGraphWidget</name> + </context> +<context> + <name>TransactionDesc</name> + <message> + <source>%1/unconfirmed</source> + <translation>%1 potvrzeno</translation> + </message> + <message> + <source>%1 confirmations</source> + <translation>%1 potvrzení</translation> + </message> + <message> + <source>Status</source> + <translation>Stav</translation> + </message> + <message> + <source>Date</source> + <translation>Datum</translation> + </message> + <message> + <source>Message</source> + <translation>Zpráva</translation> + </message> + <message> + <source>Transaction</source> + <translation>Transakce</translation> + </message> + <message> + <source>Amount</source> + <translation>Množství</translation> + </message> + </context> +<context> + <name>TransactionDescDialog</name> + <message> + <source>Transaction details</source> + <translation>Detaily transakce</translation> + </message> + <message> + <source>This pane shows a detailed description of the transaction</source> + <translation>Toto podokno zobrazuje detailní popis transakce</translation> + </message> +</context> +<context> + <name>TransactionTableModel</name> + <message> + <source>Date</source> + <translation>Datum</translation> + </message> + <message> + <source>Type</source> + <translation>Typ</translation> + </message> + <message> + <source>Confirmed (%1 confirmations)</source> + <translation>Potvrzeno (%1 potvrzení)</translation> + </message> + <message> + <source>This block was not received by any other nodes and will probably not be accepted!</source> + <translation>Tento blok nebyl přijat žádným dalším uzlem a pravděpodobně nebude akceptován!</translation> + </message> + <message> + <source>Label</source> + <translation>Popis</translation> + </message> + <message> + <source>Received with</source> + <translation>Přijato s</translation> + </message> + <message> + <source>Sent to</source> + <translation>Odesláno na</translation> + </message> + <message> + <source>Payment to yourself</source> + <translation>Platba sobě samému</translation> + </message> + <message> + <source>Mined</source> + <translation>Vytěženo</translation> + </message> + <message> + <source>Type of transaction.</source> + <translation>Typ transakce.</translation> + </message> + </context> +<context> + <name>TransactionView</name> + <message> + <source>All</source> + <translation>Vše</translation> + </message> + <message> + <source>Today</source> + <translation>Dnes</translation> + </message> + <message> + <source>This week</source> + <translation>Tento týden</translation> + </message> + <message> + <source>This month</source> + <translation>Tento měsíc</translation> + </message> + <message> + <source>Last month</source> + <translation>Minulý měsíc</translation> + </message> + <message> + <source>This year</source> + <translation>Tento rok</translation> + </message> + <message> + <source>Range...</source> + <translation>Rozsah...</translation> + </message> + <message> + <source>Received with</source> + <translation>Přijato s</translation> + </message> + <message> + <source>Sent to</source> + <translation>Odesláno na</translation> + </message> + <message> + <source>To yourself</source> + <translation>Sobě samému</translation> + </message> + <message> + <source>Mined</source> + <translation>Vytěženo</translation> + </message> + <message> + <source>Other</source> + <translation>Ostatní</translation> + </message> + <message> + <source>Min amount</source> + <translation>Min. množství</translation> + </message> + <message> + <source>Copy address</source> + <translation>Kopírovat sdresu</translation> + </message> + <message> + <source>Copy label</source> + <translation>Kopírovat popis</translation> + </message> + <message> + <source>Edit label</source> + <translation>Upravit popis</translation> + </message> + <message> + <source>Comma separated file (*.csv)</source> + <translation>Textový soubor oddělený středníkem (*.csv)</translation> + </message> + <message> + <source>Confirmed</source> + <translation>Potvrzeno</translation> + </message> + <message> + <source>Date</source> + <translation>Datum</translation> + </message> + <message> + <source>Type</source> + <translation>Typ</translation> + </message> + <message> + <source>Label</source> + <translation>Popis</translation> + </message> + <message> + <source>Address</source> + <translation>Adresa</translation> + </message> + <message> + <source>ID</source> + <translation>ID</translation> + </message> + <message> + <source>Range:</source> + <translation>Rozsah:</translation> + </message> + </context> +<context> + <name>UnitDisplayStatusBarControl</name> + </context> +<context> + <name>WalletFrame</name> + </context> +<context> + <name>WalletModel</name> + </context> +<context> + <name>WalletView</name> + </context> +<context> + <name>bitcoin-core</name> + <message> + <source>Options:</source> + <translation>Možnosti:</translation> + </message> + <message> + <source>Loading addresses...</source> + <translation>Načítání adres...</translation> + </message> + <message> + <source>Loading wallet...</source> + <translation>Načítání peněženky...</translation> + </message> + <message> + <source>Done loading</source> + <translation>Načítání dokončeno</translation> + </message> + </context> +</TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_cy.ts b/src/qt/locale/bitcoin_cy.ts index 1b8eb3dc41..c32d236a91 100644 --- a/src/qt/locale/bitcoin_cy.ts +++ b/src/qt/locale/bitcoin_cy.ts @@ -1,4 +1,4 @@ -<TS language="cy" version="2.0"> +<TS language="cy" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -6,13 +6,61 @@ <translation>Creu cyfeiriad newydd</translation> </message> <message> + <source>&New</source> + <translation>&Newydd</translation> + </message> + <message> <source>Copy the currently selected address to the system clipboard</source> <translation>Copio'r cyfeiriad sydd wedi'i ddewis i'r clipfwrdd system</translation> </message> <message> + <source>&Copy</source> + <translation>&Copïo</translation> + </message> + <message> + <source>C&lose</source> + <translation>C&au</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>&Cyfeiriad Copi</translation> + </message> + <message> + <source>&Export</source> + <translation>&Allforio</translation> + </message> + <message> <source>&Delete</source> <translation>&Dileu</translation> </message> + <message> + <source>C&hoose</source> + <translation>&Dewis</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Cyfeiriadau anfon</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Cyfeiriadau derbyn</translation> + </message> + <message> + <source>Copy &Label</source> + <translation>Copïo &Label</translation> + </message> + <message> + <source>&Edit</source> + <translation>&Golygu</translation> + </message> + <message> + <source>Export Address List</source> + <translation>Allforio Rhestr Cyfeiriad</translation> + </message> + <message> + <source>Exporting Failed</source> + <translation>Methodd Allfor</translation> + </message> </context> <context> <name>AddressTableModel</name> @@ -72,6 +120,10 @@ <translation>Cadarnau amgryptiad y waled</translation> </message> <message> + <source>Are you sure you wish to encrypt your wallet?</source> + <translation>Ydych chi'n siwr eich bod chi eisiau amgryptio dy waled di?</translation> + </message> + <message> <source>Wallet encrypted</source> <translation>Waled wedi'i amgryptio</translation> </message> @@ -97,6 +149,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Synchronizing with network...</source> @@ -119,18 +174,70 @@ <translation>Pori hanes trafodion</translation> </message> <message> + <source>E&xit</source> + <translation>A&llanfa</translation> + </message> + <message> <source>Quit application</source> <translation>Gadael rhaglen</translation> </message> <message> + <source>About &Qt</source> + <translation>Ynghylch &Qt</translation> + </message> + <message> <source>&Options...</source> <translation>&Opsiynau</translation> </message> <message> + <source>&Encrypt Wallet...</source> + <translation>&Amgryptio'r waled...</translation> + </message> + <message> + <source>&Change Passphrase...</source> + <translation>&Newid cyfrinymadrodd...</translation> + </message> + <message> + <source>&Sending addresses...</source> + <translation>&Cyfeiriadau anfon...</translation> + </message> + <message> + <source>&Receiving addresses...</source> + <translation>&Cyfeiriadau derbyn...</translation> + </message> + <message> + <source>Open &URI...</source> + <translation>Agor &URI...</translation> + </message> + <message> <source>Change the passphrase used for wallet encryption</source> <translation>Newid y cyfrinymadrodd a ddefnyddiwyd ar gyfer amgryptio'r waled</translation> </message> <message> + <source>Bitcoin</source> + <translation>Bitcoin</translation> + </message> + <message> + <source>Wallet</source> + <translation>Waled</translation> + </message> + <message> + <source>&Send</source> + <translation>&Anfon</translation> + </message> + <message> + <source>&Receive</source> + <translation>&Derbyn</translation> + </message> + <message> + <source>Show information about Bitcoin Core</source> + <translation>Dangos gwybodaeth am Graidd Bitcoin</translation> + </message> + <message> + <source>&Show / Hide</source> + <translation>&Dangos / Cuddio</translation> + </message> + <message> <source>&File</source> <translation>&Ffeil</translation> </message> @@ -147,6 +254,34 @@ <translation>Bar offer tabiau</translation> </message> <message> + <source>Bitcoin Core</source> + <translation>Craidd Bitcoin</translation> + </message> + <message> + <source>&About Bitcoin Core</source> + <translation>&Ynghylch Craidd Bitcoin</translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n awr</numerusform><numerusform>%n awr</numerusform><numerusform>%n awr</numerusform><numerusform>%n awr</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n dydd</numerusform><numerusform>%n dydd</numerusform><numerusform>%n dydd</numerusform><numerusform>%n dydd</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n wythnos</numerusform><numerusform>%n wythnos</numerusform><numerusform>%n wythnos</numerusform><numerusform>%n wythnos</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 blwydd</numerusform><numerusform>%n blwydd</numerusform><numerusform>%n blwydd</numerusform><numerusform>%n blwydd</numerusform></translation> + </message> + <message> <source>Error</source> <translation>Gwall</translation> </message> @@ -167,6 +302,30 @@ <translation>Dal i fyny</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Dyddiad: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Math: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Label: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Cyfeiriad: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Trafodiad a anfonwyd</translation> </message> @@ -189,14 +348,30 @@ <context> <name>CoinControlDialog</name> <message> + <source>Amount:</source> + <translation>Maint</translation> + </message> + <message> <source>Date</source> <translation>Dyddiad</translation> </message> <message> + <source>Copy address</source> + <translation>Cyfeiriad copi</translation> + </message> + <message> + <source>Copy label</source> + <translation>Copïo label</translation> + </message> + <message> <source>(no label)</source> <translation>(heb label)</translation> </message> - </context> + <message> + <source>(change)</source> + <translation>(newid)</translation> + </message> +</context> <context> <name>EditAddressDialog</name> <message> @@ -242,19 +417,55 @@ </context> <context> <name>FreespaceChecker</name> + <message> + <source>name</source> + <translation>enw</translation> + </message> </context> <context> <name>HelpMessageDialog</name> + <message> + <source>Bitcoin Core</source> + <translation>Craidd Bitcoin</translation> + </message> + <message> + <source>About Bitcoin Core</source> + <translation>Ynghylch Craidd Bitcoin</translation> + </message> + <message> + <source>Usage:</source> + <translation>Cynefod:</translation> + </message> </context> <context> <name>Intro</name> <message> + <source>Welcome</source> + <translation>Croeso</translation> + </message> + <message> + <source>Welcome to Bitcoin Core.</source> + <translation>Croeso i Graidd Bitcoin</translation> + </message> + <message> + <source>Bitcoin Core</source> + <translation>Craidd Bitcoin</translation> + </message> + <message> <source>Error</source> <translation>Gwall</translation> </message> </context> <context> <name>OpenURIDialog</name> + <message> + <source>Open URI</source> + <translation>Agor URI</translation> + </message> + <message> + <source>URI:</source> + <translation>URI:</translation> + </message> </context> <context> <name>OptionsDialog</name> @@ -262,6 +473,34 @@ <source>Options</source> <translation>Opsiynau</translation> </message> + <message> + <source>&Network</source> + <translation>&Rhwydwaith</translation> + </message> + <message> + <source>W&allet</source> + <translation>W&aled</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>&Window</source> + <translation>&Ffenestr</translation> + </message> + <message> + <source>&Display</source> + <translation>&Dangos</translation> + </message> </context> <context> <name>OverviewPage</name> @@ -288,6 +527,14 @@ <source>&Information</source> <translation>Gwybodaeth</translation> </message> + <message> + <source>Network</source> + <translation>Rhwydwaith</translation> + </message> + <message> + <source>&Open</source> + <translation>&Agor</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -295,10 +542,18 @@ <source>&Label:</source> <translation>&Label:</translation> </message> + <message> + <source>Copy label</source> + <translation>Copïo label</translation> + </message> </context> <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>&Cyfeiriad Copi</translation> + </message> + <message> <source>Address</source> <translation>Cyfeiriad</translation> </message> @@ -337,6 +592,10 @@ <translation>Anfon arian</translation> </message> <message> + <source>Amount:</source> + <translation>Maint</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Anfon at pobl lluosog ar yr un pryd</translation> </message> @@ -379,6 +638,10 @@ <source>Alt+P</source> <translation>Alt+P</translation> </message> + <message> + <source>Message:</source> + <translation>Neges:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -401,6 +664,14 @@ <context> <name>SplashScreen</name> <message> + <source>Bitcoin Core</source> + <translation>Craidd Bitcoin</translation> + </message> + <message> + <source>The Bitcoin Core developers</source> + <translation>Datblygwyr Graidd Bitcoin</translation> + </message> + <message> <source>[testnet]</source> <translation>[testnet]</translation> </message> @@ -456,6 +727,18 @@ <translation>Eleni</translation> </message> <message> + <source>Copy address</source> + <translation>Cyfeiriad copi</translation> + </message> + <message> + <source>Copy label</source> + <translation>Copïo label</translation> + </message> + <message> + <source>Exporting Failed</source> + <translation>Methodd Allfor</translation> + </message> + <message> <source>Date</source> <translation>Dyddiad</translation> </message> @@ -487,10 +770,18 @@ </context> <context> <name>WalletView</name> + <message> + <source>&Export</source> + <translation>&Allforio</translation> + </message> </context> <context> <name>bitcoin-core</name> <message> + <source>Options:</source> + <translation>Opsiynau:</translation> + </message> + <message> <source>Information</source> <translation>Gwybodaeth</translation> </message> diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index 60b8925e8c..aa2724a1e8 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -1,4 +1,4 @@ -<TS language="da" version="2.0"> +<TS language="da" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,14 +221,25 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/Netmaske</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Bandlyst indtil</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> - <translation>Underskriv &besked …</translation> + <translation>Underskriv &besked…</translation> </message> <message> <source>Synchronizing with network...</source> - <translation>Synkroniserer med netværk …</translation> + <translation>Synkroniserer med netværk…</translation> </message> <message> <source>&Overview</source> @@ -268,31 +279,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> @@ -300,11 +311,11 @@ </message> <message> <source>Importing blocks from disk...</source> - <translation>Importerer blokke fra disken …</translation> + <translation>Importerer blokke fra disken…</translation> </message> <message> <source>Reindexing blocks on disk...</source> - <translation>Genindekserer blokke på disken …</translation> + <translation>Genindekserer blokke på disken…</translation> </message> <message> <source>Send coins to a Bitcoin address</source> @@ -328,7 +339,7 @@ </message> <message> <source>&Verify message...</source> - <translation>&Verificér besked …</translation> + <translation>&Verificér besked…</translation> </message> <message> <source>Bitcoin</source> @@ -428,7 +439,7 @@ </message> <message> <source>No block source available...</source> - <translation>Ingen blokkilde tilgængelig …</translation> + <translation>Ingen blokkilde tilgængelig…</translation> </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> @@ -484,7 +495,7 @@ </message> <message> <source>Catching up...</source> - <translation>Indhenter …</translation> + <translation>Indhenter…</translation> </message> <message> <source>Date: %1 @@ -871,6 +882,34 @@ <source>command-line options</source> <translation>kommandolinjetilvalg</translation> </message> + <message> + <source>UI Options:</source> + <translation>Indstillinger for brugergrænseflade:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Vælg datamappe under opstart (standard: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Vælg sprog; fx "da_DK" (standard: systemsprog)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Start minimeret</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Opsæt SSL-rodcertifikater til betalingsadmodninger (standard: -system-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Vis startskærm under opstart (standard: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Nulstil alle indstillinger, der er foretaget i den grafiske brugerflade</translation> + </message> </context> <context> <name>Intro</name> @@ -914,7 +953,11 @@ <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> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(ud af %n GB behøvet)</numerusform><numerusform>(ud af %n GB behøvet)</numerusform></translation> + </message> +</context> <context> <name>OpenURIDialog</name> <message> @@ -1065,6 +1108,34 @@ <translation>Port for proxyen (fx 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Bruges til at nå knuder via:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Viser om den angivne standard-SOCKS5-proxy bruges til at nå knuder via denne netværkstype.</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Forbind til Bitcoin-netværket gennem en separat SOCKS5-proxy for skjulte Tor-tjenester.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Brug separat SOCKS5-proxy for at nå knuder via skjulte Tor-tjenester.</translation> + </message> + <message> <source>&Window</source> <translation>&Vindue</translation> </message> @@ -1090,7 +1161,7 @@ </message> <message> <source>&Unit to show amounts in:</source> - <translation>&Enhed at vise beløb i:</translation> + <translation>&Enhed, som beløb vises i:</translation> </message> <message> <source>Choose the default subdivision unit to show in the interface and when sending coins.</source> @@ -1102,7 +1173,7 @@ </message> <message> <source>&OK</source> - <translation>&O.k.</translation> + <translation>&Ok</translation> </message> <message> <source>&Cancel</source> @@ -1161,7 +1232,7 @@ </message> <message> <source>Pending:</source> - <translation>Uafgjort:</translation> + <translation>Afventende:</translation> </message> <message> <source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source> @@ -1283,10 +1354,6 @@ <translation>Betalingsanmodning %1 er for stor (%2 byte, %3 byte tilladt).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Beskyttelse mod DoS-angreb via betalingsanmodninger</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Fejl under kommunikation med %1: %2</translation> </message> @@ -1365,7 +1432,7 @@ <name>QRImageWidget</name> <message> <source>&Save Image...</source> - <translation>&Gem billede …</translation> + <translation>&Gem billede…</translation> </message> <message> <source>&Copy Image</source> @@ -1439,6 +1506,18 @@ <translation>Nuværende antal blokke</translation> </message> <message> + <source>Memory Pool</source> + <translation>Hukommelsespulje</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>Aktuelt antal transaktioner</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Hukommelsesforbrug</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>Åbn Bitcoin Cores fejlsøgningslogfil fra den aktuelle datamappe. Dette kan tage nogle få sekunder for store logfiler.</translation> </message> @@ -1455,10 +1534,18 @@ <translation>Andre &knuder</translation> </message> <message> + <source>Banned peers</source> + <translation>Bandlyste knuder</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Vælg en anden knude for at se detaljeret information.</translation> </message> <message> + <source>Whitelisted</source> + <translation>På hvidliste</translation> + </message> + <message> <source>Direction</source> <translation>Retning</translation> </message> @@ -1467,20 +1554,24 @@ <translation>Version</translation> </message> <message> - <source>User Agent</source> - <translation>Brugeragent</translation> + <source>Starting Block</source> + <translation>Startblok</translation> </message> <message> - <source>Services</source> - <translation>Tjenester</translation> + <source>Synced Headers</source> + <translation>Synkroniserede headers</translation> + </message> + <message> + <source>Synced Blocks</source> + <translation>Synkroniserede blokke</translation> </message> <message> - <source>Starting Height</source> - <translation>Starthøjde</translation> + <source>User Agent</source> + <translation>Brugeragent</translation> </message> <message> - <source>Sync Height</source> - <translation>Synkroniseringshøjde</translation> + <source>Services</source> + <translation>Tjenester</translation> </message> <message> <source>Ban Score</source> @@ -1499,16 +1590,16 @@ <translation>Seneste modtagelse</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Byte sendt</translation> + <source>Ping Time</source> + <translation>Ping-tid</translation> </message> <message> - <source>Bytes Received</source> - <translation>Byte modtaget</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>Varigheden af den aktuelt igangværende ping.</translation> </message> <message> - <source>Ping Time</source> - <translation>Ping-tid</translation> + <source>Ping Wait</source> + <translation>Ping-ventetid</translation> </message> <message> <source>Time Offset</source> @@ -1559,6 +1650,34 @@ <translation>Ryd konsol</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>&Afbryd forbindelse til knude</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Bandlys knude i</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &time</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &dag</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &uge</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &år</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>&Fjern bandlysning af knude</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Velkommen til Bitcoin Cores RPC-konsol.</translation> </message> @@ -1587,6 +1706,10 @@ <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(knude-id: %1)</translation> + </message> + <message> <source>via %1</source> <translation>via %1</translation> </message> @@ -1603,12 +1726,16 @@ <translation>Udgående</translation> </message> <message> - <source>Unknown</source> - <translation>Ukendt</translation> + <source>Yes</source> + <translation>Ja</translation> </message> <message> - <source>Fetching...</source> - <translation>Henter …</translation> + <source>No</source> + <translation>Nej</translation> + </message> + <message> + <source>Unknown</source> + <translation>Ukendt</translation> </message> </context> <context> @@ -1710,7 +1837,7 @@ </message> <message> <source>&Save Image...</source> - <translation>&Gem billede …</translation> + <translation>&Gem billede…</translation> </message> <message> <source>Request payment to %1</source> @@ -1792,7 +1919,7 @@ </message> <message> <source>Inputs...</source> - <translation>Inputs …</translation> + <translation>Inputs…</translation> </message> <message> <source>automatically selected</source> @@ -1844,7 +1971,7 @@ </message> <message> <source>Choose...</source> - <translation>Vælg …</translation> + <translation>Vælg…</translation> </message> <message> <source>collapse fee-settings</source> @@ -1884,7 +2011,7 @@ </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> + <translation>(Smart-gebyr er ikke initialiseret endnu. Dette tager typisk nogle få blokke…)</translation> </message> <message> <source>Confirmation time:</source> @@ -1975,8 +2102,8 @@ <translation>Kopiér byttepenge</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Totalbeløb %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Totalbeløb %1</translation> </message> <message> <source>or</source> @@ -2010,15 +2137,15 @@ <source>Payment request expired.</source> <translation>Betalingsanmodning er udløbet.</translation> </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>Betal kun det påkrævede gebyr på %1</translation> + </message> <message numerus="yes"> <source>Estimated to begin confirmation within %n block(s).</source> <translation><numerusform>Bekræftelse estimeres til at begynde inden for %n blok.</numerusform><numerusform>Bekræftelse estimeres til at begynde inden for %n blokke.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Betal kun det minimale gebyr på %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>Modtageradressen er ikke gyldig. Tjek venligst igen.</translation> </message> @@ -2138,7 +2265,7 @@ <name>ShutdownWindow</name> <message> <source>Bitcoin Core is shutting down...</source> - <translation>Bitcoin Core lukker ned …</translation> + <translation>Bitcoin Core lukker ned…</translation> </message> <message> <source>Do not shut down the computer until this window disappears.</source> @@ -2603,7 +2730,7 @@ </message> <message> <source>Range...</source> - <translation>Interval …</translation> + <translation>Interval…</translation> </message> <message> <source>Received with</source> @@ -2650,6 +2777,10 @@ <translation>Kopiér transaktions-ID</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>Kopiér rå transaktion</translation> + </message> + <message> <source>Edit label</source> <translation>Redigér mærkat</translation> </message> @@ -2797,12 +2928,52 @@ <translation>Acceptér kommandolinje- og JSON-RPC-kommandoer</translation> </message> <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>Hvis <category> ikke angives eller hvis <category> = 1, udskriv al fejlretningsinformation.</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Maksimalt totalgebyr (i %s) for brug i en enkelt tegnebogstransaktion; ved at sætte dette for lavt, kan store transaktioner afbrydes (standard: %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Kontrollér venligst, at din computers dato og tid er korrekt! Hvis uret ikke passer, vil Bitcoin Core ikke fungere korrekt.</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>Beskæring er sat under minimumsgrænsen på %d MiB. Brug venligst et større tal.</translation> + </message> + <message> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation>Beskæring: Seneste synkronisering rækker udover beskårne data. Du er nødt til at bruge -reindex (downloade hele blokkæden igen i fald af beskåret knude)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Reducér lagringskravene ved at beskære (slette) gamle blokke. Denne tilstand er ikke kompatibel med -txindex og -rescan. Advarsel: Fortrydelse af denne indstilling kræver gendownload af hele blokkæden. (standard: 0 = slå beskæring af blokke fra, >%u = målstørrelse i MiB der skal bruges på blokfiler)</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>Genindlæsninger er ikke mulige i beskåret tilstand. Du er nødt til at bruge -reindex, hvilket vil downloade hele blokkæden igen.</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Fejl: En alvorlig intern fejl er opstået. Se debug.log for detaljer</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Gebyr (i %s/kB) der skal lægges til de transaktioner du sender (standard: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Beskærer bloklager…</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>Kør i baggrunden som en service, og acceptér kommandoer</translation> </message> <message> - <source>Use the test network</source> - <translation>Brug testnetværket</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>Kunne ikke starte HTTP-server. Se fejlretningslog for detaljer.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2825,18 +2996,14 @@ <translation>Udfør kommando, når en transaktion i tegnebogen ændres (%s i kommandoen erstattes med TxID)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Maksimalt totalt gebyr der kan bruges i en enkelt tegnebogstransaktion. For lav en værdi kan afbryde store transaktioner (standard: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Reducér pladskravene ved at beskære (slette, "prune") gamle blokke. Denne tilstand slår understøttelse af tegnebogen fra og er ikke kompatibel med -txindex. Advarsel: Fortrydelse af denne indstilling kræver download af hele blokkæden igen. (standard: 0 = slå beskæring af blokke fra, >%u = målstørrelse i MiB der skal bruges til blokfiler)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Sæt antallet af scriptverificeringstråde (%u til %d, 0 = auto, <0 = efterlad det antal kernet fri, standard: %d)</translation> </message> <message> + <source>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>Blokdatabasen indeholder en blok, som ser ud til at være fra fremtiden. Dette kan skyldes, at din computers dato og tid ikke er sat korrekt. Genopbyg kun blokdatabasen, hvis du er sikker på, at din computers dato og tid er korrekt</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> @@ -2845,6 +3012,10 @@ <translation>Ikke i stand til at tildele til %s på denne computer. Bitcoin Core kører sansynligvis allerede.</translation> </message> <message> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>Brug UPnP for at konfigurere den lyttende port (standard: 1 under lytning og ingen -proxy)</translation> + </message> + <message> <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> <translation>ADVARSEL: unormalt mange blokke er genereret; %d blokke er modtaget i løbet af de seneste %d timer (%d forventet)</translation> </message> @@ -2853,10 +3024,6 @@ <translation>ADVARSEL: tjek din netværksforbindelse; %d blokke er modtaget i løbet af de seneste %d timer (%d forventet)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Advarsel: -paytxfee er sat meget højt! Dette er det gebyr du vil betale, hvis du sender en transaktion.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Advarsel: Netværket ser ikke ud til at være fuldt ud enige! Enkelte minere ser ud til at opleve problemer.</translation> </message> @@ -2865,10 +3032,6 @@ <translation>Advarsel: Vi ser ikke ud til at være fuldt ud enige med andre knuder! Du kan være nødt til at opgradere, eller andre knuder kan være nødt til at opgradere.</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>Advarsel: fejl under læsning af wallet.dat! Alle nøgler blev læst korrekt, men transaktionsdata eller adressebogsposter kan mangle eller være forkerte.</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>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> @@ -2877,18 +3040,14 @@ <translation>Sæt andre knuder, der forbinder fra den angivne netmaske eller IP, på hvidliste. Kan angives flere gange.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(standard: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool skal være mindst %d MB</translation> </message> <message> <source><category> can be:</source> <translation><kategori> kan være:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Forsøg at genskabe private nøgler fra ødelagt wallet.dat</translation> - </message> - <message> <source>Block creation options:</source> <translation>Blokoprettelsestilvalg:</translation> </message> @@ -2917,6 +3076,22 @@ <translation>Ønsker du at genopbygge blokdatabasen nu?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation>Aktivér offentliggørelse af hash-blok i <address></translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>Aktivér offentliggørelse af hash-transaktion i <address></translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>Aktivér offentliggørelse af rå blok i <address></translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation>Aktivér offentliggørelse af rå transaktion i <address></translation> + </message> + <message> <source>Error initializing block database</source> <translation>Klargøring af blokdatabase mislykkedes</translation> </message> @@ -2933,10 +3108,6 @@ <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> @@ -2945,12 +3116,8 @@ <translation>Lytning på enhver port mislykkedes. Brug -listen=0, hvis du ønsker dette.</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> - <message> <source>Importing...</source> - <translation>Importerer …</translation> + <translation>Importerer…</translation> </message> <message> <source>Incorrect or no genesis block found. Wrong datadir for network?</source> @@ -2961,6 +3128,10 @@ <translation>Ugyldig -onion adresse: "%s"</translation> </message> <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>Hold hukommelsespuljen med transaktioner under <n> megabyte (standard: %u)</translation> + </message> + <message> <source>Not enough file descriptors available.</source> <translation>For få tilgængelige fildeskriptorer.</translation> </message> @@ -2989,16 +3160,32 @@ <translation>Angiv tegnebogsfil (inden for datamappe)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Argument -benchmark understøttes ikke og ignoreres; brug -debug=bench.</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Argument -debugnet understøttes ikke og ignoreres; brug -debug=net.</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>Argument -tor understøttes ikke; brug -onion.</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>User Agent comment (%s) contains unsafe characters.</source> + <translation>Brugeragent-kommentar (%s) indeholder usikre tegn.</translation> + </message> + <message> <source>Verifying blocks...</source> - <translation>Verificerer blokke …</translation> + <translation>Verificerer blokke…</translation> </message> <message> <source>Verifying wallet...</source> - <translation>Verificerer tegnebog …</translation> + <translation>Verificerer tegnebog…</translation> </message> <message> <source>Wallet %s resides outside data directory %s</source> @@ -3017,18 +3204,10 @@ <translation>Du er nødt til at genopbygge databasen ved hjælp af -reindex for at ændre -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importerer blokke fra ekstern blk000??.dat fil</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> <message> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation>Der opstod en fejl under opsætning af RPC-adresse %s port %u for lytning: %s</translation> - </message> - <message> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> <translation>Tildel given adresse og sæt andre knuder, der forbinder til den, på hvidliste. Brug [vært]:port notation for IPv6</translation> </message> @@ -3053,16 +3232,12 @@ <translation>Fejl: Lytning efter indkommende forbindelser mislykkedes (lytning resultarede i fejl %s)</translation> </message> <message> - <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> - <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 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> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Gebyrer (i BTC/Kb) mindre end dette opfattes som nulgebyr for videresendelse (standard: %s)</translation> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>Gebyrer (i %s/kB) mindre end dette opfattes som intet gebyr for videresendelse, mining og oprettelse af transaktioner (standard: %s)</translation> </message> <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> @@ -3077,10 +3252,6 @@ <translation>Maksimal størrelse på data i transaktioner til dataoverførsel, som vi videresender og miner (standard: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>Beskæring opsat under minimumsværdien %d MB. Brug venligst en højere værdi.</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Forespørgsel</translation> </message> @@ -3105,38 +3276,6 @@ <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> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>For at bruge bitcoind eller valgmuligheden -server i bitcoin-qt skal du oprette et rpcpassword i konfigurationsfilen: -%s -Det anbefales, at du bruger følgende tilfældige adgangskode: -rpcuser=bitcoinrpc -rpcpassword=%s -(du behøver ikke at huske adgangskoden) -Brugernavnet og adgangskoden MÅ IKKE være det samme. -Hvis filen ikke eksisterer, opret den da så kun ejeren har læserettigheder. -Det anbefales også at sætte alertnotify, så du får besked omkring problemer; -for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Advarsel: -maxtxfee er sat meget højt! Så store gebyrer kan betales på en enkelt transaktion.</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>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>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> @@ -3154,19 +3293,23 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Activating best chain...</source> - <translation>Aktiverer bedste kæde …</translation> + <translation>Aktiverer bedste kæde…</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>Kan ikke køre med en tegnebog i beskåret tilstand.</translation> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>Videresend altid transaktioner, der modtages fra hvidlistede knuder (standard: %d)</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>Kan ikke løse -whitebind adresse: "%s"</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Forsøg at genskabe private nøgler fra en ødelagt wallet.dat under opstart</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Vælg datamappe ved opstart (standard: 0)</translation> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Opret automatisk skjult Tor-tjeneste (standard: %d)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Kan ikke løse -whitebind adresse: "%s"</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3177,10 +3320,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ophavsret © 2009-%i Udviklerne af Bitcoin Core</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Kunne ikke tolke -rpcbind-værdi %s som en netværksadresse</translation> - </message> - <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Fejl ved indlæsning af wallet.dat: Tegnebog kræver en nyere version af Bitcoin Core</translation> </message> @@ -3189,12 +3328,8 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Fejl under læsning fra database; lukker ned.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Fejl: Ikke understøttet argument -tor fundet, brug -onion.</translation> - </message> - <message> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation>Gebyr (i BTC/kB) som skal føjes til transaktioner, du sender (standard: %s)</translation> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Importerer blokeringer fra ekstern blk000??.dat-fil under opstart</translation> </message> <message> <source>Information</source> @@ -3237,18 +3372,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Videresendelsesvalgmuligheder for knude:</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> - <message> <source>RPC server options:</source> <translation>Tilvalg for RPC-server:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>RPC-understøttelse for HTTP-persistente forbindelser (standard: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Genopbyg blokkædeindeks fra nuværende blk000??.dat-filer ved opstart</translation> </message> @@ -3257,30 +3384,26 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Modtag og vis P2P-netværksadvarsler (standard: %u)</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Send sporings-/fejlsøgningsinformation til konsollen i stedet for debug.log filen</translation> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> + <translation>Reducerer -maxconnections fra %d til %d på grund af systembegrænsninger.</translation> </message> <message> - <source>Send transactions as zero-fee transactions if possible (default: %u)</source> - <translation>Send transaktioner som nul-gebyr-transaktioner hvis muligt (standard: %u)</translation> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Genindlæs blokkæden efter manglende tegnebogstransaktioner under opstart</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Sæt SSL-rodcertifikater for betalingsanmodning (standard: -system-)</translation> + <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 language, for example "de_DE" (default: system locale)</source> - <translation>Angiv sprog, fx "da_DK" (standard: systemlokalitet)</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> <translation>Vis alle tilvalg for fejlsøgning (brug: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Vis opstartsbillede ved opstart (standard: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Formindsk debug.log filen ved klientopstart (standard: 1 hvis ikke -debug)</translation> </message> @@ -3289,10 +3412,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Underskrift af transaktion mislykkedes</translation> </message> <message> - <source>Start minimized</source> - <translation>Start minimeret</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>Transaktionsbeløbet er for lille til at betale gebyret</translation> </message> @@ -3301,6 +3420,14 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Dette er eksperimentelt software.</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>Adgangskode for Tor kontrolport (standard: tom)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>Tor kontrolport, der skal bruges, hvis onion-lytning er slået til (standard: %s)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Transaktionsbeløb er for lavt</translation> </message> @@ -3317,16 +3444,12 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transaktionen er for stor</translation> </message> <message> - <source>UI Options:</source> - <translation>Indstillinger for brugerflade:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Ikke i stand til at tildele til %s på denne computer (bind returnerede fejl %s)</translation> </message> <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> + <source>Upgrade wallet to latest format on startup</source> + <translation>Opgradér tegnebog til seneste format under opstart</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3341,20 +3464,16 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Advarsel</translation> </message> <message> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation>Advarsel: Ikke understøttet argument -benchmark ignoreret, brug -debug=bench.</translation> - </message> - <message> - <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> - <translation>Advarsel: Ikke understøttet argument -debugnet ignoreret, brug -debug=net.</translation> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>Hvorvidt der skal arbejdes i kun-blokke-tilstand (standard: %u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> - <translation>Zapper alle transaktioner fra tegnebog …</translation> + <translation>Zapper alle transaktioner fra tegnebog…</translation> </message> <message> - <source>on startup</source> - <translation>under opstart</translation> + <source>ZeroMQ notification options:</source> + <translation>ZeroMQ-notifikationsindstillinger:</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3369,18 +3488,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Udfør kommando, når den bedste blok ændres (%s i kommandoen erstattes med blokhash)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Opgrader tegnebog til seneste format</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Gennemsøg blokkæden for manglende tegnebogstransaktioner</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Brug OpenSSL (https) for JSON-RPC-forbindelser</translation> - </message> - <message> <source>This help message</source> <translation>Denne hjælpebesked</translation> </message> @@ -3390,7 +3497,7 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Loading addresses...</source> - <translation>Indlæser adresser …</translation> + <translation>Indlæser adresser…</translation> </message> <message> <source>Error loading wallet.dat: Wallet corrupted</source> @@ -3401,6 +3508,26 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = behold metadata for transaktion, fx kontoindehaver og information om betalingsanmodning, 2 = drop metadata for transaktion)</translation> </message> <message> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>-maxtxfee er sat meget højt! Gebyrer så store risikeres betalt på en enkelt transaktion.</translation> + </message> + <message> + <source>-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> + <translation>-paytxfee er sat meget højt! Dette er transaktionsgebyret, som du betaler, hvis du sender en transaktion.</translation> + </message> + <message> + <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>Behold ikke transaktioner i hukommelsespuljen i mere end <n> timer (default: %u)</translation> + </message> + <message> + <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> + <translation>Fejl under læsning af wallet.dat! Alle nøgler blev læst korrekt, men transaktionsdata eller indgange i adressebogen kan mangle eller være ukorrekte.</translation> + </message> + <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>Gebyrer (i %s/kB) mindre end dette opfattes som intet gebyr under oprettelse af transaktioner (standard: %s)</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> @@ -3417,16 +3544,32 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Udskriv fejlsøgningsinformation (standard: %u, angivelse af <kategori> er valgfri)</translation> </message> <message> + <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> + <translation>Understøt filtrering af blokke og transaktioner med Bloom-filtre (standard: %u)</translation> + </message> + <message> + <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> + <translation>Den totale længde på netværksversionsstrengen (%i) overstiger maksimallængden (%i). Reducér antaller af eller størrelsen på uacomments.</translation> + </message> + <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>Prøver at holde udadgående traffik under det givne mål (i MiB pr. 24 timer), 0 = ingen grænse (standard: %d)</translation> + </message> + <message> + <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Argument -socks understøttes ikke. Det er ikke længere muligt at sætte SOCKS-version; kun SOCKS5-proxier understøttes.</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> + <translation>Brug separat SOCS5-proxy for at nå knuder via skjulte Tor-tjenester (standard: %s)</translation> </message> <message> - <source>(default: %s)</source> - <translation>(standard: %s)</translation> + <source>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source> + <translation>Brugernavn og hashet adgangskode for JSON-RPC-forbindelser. Feltet <userpw> er i formatet: <BRUGERNAVN>:<SALT>$<HASH>. Et kanonisk Python-skript inkluderes i share/rpcuser. Dette tilvalg kan angives flere gange</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Accepterede kodninger (standard: %s)</translation> + <source>(default: %s)</source> + <translation>(standard: %s)</translation> </message> <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> @@ -3489,15 +3632,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Videresend ikke-P2SH multisig (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> @@ -3552,7 +3686,7 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Loading block index...</source> - <translation>Indlæser blokindeks …</translation> + <translation>Indlæser blokindeks…</translation> </message> <message> <source>Add a node to connect to and attempt to keep the connection open</source> @@ -3560,7 +3694,7 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Loading wallet...</source> - <translation>Indlæser tegnebog …</translation> + <translation>Indlæser tegnebog…</translation> </message> <message> <source>Cannot downgrade wallet</source> @@ -3572,7 +3706,7 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Rescanning...</source> - <translation>Genindlæser …</translation> + <translation>Genindlæser…</translation> </message> <message> <source>Done loading</source> diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index a50a6e60cb..84de80aff5 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -1,4 +1,4 @@ -<TS language="de" version="2.0"> +<TS language="de" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/Netzmaske</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Gesperrt bis</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -871,6 +882,34 @@ <source>command-line options</source> <translation>Kommandozeilenoptionen</translation> </message> + <message> + <source>UI Options:</source> + <translation>UI Einstellungen:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Datenverzeichnis beim Starten auswählen (Standard: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Sprache einstellen, zum Beispiel "de_DE" (default: system locale)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Minimiert starten</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>SSL-Wurzelzertifikate für Zahlungsanforderungen festlegen (Standard: -system-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Startbildschirm beim Starten anzeigen (Standard: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Setze alle Einstellungen zurück, die über die grafische Oberfläche geändert wurden.</translation> + </message> </context> <context> <name>Intro</name> @@ -1069,6 +1108,34 @@ <translation>Port des Proxies (z.B. 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Benutzt um Gegenstellen zu erreichen über:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Zeigt an, ob der eingegebene Standard SOCKS5 Proxy genutzt wird um Peers mit dem Netzwerktyp zu erreichen.</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Über einen separaten SOCKS5 Proxy für Tor Services mit dem Bitcoint Netzwerk verbinden.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Separaten SOCKS5-Proxy verwenden, um Gegenstellen über versteckte Tor-Dienste zu erreichen:</translation> + </message> + <message> <source>&Window</source> <translation>&Programmfenster</translation> </message> @@ -1287,10 +1354,6 @@ <translation>Zahlungsanforderung %1 ist zu groß (%2 Byte, erlaubt sind %3 Byte).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Zahlungsanforderungs-DoS-Schutz</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Kommunikationsfehler mit %1: %2</translation> </message> @@ -1443,6 +1506,18 @@ <translation>Aktuelle Anzahl Blöcke</translation> </message> <message> + <source>Memory Pool</source> + <translation>Speicherpool</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>Aktuelle Anzahl der Transaktionen</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Speichernutzung</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>Öffnet die "Bitcoin Core"-Debugprotokolldatei aus dem aktuellen Datenverzeichnis. Dies kann bei großen Protokolldateien einige Sekunden dauern.</translation> </message> @@ -1459,10 +1534,18 @@ <translation>&Gegenstellen</translation> </message> <message> + <source>Banned peers</source> + <translation>Gesperrte Peers</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Gegenstelle auswählen, um detaillierte Informationen zu erhalten.</translation> </message> <message> + <source>Whitelisted</source> + <translation>Zugelassene</translation> + </message> + <message> <source>Direction</source> <translation>Richtung</translation> </message> @@ -1471,20 +1554,24 @@ <translation>Version</translation> </message> <message> - <source>User Agent</source> - <translation>User-Agent</translation> + <source>Starting Block</source> + <translation>Start Block</translation> </message> <message> - <source>Services</source> - <translation>Dienste</translation> + <source>Synced Headers</source> + <translation>Synchronisierte Kopfdaten</translation> </message> <message> - <source>Starting Height</source> - <translation>Start-Höhe</translation> + <source>Synced Blocks</source> + <translation>Synchronisierte Blöcke</translation> </message> <message> - <source>Sync Height</source> - <translation>Sync-Höhe</translation> + <source>User Agent</source> + <translation>User-Agent</translation> + </message> + <message> + <source>Services</source> + <translation>Dienste</translation> </message> <message> <source>Ban Score</source> @@ -1503,16 +1590,16 @@ <translation>Letzter Empfang</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Übertragene Byte</translation> + <source>Ping Time</source> + <translation>Pingzeit</translation> </message> <message> - <source>Bytes Received</source> - <translation>Empfangene Byte</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>Die Laufzeit eines aktuell ausstehenden Ping.</translation> </message> <message> - <source>Ping Time</source> - <translation>Pingzeit</translation> + <source>Ping Wait</source> + <translation>Ping Wartezeit</translation> </message> <message> <source>Time Offset</source> @@ -1563,6 +1650,34 @@ <translation>Konsole zurücksetzen</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>Knoten &trennen</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Knoten gebannt für</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &Stunde</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &Tag</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &Woche</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &Jahr</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>&Node entsperren</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Willkommen in der "Bitcoin Core"-RPC-Konsole.</translation> </message> @@ -1591,6 +1706,10 @@ <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(Knotenkennung: %1)</translation> + </message> + <message> <source>via %1</source> <translation>über %1</translation> </message> @@ -1607,12 +1726,16 @@ <translation>ausgehend</translation> </message> <message> - <source>Unknown</source> - <translation>Unbekannt</translation> + <source>Yes</source> + <translation>Ja</translation> </message> <message> - <source>Fetching...</source> - <translation>Aktualisiere...</translation> + <source>No</source> + <translation>Nein</translation> + </message> + <message> + <source>Unknown</source> + <translation>Unbekannt</translation> </message> </context> <context> @@ -1979,8 +2102,8 @@ <translation>Wechselgeld kopieren</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Gesamtbetrag %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Gesamtbetrag %1</translation> </message> <message> <source>or</source> @@ -2014,15 +2137,15 @@ <source>Payment request expired.</source> <translation>Zahlungsanforderung abgelaufen.</translation> </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>Nur die notwendige Gebühr in Höhe von %1 zahlen</translation> + </message> <message numerus="yes"> <source>Estimated to begin confirmation within %n block(s).</source> <translation><numerusform>Voraussichtlicher Beginn der Bestätigung innerhalb von %n Block.</numerusform><numerusform>Voraussichtlicher Beginn der Bestätigung innerhalb von %n Blöcken.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Nur die minimale Gebühr in Höhe von %1 zahlen</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>Die Zahlungsadresse ist ungültig, bitte nochmals überprüfen.</translation> </message> @@ -2654,6 +2777,10 @@ <translation>Transaktions-ID kopieren</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>Kopiere rohe Transaktion</translation> + </message> + <message> <source>Edit label</source> <translation>Bezeichnung bearbeiten</translation> </message> @@ -2801,12 +2928,28 @@ <translation>Kommandozeilen- und JSON-RPC-Befehle annehmen</translation> </message> <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Maximale Gesamtgebühr (in %s) in einer Börsentransaktion; wird dies zu niedrig gesetzten können große Transaktionen abgebrochen werden (Standard: %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Bitte korrigieren Sie die Datums- und Uhrzeiteinstellungen Ihres Computers, da Bitcoin Core ansonsten nicht ordnungsgemäß funktionieren wird.</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Fehler: Ein schwerer interner Fehler ist aufgetreten, siehe debug.log für Details.</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Kürze Blockspeicher...</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>Als Hintergrunddienst ausführen und Befehle annehmen</translation> </message> <message> - <source>Use the test network</source> - <translation>Das Testnetz verwenden</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>Kann HTTP Server nicht starten. Siehe debug log für Details.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2829,14 +2972,6 @@ <translation>Befehl ausführen wenn sich eine Wallet-Transaktion verändert (%s im Befehl wird durch die Transaktions-ID ersetzt)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Maximale Gesamtgebühren je Wallet-Transaktion, ein zu niedriger Wert kann große Transaktionen abbrechen (Standard: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Speicherplatzanforderung durch kürzen (löschen) alter Blöcke reduzieren. Dieser Modus deaktiviert die Wallet-Unterstützung und ist nicht mit -txindex kompatibel. Warnung: Die Umkehr dieser Einstellung erfordert das erneute Herunterladen der gesamten Blockkette. (Standard: 0 = deaktiviert das Kürzen von Blöcken, >%u = Zielgröße in MiB, die für Blockdateien verwendet werden darf)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Maximale Anzahl an Skript-Verifizierungs-Threads festlegen (%u bis %d, 0 = automatisch, <0 = so viele Kerne frei lassen, Standard: %d)</translation> </message> @@ -2857,10 +2992,6 @@ <translation>Warnung: Überprüpfen Sie ihre Netzwerkverbindung, %d Blöcke wurden in den letzten %d Stunden empfangen (%d wurden erwartet).</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Warnung: -paytxfee ist auf einen sehr hohen Wert festgelegt! Dies ist die Gebühr die beim Senden einer Transaktion fällig wird.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Warnung: Das Netzwerk scheint nicht vollständig übereinzustimmen! Einige Miner scheinen Probleme zu haben.</translation> </message> @@ -2869,10 +3000,6 @@ <translation>Warnung: Wir scheinen nicht vollständig mit unseren Gegenstellen übereinzustimmen! Sie oder die anderen Knoten müssen unter Umständen Ihre Client-Software aktualisieren.</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>Warnung: Lesen von wallet.dat fehlgeschlagen! Alle Schlüssel wurden korrekt gelesen, Transaktionsdaten bzw. Adressbucheinträge fehlen aber möglicherweise oder sind inkorrekt.</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>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> @@ -2881,18 +3008,14 @@ <translation>Gegenstellen die sich von der angegebenen Netzmaske oder IP-Adresse aus verbinden immer zulassen. Kann mehrmals angegeben werden.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(Standard: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool muss mindestens %d MB betragen</translation> </message> <message> <source><category> can be:</source> <translation><category> kann sein:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Versuchen, private Schlüssel aus einer beschädigten wallet.dat wiederherzustellen</translation> - </message> - <message> <source>Block creation options:</source> <translation>Blockerzeugungsoptionen:</translation> </message> @@ -2921,6 +3044,18 @@ <translation>Möchten Sie die Blockdatenbank jetzt neu aufbauen?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation>Aktiviere das Veröffentlichen des Hash-Blocks in <address></translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>Aktiviere das Veröffentlichen der Hash-Transaktion in <address></translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>Aktiviere das Veröffentlichen des Raw-Blocks in <address></translation> + </message> + <message> <source>Error initializing block database</source> <translation>Fehler beim Initialisieren der Blockdatenbank</translation> </message> @@ -2937,10 +3072,6 @@ <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> @@ -2949,10 +3080,6 @@ <translation>Fehler, es konnte kein Port abgehört werden. Wenn dies so gewünscht wird -listen=0 verwenden.</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> - <message> <source>Importing...</source> <translation>Importiere...</translation> </message> @@ -2993,6 +3120,18 @@ <translation>Wallet-Datei angeben (innerhalb des Datenverzeichnisses)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Nicht unterstütztes Argument -benchmark wurde ignoriert, bitte -debug=bench verwenden.</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Nicht unterstütztes Argument -debugnet wurde ignoriert, bitte -debug=net verwenden.</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>Nicht unterstütztes Argument -tor gefunden, bitte -onion verwenden.</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> @@ -3021,18 +3160,10 @@ <translation>Sie müssen die Datenbank mit Hilfe von -reindex neu aufbauen, um -txindex zu verändern</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Blöcke aus externer Datei blk000??.dat importieren</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-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> @@ -3057,18 +3188,10 @@ <translation>Fehler: Abhören nach eingehenden Verbindungen fehlgeschlagen (listen meldete Fehler %s)</translation> </message> <message> - <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> - <translation>Fehler: Nicht unterstütztes Argument -socks gefunden. Das Festlegen der SOCKS-Version ist nicht mehr möglich, nur noch SOCKS5-Proxies werden unterstützt.</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>Befehl ausführen wenn ein relevanter Alarm empfangen wird oder wir einen wirklich langen Fork entdecken (%s im Befehl wird durch die Nachricht ersetzt)</translation> </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 Weiterleitung als gebührenfrei angesehen (Standard: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Wenn -paytxfee nicht festgelegt wurde Gebühren einschließen, so dass mit der Bestätigung von Transaktionen im Schnitt innerhalb von n Blöcken begonnen wird (Standard: %u)</translation> </message> @@ -3081,10 +3204,6 @@ <translation>Maximale Datengröße in "Data Carrier"-Transaktionen die weitergeleitet und erarbeitet werden (Standard: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>Kürzungsmodus wurde kleiner als das Minimum in Höhe von %d MiB konfiguriert. Bitte verwenden Sie einen größeren Wert.</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Adressen von Gegenstellen via DNS-Namensauflösung finden, falls zu wenige Adressen verfügbar sind (Standard: 1, außer bei -connect)</translation> </message> @@ -3109,38 +3228,6 @@ <translation>Dieses Produkt enthält Software, die vom OpenSSL-Projekt zur Verwendung im OpenSSL-Toolkit <https://www.openssl.org/> entwickelt wird, sowie von Eric Young geschriebene kryptographische Software und von Thomas Bernard geschriebene UPnP-Software.</translation> </message> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>Um bitcoind oder die Option -server mit bitcoin-qt verwenden zu können, müssen Sie rpcpassword in der Konfigurationsdatei angeben: -%s -Es wird empfohlen das folgende Zufallspasswort zu verwenden. -rpcuser=bitcoinrpc -rpcpassword=%s -(Sie müssen sich dieses Passwort nicht merken!) -Der Benutzername und das Passwort dürfen NICHT identisch sein. -Falls die Konfigurationsdatei nicht existiert, erzeugen Sie diese bitte mit Leserechten nur für den Dateibesitzer. -Es wird ebenfalls empfohlen alertnotify anzugeben, um im Problemfall benachrichtigt zu werden. -Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Warnung: -maxtxfee ist auf einen sehr hohen Wert festgelegt! Gebühren dieser Höhe könnten für eine einzelne Transaktion bezahlt werden.</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>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> @@ -3161,16 +3248,16 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aktiviere beste Blockkette...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>Eine Wallet kann im Kürzungsmodus nicht verwendet werden.</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Versuchen, private Schlüssel beim Starten aus einer beschädigten wallet.dat wiederherzustellen</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>Kann Adresse in -whitebind nicht auflösen: '%s'</translation> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Automatisch versteckten Tor-Dienst erstellen (Standard: %d)</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Datenverzeichnis beim Starten auswählen (Standard: 0)</translation> + <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> @@ -3181,10 +3268,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Urheberrecht (C) 2009-%i Die "Bitcoin Core"-Entwickler</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Der Wert %s von -rpcbind wurde nicht als Netzwerkadresse erkannt</translation> - </message> - <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Fehler beim Laden von wallet.dat: Wallet benötigt neuere Version von Bitcoin Core</translation> </message> @@ -3193,12 +3276,8 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Fehler beim lesen der Datenbank, Ausführung wird beendet.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <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> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Blöcke beim Starten aus externer Datei blk000??.dat importieren</translation> </message> <message> <source>Information</source> @@ -3241,18 +3320,10 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Knoten-Weiterleitungsoptionen:</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> - <message> <source>RPC server options:</source> <translation>RPC-Serveroptionen:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>Unterstützung für persistente HTTP-Verbindungen bei RPC (Standard: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Blockkettenindex aus aktuellen Dateien blk000??.dat beim Starten wiederaufbauen</translation> </message> @@ -3261,6 +3332,10 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>P2P-Netzwerk-Alarme empfangen und anzeigen (Standard: %u)</translation> </message> <message> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Blockkette beim Starten erneut nach fehlenden Wallet-Transaktionen durchsuchen</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> @@ -3269,22 +3344,10 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transaktionen, wenn möglich, als gebührenfreie Transaktion senden (Standard: %u)</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>SSL-Wurzelzertifikate für Zahlungsanforderungen festlegen (Standard: -system-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Sprache festlegen, z.B. "de_DE" (Standard: Systemstandard)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Zeige alle Debuggingoptionen (Benutzung: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Startbildschirm beim Starten anzeigen (Standard: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Protokolldatei debug.log beim Starten des Clients kürzen (Standard: 1, wenn kein -debug)</translation> </message> @@ -3293,10 +3356,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Signierung der Transaktion fehlgeschlagen</translation> </message> <message> - <source>Start minimized</source> - <translation>Minimiert starten</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>Der Transaktionsbetrag ist zu niedrig, um die Gebühr zu bezahlen.</translation> </message> @@ -3305,6 +3364,14 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Dies ist experimentelle Software.</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>TOR Kontrollport Passwort (Standard: leer)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>Zu benutzender TOR Kontrollport wenn Onion Auflistung aktiv ist (Standard: %s)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Transaktionsbetrag zu niedrig</translation> </message> @@ -3321,16 +3388,12 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transaktion zu groß</translation> </message> <message> - <source>UI Options:</source> - <translation>Benutzeroberflächenoptionen:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Kann auf diesem Computer nicht an %s binden (bind meldete Fehler %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: 1, wenn abgehört wird)</translation> + <source>Upgrade wallet to latest format on startup</source> + <translation>Wallet beim Starten auf das neueste Format aktualisieren</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3345,20 +3408,16 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Warnung</translation> </message> <message> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation>Warnung: Nicht unterstütztes Argument -benchmark wurde ignoriert, bitte -debug=bench verwenden.</translation> - </message> - <message> - <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> - <translation>Warnung: Nicht unterstütztes Argument -debugnet wurde ignoriert, bitte -debug=net verwenden.</translation> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>Legt fest ob nur Blöcke Modus aktiv sein soll (Standard: %u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> <translation>Lösche alle Transaktionen aus Wallet...</translation> </message> <message> - <source>on startup</source> - <translation>beim Starten</translation> + <source>ZeroMQ notification options:</source> + <translation>ZeroMQ-Benachrichtigungsoptionen:</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3373,18 +3432,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Befehl ausführen wenn der beste Block wechselt (%s im Befehl wird durch den Hash des Blocks ersetzt)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Wallet auf das neueste Format aktualisieren</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Blockkette erneut nach fehlenden Wallet-Transaktionen durchsuchen</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>OpenSSL (https) für JSON-RPC-Verbindungen verwenden</translation> - </message> - <message> <source>This help message</source> <translation>Dieser Hilfetext</translation> </message> @@ -3405,6 +3452,22 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = TX-Metadaten wie z.B. Accountbesitzer und Zahlungsanforderungsinformationen behalten, 2 = TX-Metadaten verwerfen)</translation> </message> <message> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>-maxtxfee ist auf einen sehr hohen Wert festgelegt! Gebühren dieser Höhe könnten für eine einzelne Transaktion bezahlt werden.</translation> + </message> + <message> + <source>-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> + <translation>-paytxfee ist auf einen sehr hohen Wert festgelegt! Dies ist die Gebühr die beim Senden einer Transaktion fällig wird.</translation> + </message> + <message> + <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>Die Transaktion nicht länger im Speicherpool behalten als <n> Stunden (Standard: %u)</translation> + </message> + <message> + <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> + <translation>Lesen von wallet.dat fehlgeschlagen! Alle Schlüssel wurden korrekt gelesen, Transaktionsdaten bzw. Adressbucheinträge fehlen aber möglicherweise oder sind inkorrekt.</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> @@ -3421,6 +3484,14 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Debugginginformationen ausgeben (Standard: %u, <category> anzugeben ist optional)</translation> </message> <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>Versucht ausgehenden Datenverkehr unter dem gegebenen Wert zu halten (in MiB pro 24h), 0 = kein Limit (default: %d)</translation> + </message> + <message> + <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Nicht unterstütztes Argument -socks gefunden. Das Festlegen der SOCKS-Version ist nicht mehr möglich, nur noch SOCKS5-Proxies werden unterstützt.</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> @@ -3429,10 +3500,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <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> @@ -3461,6 +3528,10 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation><port> nach JSON-RPC-Verbindungen abhören (Standard: %u oder Testnetz: %u)</translation> </message> <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation><port> nach 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> @@ -3489,14 +3560,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Nicht-"P2SH-Multisig" weiterleiten (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> diff --git a/src/qt/locale/bitcoin_el.ts b/src/qt/locale/bitcoin_el.ts new file mode 100644 index 0000000000..6777961cbc --- /dev/null +++ b/src/qt/locale/bitcoin_el.ts @@ -0,0 +1,321 @@ +<TS language="el" version="2.1"> +<context> + <name>AddressBookPage</name> + <message> + <source>Create a new address</source> + <translation>Δημιουργία νέου λογαριασμού</translation> + </message> + </context> +<context> + <name>AddressTableModel</name> + <message> + <source>Label</source> + <translation>Ετικέτα</translation> + </message> + <message> + <source>Address</source> + <translation>Διεύθυνση</translation> + </message> + </context> +<context> + <name>AskPassphraseDialog</name> + <message> + <source>Enter passphrase</source> + <translation>Εισάγετε συνθηματικό</translation> + </message> + <message> + <source>New passphrase</source> + <translation>Νέο συνθηματικό</translation> + </message> + <message> + <source>Repeat new passphrase</source> + <translation>Επαναλάβετε νέο συνθηματικό</translation> + </message> + <message> + <source>Change passphrase</source> + <translation>Αλλαγή συνθηματικού</translation> + </message> + </context> +<context> + <name>BanTableModel</name> + </context> +<context> + <name>BitcoinGUI</name> + <message> + <source>Quit application</source> + <translation>Κλείσιμο εφαρμογής</translation> + </message> + <message> + <source>Wallet</source> + <translation>Πορτοφόλι</translation> + </message> + <message> + <source>Error</source> + <translation>Σφάλμα</translation> + </message> + </context> +<context> + <name>ClientModel</name> + </context> +<context> + <name>CoinControlDialog</name> + <message> + <source>Date</source> + <translation>Ημερομηνία</translation> + </message> + <message> + <source>Copy address</source> + <translation>Αντιγραφή διεύθυνσης</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Αντιγραφή ποσού</translation> + </message> + <message> + <source>Copy quantity</source> + <translation>Αντιγραφή ποσότητας</translation> + </message> + <message> + <source>Copy change</source> + <translation>Αντιγραφή αλλαγής</translation> + </message> + </context> +<context> + <name>EditAddressDialog</name> + <message> + <source>&Label</source> + <translation>Ετικέτα</translation> + </message> + <message> + <source>&Address</source> + <translation>Διεύθυνση</translation> + </message> + </context> +<context> + <name>FreespaceChecker</name> + </context> +<context> + <name>HelpMessageDialog</name> + <message> + <source>version</source> + <translation>έκδοση</translation> + </message> + </context> +<context> + <name>Intro</name> + <message> + <source>Welcome</source> + <translation>Καλώς Ήλθατε</translation> + </message> + <message> + <source>Error</source> + <translation>Σφάλμα</translation> + </message> + </context> +<context> + <name>OpenURIDialog</name> + </context> +<context> + <name>OptionsDialog</name> + <message> + <source>W&allet</source> + <translation>Πορτοφόλι</translation> + </message> + </context> +<context> + <name>OverviewPage</name> + </context> +<context> + <name>PaymentServer</name> + </context> +<context> + <name>PeerTableModel</name> + </context> +<context> + <name>QObject</name> + </context> +<context> + <name>QRImageWidget</name> + </context> +<context> + <name>RPCConsole</name> + <message> + <source>Services</source> + <translation>Υπηρεσίες</translation> + </message> + </context> +<context> + <name>ReceiveCoinsDialog</name> + <message> + <source>Remove</source> + <translation>Αφαίρεση</translation> + </message> + <message> + <source>Copy message</source> + <translation>Αντιγραφή μηνύματος</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Αντιγραφή ποσού</translation> + </message> +</context> +<context> + <name>ReceiveRequestDialog</name> + <message> + <source>Address</source> + <translation>Διεύθυνση</translation> + </message> + <message> + <source>Label</source> + <translation>Ετικέτα</translation> + </message> + <message> + <source>Message</source> + <translation>Μήνυμα</translation> + </message> + </context> +<context> + <name>RecentRequestsTableModel</name> + <message> + <source>Date</source> + <translation>Ημερομηνία</translation> + </message> + <message> + <source>Label</source> + <translation>Ετικέτα</translation> + </message> + <message> + <source>Message</source> + <translation>Μήνυμα</translation> + </message> + <message> + <source>(no message)</source> + <translation>(κανένα μήνυμα)</translation> + </message> + </context> +<context> + <name>SendCoinsDialog</name> + <message> + <source>Insufficient funds!</source> + <translation>Κεφάλαια μη επαρκή</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Συνίσταται:</translation> + </message> + <message> + <source>Copy quantity</source> + <translation>Αντιγραφή ποσότητας</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Αντιγραφή ποσού</translation> + </message> + <message> + <source>Copy change</source> + <translation>Αντιγραφή αλλαγής</translation> + </message> + </context> +<context> + <name>SendCoinsEntry</name> + <message> + <source>Message:</source> + <translation>Μήνυμα:</translation> + </message> + </context> +<context> + <name>ShutdownWindow</name> + </context> +<context> + <name>SignVerifyMessageDialog</name> + </context> +<context> + <name>SplashScreen</name> + </context> +<context> + <name>TrafficGraphWidget</name> + </context> +<context> + <name>TransactionDesc</name> + <message> + <source>Date</source> + <translation>Ημερομηνία</translation> + </message> + <message> + <source>Message</source> + <translation>Μήνυμα</translation> + </message> + </context> +<context> + <name>TransactionDescDialog</name> + </context> +<context> + <name>TransactionTableModel</name> + <message> + <source>Date</source> + <translation>Ημερομηνία</translation> + </message> + <message> + <source>Label</source> + <translation>Ετικέτα</translation> + </message> + </context> +<context> + <name>TransactionView</name> + <message> + <source>Copy address</source> + <translation>Αντιγραφή διεύθυνσης</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Αντιγραφή ποσού</translation> + </message> + <message> + <source>Date</source> + <translation>Ημερομηνία</translation> + </message> + <message> + <source>Label</source> + <translation>Ετικέτα</translation> + </message> + <message> + <source>Address</source> + <translation>Διεύθυνση</translation> + </message> + </context> +<context> + <name>UnitDisplayStatusBarControl</name> + </context> +<context> + <name>WalletFrame</name> + </context> +<context> + <name>WalletModel</name> + </context> +<context> + <name>WalletView</name> + </context> +<context> + <name>bitcoin-core</name> + <message> + <source>Insufficient funds</source> + <translation>Κεφάλαια μη επαρκή</translation> + </message> + <message> + <source>Loading wallet...</source> + <translation>Φόρτωση πορτοφολιού...</translation> + </message> + <message> + <source>Rescanning...</source> + <translation>Επανάληψη σάρωσης</translation> + </message> + <message> + <source>Done loading</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_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts index 8a0958a7bd..90c27c4394 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.0"> +<TS language="el_GR" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -214,6 +214,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -452,6 +455,36 @@ <translation>Ενημέρωση...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Ημερομηνία: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Ποσό: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Τύπος: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Ετικέτα: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Διεύθυνση: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Η συναλλαγή απεστάλη</translation> </message> @@ -650,6 +683,22 @@ <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 label turns red if the priority is smaller than "medium".</source> + <translation>Αυτή η ετικέτα γίνεται κόκκινη αν η προτεραιότητα είναι μικρότερη από "μεσαία".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Αυτή η ετικέτα γίνεται κόκκινη αν οποιοσδήποτε παραλήπτης λάβει ποσό μικρότερο από %1.</translation> + </message> + <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>Μπορεί να διαφέρει +/- %1 Satoshi (ες) ανά εγγραφή.</translation> + </message> + <message> <source>yes</source> <translation>ναι</translation> </message> @@ -662,6 +711,10 @@ <translation>Ελάχιστο χρεώσιμο ποσό τουλάχιστο %1 ανα kB</translation> </message> <message> + <source>Can vary +/- 1 byte per input.</source> + <translation>Μπορεί να διαφέρει +/- 1 byte ανά εγγραφή.</translation> + </message> + <message> <source>Transactions with higher priority are more likely to get included into a block.</source> <translation>Συναλλαγές με υψηλότερη προτεραιότητα είναι πιο πιθανό να περιλαμβάνονται σε ένα μπλοκ.</translation> </message> @@ -787,7 +840,7 @@ <source>command-line options</source> <translation>επιλογής γραμμής εντολών</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -826,7 +879,15 @@ <source>Error</source> <translation>Σφάλμα</translation> </message> - </context> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB ελεύθερου χώρου διαθέσιμα</numerusform><numerusform>%n GB ελεύθερου χώρου διαθέσιμα</numerusform></translation> + </message> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(από το %n GB που απαιτείται)</numerusform><numerusform>(από τα %n GB που απαιτούνται)</numerusform></translation> + </message> +</context> <context> <name>OpenURIDialog</name> <message> @@ -885,6 +946,10 @@ <translation>Διεύθυνση IP του διαμεσολαβητή (π.χ. 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Ελαχιστοποίηση αντί για έξοδο κατά το κλείσιμο του παραθύρου. Όταν αυτή η επιλογή είναι ενεργοποιημένη, η εφαρμογή θα κλείνει μόνο αν επιλεχθεί η Έξοδος στο μενού.</translation> + </message> + <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <translation>URLs από τρίτους (π.χ. ένας εξερευνητής μπλοκ) τα οποία εμφανίζονται στην καρτέλα συναλλαγών ως στοιχεία μενού. Το %s στα URL αντικαθιστάται από την τιμή της κατατεμαχισμένης συναλλαγής.</translation> </message> @@ -1316,14 +1381,6 @@ <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> @@ -1340,14 +1397,6 @@ <translation>Τελευταία λήψη</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Σταλθέντα bytes</translation> - </message> - <message> - <source>Bytes Received</source> - <translation>Ληφθέντα bytes</translation> - </message> - <message> <source>Ping Time</source> <translation>Χρόνος καθυστέρησης</translation> </message> @@ -1439,10 +1488,6 @@ <source>Unknown</source> <translation>Άγνωστο(α)</translation> </message> - <message> - <source>Fetching...</source> - <translation>Ανάκτηση...</translation> - </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -1656,6 +1701,14 @@ <translation>ανά kilobyte</translation> </message> <message> + <source>Hide</source> + <translation>Απόκρυψη</translation> + </message> + <message> + <source>total at least</source> + <translation>συνολικά τουλάχιστον</translation> + </message> + <message> <source>Recommended:</source> <translation>Προτεινόμενο: </translation> </message> @@ -1748,10 +1801,6 @@ <translation>Αντιγραφή των ρέστων</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Ολικό Ποσό %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>ή</translation> </message> @@ -2482,10 +2531,6 @@ <translation>Εκτέλεση στο παρασκήνιο κι αποδοχή εντολών</translation> </message> <message> - <source>Use the test network</source> - <translation>Χρήση του δοκιμαστικού δικτύου</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Να δέχεσαι συνδέσεις από έξω(προεπιλογή:1)</translation> </message> @@ -2502,26 +2547,10 @@ <translation>Αυτό είναι ένα προ-τεστ κυκλοφορίας - χρησιμοποιήστε το με δική σας ευθύνη - δεν χρησιμοποιείτε για εξόρυξη ή για αλλες εφαρμογές</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: 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> - <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 ειναι διεφθαρμένο, τα δεδομένα σώζονται ! Original wallet.dat αποθηκεύονται ως wallet.{timestamp}.bak στο %s . Αν το υπόλοιπο του ή τις συναλλαγές σας, είναι λάθος θα πρέπει να επαναφέρετε από ένα αντίγραφο ασφαλείας</translation> </message> <message> - <source>(default: 1)</source> - <translation>(προεπιλογή: 1)</translation> - </message> - <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Προσπάθεια για ανακτησει ιδιωτικων κλειδιων από ενα διεφθαρμένο αρχειο wallet.dat </translation> - </message> - <message> <source>Block creation options:</source> <translation>Αποκλεισμός επιλογων δημιουργίας: </translation> </message> @@ -2558,10 +2587,6 @@ <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> @@ -2586,6 +2611,10 @@ <translation>Μόνο σύνδεση σε κόμβους του δικτύου <net> (ipv4, ipv6 ή onion)</translation> </message> <message> + <source>Set maximum block size in bytes (default: %d)</source> + <translation>Ορίστε το μέγιστο μέγεθος block σε bytes (προεπιλογή: %d)</translation> + </message> + <message> <source>Specify wallet file (within data directory)</source> <translation>Επιλέξτε αρχείο πορτοφολιού (μέσα απο κατάλογο δεδομένων)</translation> </message> @@ -2606,28 +2635,16 @@ <translation>Επιλογές πορτοφολιού:</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Εισαγωγή μπλοκ από εξωτερικό αρχείο blk000?.dat</translation> - </message> - <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Αδυναμία κλειδώματος του φακέλου δεδομένων %s. Πιθανώς το Bitcoin να είναι ήδη ενεργό.</translation> </message> <message> - <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> - <translation>Προειδοποίηση: Παρακαλώ ελέγξτε ότι η ημερομηνία και ώρα του υπολογιστή σας είναι σωστά ρυθμισμένες! Εάν το ρολόι σας είναι λάθος το Bitcoin Core δεν θα λειτουργήσει σωστά. </translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Επιλογή φακέλου δεδομένων στην εκκίνηση (προεπιλεγμένο: 0)</translation> - </message> - <message> <source>Connect through SOCKS5 proxy</source> <translation>Σύνδεση μέσω διαμεσολαβητή SOCKS5</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Δεν μπόρεσε να αναλυθεί η παράμετρος -rpcbind value %s ως διεύθυνση δικτύου</translation> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Πνευματικά δικαιώματα 2009-%i Οι προγραμματιστές του Bitcoin Core</translation> </message> <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> @@ -2638,10 +2655,6 @@ <translation>Σφάλμα ανάγνωσης από τη βάση δεδομένων, γίνεται τερματισμός.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Σφάλμα: Μη συμβατή παράμετρος -tor. Χρησιμοποιήσε την παράμετρο -onion</translation> - </message> - <message> <source>Information</source> <translation>Πληροφορία</translation> </message> @@ -2650,6 +2663,10 @@ <translation>Η εκκίνηση ελέγχου ορθότητας απέτυχε. Γίνεται τερματισμός του Bitcoin Core.</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Μη έγκυρο ποσό για την παράμετρο -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s'</translation> </message> @@ -2662,10 +2679,6 @@ <translation>Επιλογές αναμετάδοσης κόμβου: </translation> </message> <message> - <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> - <translation>Ρυθμίσεις SSL: (ανατρέξτε στο Bitcoin Wiki για οδηγίες ρυθμίσεων SSL)</translation> - </message> - <message> <source>RPC server options:</source> <translation>Επιλογές διακομιστή RPC:</translation> </message> @@ -2674,22 +2687,10 @@ <translation>Αποστολή πληροφοριών εντοπισμού σφαλμάτων στην κονσόλα αντί του αρχείου debug.log</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Ορίστε SSL root certificates για αίτηση πληρωμής (default: -system-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Όρισε γλώσσα, για παράδειγμα "de_DE"(προεπιλογή:τοπικές ρυθμίσεις)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Προβολή όλων των επιλογών εντοπισμού σφαλμάτων (χρήση: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Εμφάνισε την οθόνη εκκίνησης κατά την εκκίνηση(προεπιλογή:1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Συρρίκνωση του αρχείο debug.log κατα την εκκίνηση του πελάτη (προεπιλογή: 1 όταν δεν-debug)</translation> </message> @@ -2698,10 +2699,6 @@ <translation>Η υπογραφή συναλλαγής απέτυχε </translation> </message> <message> - <source>Start minimized</source> - <translation>Έναρξη ελαχιστοποιημένο</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Η εφαρμογή είναι σε πειραματικό στάδιο.</translation> </message> @@ -2718,10 +2715,6 @@ <translation>Η συναλλαγή ειναι πολύ μεγάλη </translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Χρησιμοποίηση του UPnP για την χρήση της πόρτας αναμονής (προεπιλογή:1)</translation> - </message> - <message> <source>Username for JSON-RPC connections</source> <translation>Όνομα χρήστη για τις συνδέσεις JSON-RPC</translation> </message> @@ -2734,10 +2727,6 @@ <translation>Μεταφορά όλων των συναλλαγών απο το πορτοφόλι</translation> </message> <message> - <source>on startup</source> - <translation>κατά την εκκίνηση</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>Το αρχειο wallet.dat ειναι διεφθαρμένο, η διάσωση απέτυχε</translation> </message> @@ -2750,18 +2739,6 @@ <translation>Εκτέλεσε την εντολή όταν το καλύτερο μπλοκ αλλάξει(%s στην εντολή αντικαθίσταται από το hash του μπλοκ)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Αναβάθμισε το πορτοφόλι στην τελευταία έκδοση</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Επανέλεγχος της αλυσίδας μπλοκ για απούσες συναλλαγές</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Χρήση του OpenSSL (https) για συνδέσεις JSON-RPC</translation> - </message> - <message> <source>This help message</source> <translation>Αυτό το κείμενο βοήθειας</translation> </message> @@ -2810,8 +2787,12 @@ <translation>Δεν είναι έγκυρη η διεύθυνση διαμεσολαβητή: '%s'</translation> </message> <message> - <source>Server certificate file (default: %s)</source> - <translation>Αρχείο πιστοποιητικού του διακομιστή (προεπιλογή: %s)</translation> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Μέγιστες αριθμός συνδέσεων με τους peers <n> (προεπιλογή: %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> diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 3ebb4d0bf6..00411741f1 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -299,17 +299,17 @@ <context> <name>BitcoinGUI</name> <message> - <location filename="../bitcoingui.cpp" line="+324"/> + <location filename="../bitcoingui.cpp" line="+335"/> <source>Sign &message...</source> <translation>Sign &message...</translation> </message> <message> - <location line="+353"/> + <location line="+362"/> <source>Synchronizing with network...</source> <translation>Synchronizing with network...</translation> </message> <message> - <location line="-429"/> + <location line="-438"/> <source>&Overview</source> <translation>&Overview</translation> </message> @@ -389,12 +389,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+180"/> + <location line="+183"/> <source>Bitcoin Core client</source> <translation type="unfinished"></translation> </message> <message> - <location line="+163"/> + <location line="+169"/> <source>Importing blocks from disk...</source> <translation>Importing blocks from disk...</translation> </message> @@ -404,7 +404,7 @@ <translation>Reindexing blocks on disk...</translation> </message> <message> - <location line="-427"/> + <location line="-436"/> <source>Send coins to a Bitcoin address</source> <translation>Send coins to a Bitcoin address</translation> </message> @@ -434,12 +434,12 @@ <translation>&Verify message...</translation> </message> <message> - <location line="+450"/> + <location line="+459"/> <source>Bitcoin</source> <translation>Bitcoin</translation> </message> <message> - <location line="-660"/> + <location line="-669"/> <source>Wallet</source> <translation>Wallet</translation> </message> @@ -484,7 +484,7 @@ <translation>Verify messages to ensure they were signed with specified Bitcoin addresses</translation> </message> <message> - <location line="+53"/> + <location line="+56"/> <source>&File</source> <translation>&File</translation> </message> @@ -504,7 +504,7 @@ <translation>Tabs toolbar</translation> </message> <message> - <location line="-311"/> + <location line="-314"/> <source>Bitcoin Core</source> <translation type="unfinished">Bitcoin Core</translation> </message> @@ -549,7 +549,7 @@ <translation type="unfinished"></translation> </message> <message numerus="yes"> - <location line="+320"/> + <location line="+329"/> <source>%n active connection(s) to Bitcoin network</source> <translation> <numerusform>%n active connection to Bitcoin network</numerusform> @@ -701,7 +701,7 @@ <context> <name>ClientModel</name> <message> - <location filename="../clientmodel.cpp" line="+143"/> + <location filename="../clientmodel.cpp" line="+135"/> <source>Network Alert</source> <translation>Network Alert</translation> </message> @@ -925,7 +925,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+160"/> + <location line="+161"/> <source>This label turns red if the transaction size is greater than 1000 bytes.</source> <translation type="unfinished"></translation> </message> @@ -940,12 +940,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+9"/> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-32"/> + <location line="-33"/> <source>yes</source> <translation type="unfinished"></translation> </message> @@ -971,7 +971,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+58"/> + <location line="+59"/> <location line="+60"/> <source>(no label)</source> <translation type="unfinished">(no label)</translation> @@ -1086,7 +1086,7 @@ <context> <name>HelpMessageDialog</name> <message> - <location filename="../utilitydialog.cpp" line="+33"/> + <location filename="../utilitydialog.cpp" line="+36"/> <source>Bitcoin Core</source> <translation type="unfinished">Bitcoin Core</translation> </message> @@ -1121,6 +1121,41 @@ <source>command-line options</source> <translation type="unfinished">command-line options</translation> </message> + <message> + <location line="+9"/> + <source>UI Options:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> + <source>Choose data directory on startup (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Start minimized</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Show splash screen on startup (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Reset all settings changed in the GUI</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>Intro</name> @@ -1469,17 +1504,17 @@ <translation>&Cancel</translation> </message> <message> - <location filename="../optionsdialog.cpp" line="+83"/> + <location filename="../optionsdialog.cpp" line="+81"/> <source>default</source> <translation>default</translation> </message> <message> - <location line="+59"/> + <location line="+64"/> <source>none</source> <translation type="unfinished"></translation> </message> <message> - <location line="+83"/> + <location line="+71"/> <source>Confirm options reset</source> <translation>Confirm options reset</translation> </message> @@ -1500,7 +1535,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+24"/> + <location line="+25"/> <source>The supplied proxy address is invalid.</source> <translation>The supplied proxy address is invalid.</translation> </message> @@ -1756,7 +1791,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+761"/> + <location line="+763"/> <source>%1 d</source> <translation type="unfinished"></translation> </message> @@ -1830,11 +1865,13 @@ <location line="+26"/> <location line="+23"/> <location line="+23"/> - <location line="+36"/> + <location line="+23"/> <location line="+23"/> <location line="+36"/> <location line="+23"/> - <location line="+533"/> + <location line="+36"/> + <location line="+36"/> + <location line="+534"/> <location line="+23"/> <location line="+23"/> <location line="+23"/> @@ -1855,7 +1892,7 @@ <translation>N/A</translation> </message> <message> - <location line="-1156"/> + <location line="-1216"/> <source>Client version</source> <translation>Client version</translation> </message> @@ -1890,12 +1927,12 @@ <translation>Startup time</translation> </message> <message> - <location line="+29"/> + <location line="+170"/> <source>Network</source> <translation>Network</translation> </message> <message> - <location line="+7"/> + <location line="-147"/> <source>Name</source> <translation type="unfinished"></translation> </message> @@ -1915,22 +1952,39 @@ <translation>Current number of blocks</translation> </message> <message> - <location line="+72"/> + <location line="+52"/> + <source>Memory Pool</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>Current number of transactions</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+36"/> + <source>Memory usage</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+48"/> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+231"/> + <location line="+233"/> + <location line="+552"/> <source>Received</source> <translation type="unfinished"></translation> </message> <message> - <location line="+80"/> + <location line="-472"/> + <location line="+449"/> <source>Sent</source> <translation type="unfinished"></translation> </message> <message> - <location line="+41"/> + <location line="-408"/> <source>&Peers</source> <translation type="unfinished"></translation> </message> @@ -1941,8 +1995,8 @@ </message> <message> <location line="+57"/> - <location filename="../rpcconsole.cpp" line="+281"/> - <location line="+560"/> + <location filename="../rpcconsole.cpp" line="+287"/> + <location line="+578"/> <source>Select a peer to view detailed information.</source> <translation type="unfinished"></translation> </message> @@ -1977,8 +2031,8 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-913"/> - <location line="+821"/> + <location line="-973"/> + <location line="+881"/> <source>User Agent</source> <translation type="unfinished"></translation> </message> @@ -2008,17 +2062,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+23"/> - <source>Bytes Sent</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+23"/> - <source>Bytes Received</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+23"/> + <location line="+69"/> <source>Ping Time</source> <translation type="unfinished"></translation> </message> @@ -2038,17 +2082,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-904"/> + <location line="-977"/> <source>Last block time</source> <translation>Last block time</translation> </message> <message> - <location line="+52"/> + <location line="+123"/> <source>&Open</source> <translation>&Open</translation> </message> <message> - <location line="+24"/> + <location line="+26"/> <source>&Console</source> <translation>&Console</translation> </message> @@ -2068,7 +2112,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../rpcconsole.cpp" line="-333"/> + <location filename="../rpcconsole.cpp" line="-343"/> <source>In:</source> <translation type="unfinished"></translation> </message> @@ -2078,22 +2122,22 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../forms/debugwindow.ui" line="-357"/> + <location filename="../forms/debugwindow.ui" line="-417"/> <source>Build date</source> <translation>Build date</translation> </message> <message> - <location line="+183"/> + <location line="+241"/> <source>Debug log file</source> <translation>Debug log file</translation> </message> <message> - <location line="+83"/> + <location line="+85"/> <source>Clear console</source> <translation>Clear console</translation> </message> <message> - <location filename="../rpcconsole.cpp" line="-150"/> + <location filename="../rpcconsole.cpp" line="-156"/> <source>&Disconnect Node</source> <translation type="unfinished"></translation> </message> @@ -2131,7 +2175,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+64"/> + <location line="+70"/> <source>Welcome to the Bitcoin Core RPC console.</source> <translation type="unfinished"></translation> </message> @@ -2146,7 +2190,7 @@ <translation>Type <b>help</b> for an overview of available commands.</translation> </message> <message> - <location line="+134"/> + <location line="+144"/> <source>%1 B</source> <translation type="unfinished"></translation> </message> @@ -2424,7 +2468,7 @@ <name>SendCoinsDialog</name> <message> <location filename="../forms/sendcoinsdialog.ui" line="+14"/> - <location filename="../sendcoinsdialog.cpp" line="+545"/> + <location filename="../sendcoinsdialog.cpp" line="+546"/> <source>Send Coins</source> <translation>Send Coins</translation> </message> @@ -2626,7 +2670,7 @@ <translation>Confirm send coins</translation> </message> <message> - <location line="-48"/> + <location line="-49"/> <location line="+5"/> <location line="+5"/> <location line="+4"/> @@ -2669,7 +2713,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+246"/> + <location line="+244"/> + <source>Total Amount %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> <source>or</source> <translation type="unfinished"></translation> </message> @@ -2708,8 +2757,13 @@ <source>Payment request expired.</source> <translation type="unfinished"></translation> </message> + <message> + <location line="+91"/> + <source>Pay only the required fee of %1</source> + <translation type="unfinished"></translation> + </message> <message numerus="yes"> - <location line="+110"/> + <location line="+23"/> <source>Estimated to begin confirmation within %n block(s).</source> <translation type="unfinished"> <numerusform>Estimated to begin confirmation within %n block.</numerusform> @@ -2717,17 +2771,7 @@ </translation> </message> <message> - <location line="-22"/> - <source>Pay only the minimum fee of %1</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="-309"/> - <source>Total Amount %1<span style='font-size:10pt;font-weight:normal;'><br />(=%2)</span></source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+195"/> + <location line="-140"/> <source>The recipient address is not valid. Please recheck.</source> <translation type="unfinished"></translation> </message> @@ -2737,7 +2781,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+231"/> + <location line="+234"/> <source>Warning: Invalid Bitcoin address</source> <translation type="unfinished"></translation> </message> @@ -2752,7 +2796,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-691"/> + <location line="-695"/> <source>Copy dust</source> <translation type="unfinished"></translation> </message> @@ -2879,7 +2923,7 @@ <context> <name>ShutdownWindow</name> <message> - <location filename="../utilitydialog.cpp" line="+81"/> + <location filename="../utilitydialog.cpp" line="+78"/> <source>Bitcoin Core is shutting down...</source> <translation type="unfinished"></translation> </message> @@ -3324,7 +3368,7 @@ <context> <name>TransactionTableModel</name> <message> - <location filename="../transactiontablemodel.cpp" line="+233"/> + <location filename="../transactiontablemodel.cpp" line="+246"/> <source>Date</source> <translation>Date</translation> </message> @@ -3427,7 +3471,7 @@ <translation>(n/a)</translation> </message> <message> - <location line="+215"/> + <location line="+217"/> <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> @@ -3552,6 +3596,11 @@ </message> <message> <location line="+1"/> + <source>Copy raw transaction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source>Edit label</source> <translation>Edit label</translation> </message> @@ -3561,7 +3610,7 @@ <translation>Show transaction details</translation> </message> <message> - <location line="+179"/> + <location line="+181"/> <source>Export Transaction History</source> <translation type="unfinished"></translation> </message> @@ -3626,7 +3675,7 @@ <translation>ID</translation> </message> <message> - <location line="+116"/> + <location line="+121"/> <source>Range:</source> <translation>Range:</translation> </message> @@ -3706,37 +3755,32 @@ <context> <name>bitcoin-core</name> <message> - <location filename="../bitcoinstrings.cpp" line="+249"/> + <location filename="../bitcoinstrings.cpp" line="+267"/> <source>Options:</source> <translation>Options:</translation> </message> <message> - <location line="+30"/> + <location line="+27"/> <source>Specify data directory</source> <translation>Specify data directory</translation> </message> <message> - <location line="-87"/> + <location line="-84"/> <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="+90"/> + <location line="+87"/> <source>Specify your own public address</source> <translation>Specify your own public address</translation> </message> <message> - <location line="-107"/> + <location line="-105"/> <source>Accept command line and JSON-RPC commands</source> <translation>Accept command line and JSON-RPC commands</translation> </message> <message> - <location line="-117"/> - <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+5"/> + <location line="-118"/> <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> <translation type="unfinished"></translation> </message> @@ -3771,17 +3815,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+109"/> + <location line="+116"/> <source>Error: A fatal internal error occurred, see debug.log for details</source> <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> + <location line="+3"/> <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+37"/> + <location line="+38"/> <source>Pruning blockstore...</source> <translation type="unfinished"></translation> </message> @@ -3791,22 +3835,17 @@ <translation>Run in the background as a daemon and accept commands</translation> </message> <message> - <location line="+32"/> + <location line="+29"/> <source>Unable to start HTTP server. See debug log for details.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> - <source>Use the test network</source> - <translation>Use the test network</translation> - </message> - <message> - <location line="-123"/> + <location line="-117"/> <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="-157"/> + <location line="-168"/> <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> @@ -3821,17 +3860,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+13"/> <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="+57"/> + <location line="+60"/> <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="+6"/> + <location line="+8"/> <source>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> <translation type="unfinished"></translation> </message> @@ -3841,17 +3880,17 @@ <translation>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</translation> </message> <message> - <location line="+7"/> + <location line="+13"/> <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+6"/> <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> + <location line="+9"/> <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> <translation type="unfinished"></translation> </message> @@ -3861,11 +3900,6 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</translation> - </message> - <message> <location line="+3"/> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</translation> @@ -3877,11 +3911,6 @@ </message> <message> <location line="+3"/> - <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> - <translation>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</translation> - </message> - <message> - <location line="+3"/> <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>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> @@ -3892,7 +3921,7 @@ </message> <message> <location line="+11"/> - <source>(default: 1)</source> + <source>-maxmempool must be at least %d MB</source> <translation type="unfinished"></translation> </message> <message> @@ -3901,17 +3930,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Attempt to recover private keys from a corrupt wallet.dat</translation> - </message> - <message> - <location line="+1"/> + <location line="+11"/> <source>Block creation options:</source> <translation>Block creation options:</translation> </message> <message> - <location line="+7"/> + <location line="+6"/> <source>Connect only to the specified node(s)</source> <translation>Connect only to the specified node(s)</translation> </message> @@ -3986,7 +4010,7 @@ <translation>Error: Disk space is low!</translation> </message> <message> - <location line="+2"/> + <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> @@ -4006,7 +4030,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+20"/> + <location line="+9"/> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+12"/> <source>Not enough file descriptors available.</source> <translation>Not enough file descriptors available.</translation> </message> @@ -4026,27 +4055,47 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+14"/> + <location line="+13"/> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+2"/> <source>Set maximum block size in bytes (default: %d)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+10"/> <source>Specify wallet file (within data directory)</source> <translation>Specify wallet file (within data directory)</translation> </message> <message> - <location line="+17"/> + <location line="+16"/> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Unsupported argument -tor found, use -onion.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> <source>Use UPnP to map the listening port (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+1"/> + <source>User Agent comment (%s) contains unsafe characters.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> <source>Verifying blocks...</source> <translation>Verifying blocks...</translation> </message> @@ -4071,17 +4120,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+2"/> <source>You need to rebuild the database using -reindex to change -txindex</source> <translation>You need to rebuild the database using -reindex to change -txindex</translation> </message> <message> - <location line="-89"/> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Imports blocks from external blk000??.dat file</translation> - </message> - <message> - <location line="-206"/> + <location line="-306"/> <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> @@ -4111,22 +4155,22 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <location line="+11"/> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation type="unfinished"></translation> </message> <message> <location line="+2"/> - <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</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> <message> - <location line="+17"/> + <location line="+9"/> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+11"/> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4161,7 +4205,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+10"/> <source>The transaction amount is too small to send after the fee has been deducted</source> <translation type="unfinished"></translation> </message> @@ -4171,12 +4215,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+18"/> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+22"/> + <location line="+44"/> <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> @@ -4201,17 +4240,27 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> - <source>Cannot resolve -whitebind address: '%s'</source> + <location line="+4"/> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> - <source>Choose data directory on startup (default: 0)</source> - <translation type="unfinished">Choose data directory on startup (default: 0)</translation> + <location line="+1"/> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation type="unfinished"></translation> </message> <message> - <location line="+2"/> + <location line="+1"/> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> <source>Connect through SOCKS5 proxy</source> <translation type="unfinished"></translation> </message> @@ -4231,12 +4280,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+4"/> - <source>Error: Unsupported argument -tor found, use -onion.</source> + <location line="+9"/> + <source>Imports blocks from external blk000??.dat file on startup</source> <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+3"/> <source>Information</source> <translation>Information</translation> </message> @@ -4276,7 +4325,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+10"/> + <location line="+11"/> <source>Need to specify a port with -whitebind: '%s'</source> <translation type="unfinished"></translation> </message> @@ -4306,7 +4355,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <location line="+3"/> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> <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> @@ -4316,27 +4370,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation type="unfinished">Set language, for example "de_DE" (default: system locale)</translation> - </message> - <message> - <location line="+4"/> + <location line="+6"/> <source>Show all debugging options (usage: --help -help-debug)</source> <translation type="unfinished"></translation> </message> <message> <location line="+1"/> - <source>Show splash screen on startup (default: 1)</source> - <translation type="unfinished">Show splash screen on startup (default: 1)</translation> - </message> - <message> - <location line="+1"/> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Shrink debug.log file on client startup (default: 1 when no -debug)</translation> </message> @@ -4347,11 +4386,6 @@ </message> <message> <location line="+8"/> - <source>Start minimized</source> - <translation type="unfinished">Start minimized</translation> - </message> - <message> - <location line="+1"/> <source>The transaction amount is too small to pay the fee</source> <translation type="unfinished"></translation> </message> @@ -4362,6 +4396,16 @@ </message> <message> <location line="+2"/> + <source>Tor control port password (default: empty)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source>Transaction amount too small</source> <translation>Transaction amount too small</translation> </message> @@ -4382,16 +4426,16 @@ </message> <message> <location line="+1"/> - <source>UI Options:</source> + <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> - <source>Unable to bind to %s on this computer (bind returned error %s)</source> + <location line="+6"/> + <source>Upgrade wallet to latest format on startup</source> <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <location line="+3"/> <source>Username for JSON-RPC connections</source> <translation>Username for JSON-RPC connections</translation> </message> @@ -4407,12 +4451,7 @@ </message> <message> <location line="+2"/> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> - <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> + <source>Whether to operate in a blocks only mode (default: %u)</source> <translation type="unfinished"></translation> </message> <message> @@ -4427,46 +4466,31 @@ </message> <message> <location line="+1"/> - <source>on startup</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+1"/> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat corrupt, salvage failed</translation> </message> <message> - <location line="-64"/> + <location line="-62"/> <source>Password for JSON-RPC connections</source> <translation>Password for JSON-RPC connections</translation> </message> <message> - <location line="-195"/> + <location line="-205"/> <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="+242"/> - <source>Upgrade wallet to latest format</source> - <translation>Upgrade wallet to latest format</translation> - </message> - <message> - <location line="-36"/> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Rescan the block chain for missing wallet transactions</translation> - </message> - <message> - <location line="+25"/> + <location line="+237"/> <source>This help message</source> <translation>This help message</translation> </message> <message> - <location line="-106"/> + <location line="-103"/> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> <translation>Allow DNS lookups for -addnode, -seednode and -connect</translation> </message> <message> - <location line="+58"/> + <location line="+59"/> <source>Loading addresses...</source> <translation>Loading addresses...</translation> </message> @@ -4476,12 +4500,37 @@ <translation>Error loading wallet.dat: Wallet corrupted</translation> </message> <message> - <location line="-196"/> + <location line="-214"/> <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="+49"/> + <location line="+3"/> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+32"/> + <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+17"/> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</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> @@ -4501,12 +4550,37 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+51"/> + <location line="+32"/> + <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+16"/> + <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+6"/> + <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+37"/> + <location line="+3"/> + <source>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+29"/> <source>(default: %s)</source> <translation type="unfinished"></translation> </message> @@ -4516,12 +4590,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+26"/> + <location line="+27"/> <source>Error loading wallet.dat</source> <translation>Error loading wallet.dat</translation> </message> <message> - <location line="+11"/> + <location line="+10"/> <source>Generate coins (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4541,7 +4615,7 @@ <translation>Invalid -proxy address: '%s'</translation> </message> <message> - <location line="+8"/> + <location line="+9"/> <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> <translation type="unfinished"></translation> </message> @@ -4586,12 +4660,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+7"/> <source>Set key pool size to <n> (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+2"/> <source>Set minimum block size in bytes (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4601,7 +4675,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> + <location line="+4"/> <source>Specify configuration file (default: %s)</source> <translation type="unfinished"></translation> </message> @@ -4621,17 +4695,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+5"/> + <location line="+4"/> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+8"/> + <location line="+9"/> <source>Unknown network specified in -onlynet: '%s'</source> <translation>Unknown network specified in -onlynet: '%s'</translation> </message> <message> - <location line="-111"/> + <location line="-107"/> <source>Cannot resolve -bind address: '%s'</source> <translation>Cannot resolve -bind address: '%s'</translation> </message> @@ -4641,7 +4715,7 @@ <translation>Cannot resolve -externalip address: '%s'</translation> </message> <message> - <location line="+47"/> + <location line="+45"/> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> <translation>Invalid amount for -paytxfee=<amount>: '%s'</translation> </message> @@ -4651,22 +4725,22 @@ <translation>Insufficient funds</translation> </message> <message> - <location line="+13"/> + <location line="+14"/> <source>Loading block index...</source> <translation>Loading block index...</translation> </message> <message> - <location line="-60"/> + <location line="-61"/> <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="+61"/> + <location line="+62"/> <source>Loading wallet...</source> <translation>Loading wallet...</translation> </message> <message> - <location line="-56"/> + <location line="-55"/> <source>Cannot downgrade wallet</source> <translation>Cannot downgrade wallet</translation> </message> @@ -4676,7 +4750,7 @@ <translation>Cannot write default address</translation> </message> <message> - <location line="+74"/> + <location line="+73"/> <source>Rescanning...</source> <translation>Rescanning...</translation> </message> diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts new file mode 100644 index 0000000000..bf912d295e --- /dev/null +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -0,0 +1,3719 @@ +<TS language="en_GB" version="2.1"> +<context> + <name>AddressBookPage</name> + <message> + <source>Right-click to edit address or label</source> + <translation>Right-click to edit address or label</translation> + </message> + <message> + <source>Create a new address</source> + <translation>Create a new address</translation> + </message> + <message> + <source>&New</source> + <translation>&New</translation> + </message> + <message> + <source>Copy the currently selected address to the system clipboard</source> + <translation>Copy the currently selected address to the system clipboard</translation> + </message> + <message> + <source>&Copy</source> + <translation>&Copy</translation> + </message> + <message> + <source>C&lose</source> + <translation>C&lose</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>&Copy Address</translation> + </message> + <message> + <source>Delete the currently selected address from the list</source> + <translation>Delete the currently selected address from the list</translation> + </message> + <message> + <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> + <message> + <source>&Export</source> + <translation>&Export</translation> + </message> + <message> + <source>&Delete</source> + <translation>&Delete</translation> + </message> + <message> + <source>Choose the address to send coins to</source> + <translation>Choose the address to send coins to</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>Choose the address to receive coins with</translation> + </message> + <message> + <source>C&hoose</source> + <translation>C&hoose</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Sending addresses</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Receiving addresses</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>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</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>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</translation> + </message> + <message> + <source>Copy &Label</source> + <translation>Copy &Label</translation> + </message> + <message> + <source>&Edit</source> + <translation>&Edit</translation> + </message> + <message> + <source>Export Address List</source> + <translation>Export Address List</translation> + </message> + <message> + <source>Comma separated file (*.csv)</source> + <translation>Comma separated file (*.csv)</translation> + </message> + <message> + <source>Exporting Failed</source> + <translation>Exporting Failed</translation> + </message> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>There was an error trying to save the address list to %1. Please try again.</translation> + </message> +</context> +<context> + <name>AddressTableModel</name> + <message> + <source>Label</source> + <translation>Label</translation> + </message> + <message> + <source>Address</source> + <translation>Address</translation> + </message> + <message> + <source>(no label)</source> + <translation>(no label)</translation> + </message> +</context> +<context> + <name>AskPassphraseDialog</name> + <message> + <source>Passphrase Dialog</source> + <translation>Passphrase Dialog</translation> + </message> + <message> + <source>Enter passphrase</source> + <translation>Enter passphrase</translation> + </message> + <message> + <source>New passphrase</source> + <translation>New passphrase</translation> + </message> + <message> + <source>Repeat new passphrase</source> + <translation>Repeat new passphrase</translation> + </message> + <message> + <source>Encrypt wallet</source> + <translation>Encrypt wallet</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to unlock the wallet.</source> + <translation>This operation needs your wallet passphrase to unlock the wallet.</translation> + </message> + <message> + <source>Unlock wallet</source> + <translation>Unlock wallet</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to decrypt the wallet.</source> + <translation>This operation needs your wallet passphrase to decrypt the wallet.</translation> + </message> + <message> + <source>Decrypt wallet</source> + <translation>Decrypt wallet</translation> + </message> + <message> + <source>Change passphrase</source> + <translation>Change passphrase</translation> + </message> + <message> + <source>Confirm wallet encryption</source> + <translation>Confirm wallet encryption</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>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</translation> + </message> + <message> + <source>Are you sure you wish to encrypt your wallet?</source> + <translation>Are you sure you wish to encrypt your wallet?</translation> + </message> + <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Bitcoin Core 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> + <message> + <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> + <translation>IMPORTANT: 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.</translation> + </message> + <message> + <source>Warning: The Caps Lock key is on!</source> + <translation>Warning: The Caps Lock key is on!</translation> + </message> + <message> + <source>Wallet encrypted</source> + <translation>Wallet encrypted</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>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>.</translation> + </message> + <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Enter the old passphrase and new passphrase to the wallet.</translation> + </message> + <message> + <source>Wallet encryption failed</source> + <translation>Wallet encryption failed</translation> + </message> + <message> + <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> + <translation>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</translation> + </message> + <message> + <source>The supplied passphrases do not match.</source> + <translation>The supplied passphrases do not match.</translation> + </message> + <message> + <source>Wallet unlock failed</source> + <translation>Wallet unlock failed</translation> + </message> + <message> + <source>The passphrase entered for the wallet decryption was incorrect.</source> + <translation>The passphrase entered for the wallet decryption was incorrect.</translation> + </message> + <message> + <source>Wallet decryption failed</source> + <translation>Wallet decryption failed</translation> + </message> + <message> + <source>Wallet passphrase was successfully changed.</source> + <translation>Wallet passphrase was successfully changed.</translation> + </message> +</context> +<context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/Netmask</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Banned Until</translation> + </message> +</context> +<context> + <name>BitcoinGUI</name> + <message> + <source>Sign &message...</source> + <translation>Sign &message...</translation> + </message> + <message> + <source>Synchronizing with network...</source> + <translation>Synchronising with network...</translation> + </message> + <message> + <source>&Overview</source> + <translation>&Overview</translation> + </message> + <message> + <source>Node</source> + <translation>Node</translation> + </message> + <message> + <source>Show general overview of wallet</source> + <translation>Show general overview of wallet</translation> + </message> + <message> + <source>&Transactions</source> + <translation>&Transactions</translation> + </message> + <message> + <source>Browse transaction history</source> + <translation>Browse transaction history</translation> + </message> + <message> + <source>E&xit</source> + <translation>E&xit</translation> + </message> + <message> + <source>Quit application</source> + <translation>Quit application</translation> + </message> + <message> + <source>About &Qt</source> + <translation>About &Qt</translation> + </message> + <message> + <source>Show information about Qt</source> + <translation>Show information about Qt</translation> + </message> + <message> + <source>&Options...</source> + <translation>&Options...</translation> + </message> + <message> + <source>&Encrypt Wallet...</source> + <translation>&Encrypt Wallet...</translation> + </message> + <message> + <source>&Backup Wallet...</source> + <translation>&Backup Wallet...</translation> + </message> + <message> + <source>&Change Passphrase...</source> + <translation>&Change Passphrase...</translation> + </message> + <message> + <source>&Sending addresses...</source> + <translation>&Sending addresses...</translation> + </message> + <message> + <source>&Receiving addresses...</source> + <translation>&Receiving addresses...</translation> + </message> + <message> + <source>Open &URI...</source> + <translation>Open &URI...</translation> + </message> + <message> + <source>Bitcoin Core client</source> + <translation>Bitcoin Core client</translation> + </message> + <message> + <source>Importing blocks from disk...</source> + <translation>Importing blocks from disk...</translation> + </message> + <message> + <source>Reindexing blocks on disk...</source> + <translation>Reindexing blocks on disk...</translation> + </message> + <message> + <source>Send coins to a Bitcoin address</source> + <translation>Send coins to a Bitcoin address</translation> + </message> + <message> + <source>Backup wallet to another location</source> + <translation>Backup wallet to another location</translation> + </message> + <message> + <source>Change the passphrase used for wallet encryption</source> + <translation>Change the passphrase used for wallet encryption</translation> + </message> + <message> + <source>&Debug window</source> + <translation>&Debug window</translation> + </message> + <message> + <source>Open debugging and diagnostic console</source> + <translation>Open debugging and diagnostic console</translation> + </message> + <message> + <source>&Verify message...</source> + <translation>&Verify message...</translation> + </message> + <message> + <source>Bitcoin</source> + <translation>Bitcoin</translation> + </message> + <message> + <source>Wallet</source> + <translation>Wallet</translation> + </message> + <message> + <source>&Send</source> + <translation>&Send</translation> + </message> + <message> + <source>&Receive</source> + <translation>&Receive</translation> + </message> + <message> + <source>Show information about Bitcoin Core</source> + <translation>Show information about Bitcoin Core</translation> + </message> + <message> + <source>&Show / Hide</source> + <translation>&Show / Hide</translation> + </message> + <message> + <source>Show or hide the main Window</source> + <translation>Show or hide the main Window</translation> + </message> + <message> + <source>Encrypt the private keys that belong to your wallet</source> + <translation>Encrypt the private keys that belong to your wallet</translation> + </message> + <message> + <source>Sign messages with your Bitcoin addresses to prove you own them</source> + <translation>Sign messages with your Bitcoin addresses to prove you own them</translation> + </message> + <message> + <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source> + <translation>Verify messages to ensure they were signed with specified Bitcoin addresses</translation> + </message> + <message> + <source>&File</source> + <translation>&File</translation> + </message> + <message> + <source>&Settings</source> + <translation>&Settings</translation> + </message> + <message> + <source>&Help</source> + <translation>&Help</translation> + </message> + <message> + <source>Tabs toolbar</source> + <translation>Tabs toolbar</translation> + </message> + <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>Request payments (generates QR codes and bitcoin: URIs)</source> + <translation>Request payments (generates QR codes and bitcoin: URIs)</translation> + </message> + <message> + <source>&About Bitcoin Core</source> + <translation>&About Bitcoin Core</translation> + </message> + <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Modify configuration options for Bitcoin Core</translation> + </message> + <message> + <source>Show the list of used sending addresses and labels</source> + <translation>Show the list of used sending addresses and labels</translation> + </message> + <message> + <source>Show the list of used receiving addresses and labels</source> + <translation>Show the list of used receiving addresses and labels</translation> + </message> + <message> + <source>Open a bitcoin: URI or payment request</source> + <translation>Open a bitcoin: URI or payment request</translation> + </message> + <message> + <source>&Command-line options</source> + <translation>&Command-line options</translation> + </message> + <message> + <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> + <translation>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</translation> + </message> + <message numerus="yes"> + <source>%n active connection(s) to Bitcoin network</source> + <translation><numerusform>%n active connection to Bitcoin network</numerusform><numerusform>%n active connections to Bitcoin network</numerusform></translation> + </message> + <message> + <source>No block source available...</source> + <translation>No block source available...</translation> + </message> + <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Processed %n block of transaction history.</numerusform><numerusform>Processed %n blocks of transaction history.</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n hour</numerusform><numerusform>%n hours</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n day</numerusform><numerusform>%n days</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n week</numerusform><numerusform>%n weeks</numerusform></translation> + </message> + <message> + <source>%1 and %2</source> + <translation>%1 and %2</translation> + </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n year</numerusform><numerusform>%n years</numerusform></translation> + </message> + <message> + <source>%1 behind</source> + <translation>%1 behind</translation> + </message> + <message> + <source>Last received block was generated %1 ago.</source> + <translation>Last received block was generated %1 ago.</translation> + </message> + <message> + <source>Transactions after this will not yet be visible.</source> + <translation>Transactions after this will not yet be visible.</translation> + </message> + <message> + <source>Error</source> + <translation>Error</translation> + </message> + <message> + <source>Warning</source> + <translation>Warning</translation> + </message> + <message> + <source>Information</source> + <translation>Information</translation> + </message> + <message> + <source>Up to date</source> + <translation>Up to date</translation> + </message> + <message> + <source>Catching up...</source> + <translation>Catching up...</translation> + </message> + <message> + <source>Date: %1 +</source> + <translation>Date: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Amount: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Type: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Label: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Address: %1 +</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Sent transaction</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Incoming transaction</translation> + </message> + <message> + <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> + <message> + <source>Wallet is <b>encrypted</b> and currently <b>locked</b></source> + <translation>Wallet is <b>encrypted</b> and currently <b>locked</b></translation> + </message> +</context> +<context> + <name>ClientModel</name> + <message> + <source>Network Alert</source> + <translation>Network Alert</translation> + </message> +</context> +<context> + <name>CoinControlDialog</name> + <message> + <source>Coin Selection</source> + <translation>Coin Selection</translation> + </message> + <message> + <source>Quantity:</source> + <translation>Quantity:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Bytes:</translation> + </message> + <message> + <source>Amount:</source> + <translation>Amount:</translation> + </message> + <message> + <source>Priority:</source> + <translation>Priority:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Fee:</translation> + </message> + <message> + <source>Dust:</source> + <translation>Dust:</translation> + </message> + <message> + <source>After Fee:</source> + <translation>After Fee:</translation> + </message> + <message> + <source>Change:</source> + <translation>Change:</translation> + </message> + <message> + <source>(un)select all</source> + <translation>(un)select all</translation> + </message> + <message> + <source>Tree mode</source> + <translation>Tree mode</translation> + </message> + <message> + <source>List mode</source> + <translation>List mode</translation> + </message> + <message> + <source>Amount</source> + <translation>Amount</translation> + </message> + <message> + <source>Received with label</source> + <translation>Received with label</translation> + </message> + <message> + <source>Received with address</source> + <translation>Received with address</translation> + </message> + <message> + <source>Date</source> + <translation>Date</translation> + </message> + <message> + <source>Confirmations</source> + <translation>Confirmations</translation> + </message> + <message> + <source>Confirmed</source> + <translation>Confirmed</translation> + </message> + <message> + <source>Priority</source> + <translation>Priority</translation> + </message> + <message> + <source>Copy address</source> + <translation>Copy address</translation> + </message> + <message> + <source>Copy label</source> + <translation>Copy label</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Copy amount</translation> + </message> + <message> + <source>Copy transaction ID</source> + <translation>Copy transaction ID</translation> + </message> + <message> + <source>Lock unspent</source> + <translation>Lock unspent</translation> + </message> + <message> + <source>Unlock unspent</source> + <translation>Unlock unspent</translation> + </message> + <message> + <source>Copy quantity</source> + <translation>Copy quantity</translation> + </message> + <message> + <source>Copy fee</source> + <translation>Copy fee</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Copy after fee</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Copy bytes</translation> + </message> + <message> + <source>Copy priority</source> + <translation>Copy priority</translation> + </message> + <message> + <source>Copy dust</source> + <translation>Copy dust</translation> + </message> + <message> + <source>Copy change</source> + <translation>Copy change</translation> + </message> + <message> + <source>highest</source> + <translation>highest</translation> + </message> + <message> + <source>higher</source> + <translation>higher</translation> + </message> + <message> + <source>high</source> + <translation>high</translation> + </message> + <message> + <source>medium-high</source> + <translation>medium-high</translation> + </message> + <message> + <source>medium</source> + <translation>medium</translation> + </message> + <message> + <source>low-medium</source> + <translation>low-medium</translation> + </message> + <message> + <source>low</source> + <translation>low</translation> + </message> + <message> + <source>lower</source> + <translation>lower</translation> + </message> + <message> + <source>lowest</source> + <translation>lowest</translation> + </message> + <message> + <source>(%1 locked)</source> + <translation>(%1 locked)</translation> + </message> + <message> + <source>none</source> + <translation>none</translation> + </message> + <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>This label turns red if the transaction size is greater than 1000 bytes.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>This label turns red if the priority is smaller than "medium".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>This label turns red if any recipient receives an amount smaller than %1.</translation> + </message> + <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>Can vary +/- %1 satoshi(s) per input.</translation> + </message> + <message> + <source>yes</source> + <translation>yes</translation> + </message> + <message> + <source>no</source> + <translation>no</translation> + </message> + <message> + <source>This means a fee of at least %1 per kB is required.</source> + <translation>This means a fee of at least %1 per kB is required.</translation> + </message> + <message> + <source>Can vary +/- 1 byte per input.</source> + <translation>Can vary +/- 1 byte per input.</translation> + </message> + <message> + <source>Transactions with higher priority are more likely to get included into a block.</source> + <translation>Transactions with higher priority are more likely to get included into a block.</translation> + </message> + <message> + <source>(no label)</source> + <translation>(no label)</translation> + </message> + <message> + <source>change from %1 (%2)</source> + <translation>change from %1 (%2)</translation> + </message> + <message> + <source>(change)</source> + <translation>(change)</translation> + </message> +</context> +<context> + <name>EditAddressDialog</name> + <message> + <source>Edit Address</source> + <translation>Edit Address</translation> + </message> + <message> + <source>&Label</source> + <translation>&Label</translation> + </message> + <message> + <source>The label associated with this address list entry</source> + <translation>The label associated with this address list entry</translation> + </message> + <message> + <source>The address associated with this address list entry. This can only be modified for sending addresses.</source> + <translation>The address associated with this address list entry. This can only be modified for sending addresses.</translation> + </message> + <message> + <source>&Address</source> + <translation>&Address</translation> + </message> + <message> + <source>New receiving address</source> + <translation>New receiving address</translation> + </message> + <message> + <source>New sending address</source> + <translation>New sending address</translation> + </message> + <message> + <source>Edit receiving address</source> + <translation>Edit receiving address</translation> + </message> + <message> + <source>Edit sending address</source> + <translation>Edit sending address</translation> + </message> + <message> + <source>The entered address "%1" is already in the address book.</source> + <translation>The entered address "%1" is already in the address book.</translation> + </message> + <message> + <source>The entered address "%1" is not a valid Bitcoin address.</source> + <translation>The entered address "%1" is not a valid Bitcoin address.</translation> + </message> + <message> + <source>Could not unlock wallet.</source> + <translation>Could not unlock wallet.</translation> + </message> + <message> + <source>New key generation failed.</source> + <translation>New key generation failed.</translation> + </message> +</context> +<context> + <name>FreespaceChecker</name> + <message> + <source>A new data directory will be created.</source> + <translation>A new data directory will be created.</translation> + </message> + <message> + <source>name</source> + <translation>name</translation> + </message> + <message> + <source>Directory already exists. Add %1 if you intend to create a new directory here.</source> + <translation>Directory already exists. Add %1 if you intend to create a new directory here.</translation> + </message> + <message> + <source>Path already exists, and is not a directory.</source> + <translation>Path already exists, and is not a directory.</translation> + </message> + <message> + <source>Cannot create data directory here.</source> + <translation>Cannot create data directory here.</translation> + </message> +</context> +<context> + <name>HelpMessageDialog</name> + <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>version</source> + <translation>version</translation> + </message> + <message> + <source>(%1-bit)</source> + <translation>(%1-bit)</translation> + </message> + <message> + <source>About Bitcoin Core</source> + <translation>About Bitcoin Core</translation> + </message> + <message> + <source>Command-line options</source> + <translation>Command-line options</translation> + </message> + <message> + <source>Usage:</source> + <translation>Usage:</translation> + </message> + <message> + <source>command-line options</source> + <translation>command-line options</translation> + </message> + <message> + <source>UI Options:</source> + <translation>UI Options:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Choose data directory on startup (default: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Set language, for example "de_DE" (default: system locale)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Start minimised</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Set SSL root certificates for payment request (default: -system-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Show splash screen on startup (default: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Reset all settings changes made over the GUI</translation> + </message> +</context> +<context> + <name>Intro</name> + <message> + <source>Welcome</source> + <translation>Welcome</translation> + </message> + <message> + <source>Welcome to Bitcoin Core.</source> + <translation>Welcome to 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>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</translation> + </message> + <message> + <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source> + <translation>Bitcoin Core 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.</translation> + </message> + <message> + <source>Use the default data directory</source> + <translation>Use the default data directory</translation> + </message> + <message> + <source>Use a custom data directory:</source> + <translation>Use a custom data directory:</translation> + </message> + <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>Error: Specified data directory "%1" cannot be created.</source> + <translation>Error: Specified data directory "%1" cannot be created.</translation> + </message> + <message> + <source>Error</source> + <translation>Error</translation> + </message> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB of free space available</numerusform><numerusform>%n GB of free space available</numerusform></translation> + </message> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(of %n GB needed)</numerusform><numerusform>(of %n GB needed)</numerusform></translation> + </message> +</context> +<context> + <name>OpenURIDialog</name> + <message> + <source>Open URI</source> + <translation>Open URI</translation> + </message> + <message> + <source>Open payment request from URI or file</source> + <translation>Open payment request from URI or file</translation> + </message> + <message> + <source>URI:</source> + <translation>URI:</translation> + </message> + <message> + <source>Select payment request file</source> + <translation>Select payment request file</translation> + </message> + <message> + <source>Select payment request file to open</source> + <translation>Select payment request file to open</translation> + </message> +</context> +<context> + <name>OptionsDialog</name> + <message> + <source>Options</source> + <translation>Options</translation> + </message> + <message> + <source>&Main</source> + <translation>&Main</translation> + </message> + <message> + <source>Size of &database cache</source> + <translation>Size of &database cache</translation> + </message> + <message> + <source>MB</source> + <translation>MB</translation> + </message> + <message> + <source>Number of script &verification threads</source> + <translation>Number of script &verification threads</translation> + </message> + <message> + <source>Accept connections from outside</source> + <translation>Accept connections from outside</translation> + </message> + <message> + <source>Allow incoming connections</source> + <translation>Allow incoming connections</translation> + </message> + <message> + <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> + <translation>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</translation> + </message> + <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Minimise instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</translation> + </message> + <message> + <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> + <translation>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 |.</translation> + </message> + <message> + <source>Third party transaction URLs</source> + <translation>Third party transaction URLs</translation> + </message> + <message> + <source>Active command-line options that override above options:</source> + <translation>Active command-line options that override above options:</translation> + </message> + <message> + <source>Reset all client options to default.</source> + <translation>Reset all client options to default.</translation> + </message> + <message> + <source>&Reset Options</source> + <translation>&Reset Options</translation> + </message> + <message> + <source>&Network</source> + <translation>&Network</translation> + </message> + <message> + <source>Automatically start Bitcoin Core after logging in to the system.</source> + <translation>Automatically start Bitcoin Core after logging in to the system.</translation> + </message> + <message> + <source>&Start Bitcoin Core on system login</source> + <translation>&Start Bitcoin Core on system login</translation> + </message> + <message> + <source>(0 = auto, <0 = leave that many cores free)</source> + <translation>(0 = auto, <0 = leave that many cores free)</translation> + </message> + <message> + <source>W&allet</source> + <translation>W&allet</translation> + </message> + <message> + <source>Expert</source> + <translation>Expert</translation> + </message> + <message> + <source>Enable coin &control features</source> + <translation>Enable coin &control features</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>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.</translation> + </message> + <message> + <source>&Spend unconfirmed change</source> + <translation>&Spend unconfirmed change</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>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</translation> + </message> + <message> + <source>Map port using &UPnP</source> + <translation>Map port using &UPnP</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation>Connect to the Bitcoin network through a SOCKS5 proxy.</translation> + </message> + <message> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation>&Connect through SOCKS5 proxy (default proxy):</translation> + </message> + <message> + <source>Proxy &IP:</source> + <translation>Proxy &IP:</translation> + </message> + <message> + <source>&Port:</source> + <translation>&Port:</translation> + </message> + <message> + <source>Port of the proxy (e.g. 9050)</source> + <translation>Port of the proxy (e.g. 9050)</translation> + </message> + <message> + <source>Used for reaching peers via:</source> + <translation>Used for reaching peers via:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</translation> + </message> + <message> + <source>&Window</source> + <translation>&Window</translation> + </message> + <message> + <source>Show only a tray icon after minimizing the window.</source> + <translation>Show on a tray icon after minimising the window.</translation> + </message> + <message> + <source>&Minimize to the tray instead of the taskbar</source> + <translation>&Minimise to the tray instead of the task bar</translation> + </message> + <message> + <source>M&inimize on close</source> + <translation>M&inimise on close</translation> + </message> + <message> + <source>&Display</source> + <translation>&Display</translation> + </message> + <message> + <source>User Interface &language:</source> + <translation>User Interface &language:</translation> + </message> + <message> + <source>&Unit to show amounts in:</source> + <translation>&Unit to show amounts in:</translation> + </message> + <message> + <source>Choose the default subdivision unit to show in the interface and when sending coins.</source> + <translation>Choose the default subdivision unit to show in the interface and when sending coins.</translation> + </message> + <message> + <source>Whether to show coin control features or not.</source> + <translation>Whether to show coin control features or not.</translation> + </message> + <message> + <source>&OK</source> + <translation>&OK</translation> + </message> + <message> + <source>&Cancel</source> + <translation>&Cancel</translation> + </message> + <message> + <source>default</source> + <translation>default</translation> + </message> + <message> + <source>none</source> + <translation>none</translation> + </message> + <message> + <source>Confirm options reset</source> + <translation>Confirm options reset</translation> + </message> + <message> + <source>Client restart required to activate changes.</source> + <translation>Client restart required to activate changes.</translation> + </message> + <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Client will be shut down. Do you want to proceed?</translation> + </message> + <message> + <source>This change would require a client restart.</source> + <translation>This change would require a client restart.</translation> + </message> + <message> + <source>The supplied proxy address is invalid.</source> + <translation>The supplied proxy address is invalid.</translation> + </message> +</context> +<context> + <name>OverviewPage</name> + <message> + <source>Form</source> + <translation>Form</translation> + </message> + <message> + <source>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source> + <translation>The displayed information may be out of date. Your Wallet automatically synchronises with the Bitcoin Network after a connection is established, but this process has not been completed yet.</translation> + </message> + <message> + <source>Watch-only:</source> + <translation>Watch-only:</translation> + </message> + <message> + <source>Available:</source> + <translation>Available:</translation> + </message> + <message> + <source>Your current spendable balance</source> + <translation>Your current spendable balance</translation> + </message> + <message> + <source>Pending:</source> + <translation>Pending:</translation> + </message> + <message> + <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> + <source>Immature:</source> + <translation>Immature:</translation> + </message> + <message> + <source>Mined balance that has not yet matured</source> + <translation>Mined balance that has not yet matured</translation> + </message> + <message> + <source>Balances</source> + <translation>Balances</translation> + </message> + <message> + <source>Total:</source> + <translation>Total:</translation> + </message> + <message> + <source>Your current total balance</source> + <translation>Your current total balance</translation> + </message> + <message> + <source>Your current balance in watch-only addresses</source> + <translation>Your current balance in watch-only addresses</translation> + </message> + <message> + <source>Spendable:</source> + <translation>Spendable:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Recent transactions</translation> + </message> + <message> + <source>Unconfirmed transactions to watch-only addresses</source> + <translation>Unconfirmed transactions to watch-only addresses</translation> + </message> + <message> + <source>Mined balance in watch-only addresses that has not yet matured</source> + <translation>Mined balance in watch-only addresses that has not yet matured</translation> + </message> + <message> + <source>Current total balance in watch-only addresses</source> + <translation>Current total balance in watch-only addresses</translation> + </message> +</context> +<context> + <name>PaymentServer</name> + <message> + <source>URI handling</source> + <translation>URI handling</translation> + </message> + <message> + <source>Invalid payment address %1</source> + <translation>Invalid payment address %1</translation> + </message> + <message> + <source>Payment request rejected</source> + <translation>Payment request rejected</translation> + </message> + <message> + <source>Payment request network doesn't match client network.</source> + <translation>Payment request network doesn't match client network.</translation> + </message> + <message> + <source>Payment request is not initialized.</source> + <translation>Payment request is not initialised.</translation> + </message> + <message> + <source>Requested payment amount of %1 is too small (considered dust).</source> + <translation>Requested payment amount of %1 is too small (considered dust).</translation> + </message> + <message> + <source>Payment request error</source> + <translation>Payment request error</translation> + </message> + <message> + <source>Cannot start bitcoin: click-to-pay handler</source> + <translation>Cannot start bitcoin: click-to-pay handler</translation> + </message> + <message> + <source>Payment request fetch URL is invalid: %1</source> + <translation>Payment request fetch URL is invalid: %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 cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</translation> + </message> + <message> + <source>Payment request file handling</source> + <translation>Payment request file handling</translation> + </message> + <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>Payment request file cannot be read! This can be caused by an invalid payment request file.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Payment request expired.</translation> + </message> + <message> + <source>Unverified payment requests to custom payment scripts are unsupported.</source> + <translation>Unverified payment requests to custom payment scripts are unsupported.</translation> + </message> + <message> + <source>Invalid payment request.</source> + <translation>Invalid payment request.</translation> + </message> + <message> + <source>Refund from %1</source> + <translation>Refund from %1</translation> + </message> + <message> + <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source> + <translation>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</translation> + </message> + <message> + <source>Error communicating with %1: %2</source> + <translation>Error communicating with %1: %2</translation> + </message> + <message> + <source>Payment request cannot be parsed!</source> + <translation>Payment request cannot be parsed!</translation> + </message> + <message> + <source>Bad response from server %1</source> + <translation>Bad response from server %1</translation> + </message> + <message> + <source>Payment acknowledged</source> + <translation>Payment acknowledged</translation> + </message> + <message> + <source>Network request error</source> + <translation>Network request error</translation> + </message> +</context> +<context> + <name>PeerTableModel</name> + <message> + <source>User Agent</source> + <translation>User Agent</translation> + </message> + <message> + <source>Node/Service</source> + <translation>Node/Service</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Ping Time</translation> + </message> +</context> +<context> + <name>QObject</name> + <message> + <source>Amount</source> + <translation>Amount</translation> + </message> + <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>Enter a Bitcoin address (e.g. %1)</translation> + </message> + <message> + <source>%1 d</source> + <translation>%1 d</translation> + </message> + <message> + <source>%1 h</source> + <translation>%1 h</translation> + </message> + <message> + <source>%1 m</source> + <translation>%1 m</translation> + </message> + <message> + <source>%1 s</source> + <translation>%1 s</translation> + </message> + <message> + <source>None</source> + <translation>None</translation> + </message> + <message> + <source>N/A</source> + <translation>N/A</translation> + </message> + <message> + <source>%1 ms</source> + <translation>%1 ms</translation> + </message> +</context> +<context> + <name>QRImageWidget</name> + <message> + <source>&Save Image...</source> + <translation>&Save Image...</translation> + </message> + <message> + <source>&Copy Image</source> + <translation>&Copy Image</translation> + </message> + <message> + <source>Save QR Code</source> + <translation>Save QR Code</translation> + </message> + <message> + <source>PNG Image (*.png)</source> + <translation>PNG Image (*.png)</translation> + </message> +</context> +<context> + <name>RPCConsole</name> + <message> + <source>Client name</source> + <translation>Client name</translation> + </message> + <message> + <source>N/A</source> + <translation>N/A</translation> + </message> + <message> + <source>Client version</source> + <translation>Client version</translation> + </message> + <message> + <source>&Information</source> + <translation>&Information</translation> + </message> + <message> + <source>Debug window</source> + <translation>Debug window</translation> + </message> + <message> + <source>General</source> + <translation>General</translation> + </message> + <message> + <source>Using OpenSSL version</source> + <translation>Using OpenSSL version</translation> + </message> + <message> + <source>Using BerkeleyDB version</source> + <translation>Using BerkeleyDB version</translation> + </message> + <message> + <source>Startup time</source> + <translation>Startup time</translation> + </message> + <message> + <source>Network</source> + <translation>Network</translation> + </message> + <message> + <source>Name</source> + <translation>Name</translation> + </message> + <message> + <source>Number of connections</source> + <translation>Number of connections</translation> + </message> + <message> + <source>Block chain</source> + <translation>Block chain</translation> + </message> + <message> + <source>Current number of blocks</source> + <translation>Current number of blocks</translation> + </message> + <message> + <source>Memory Pool</source> + <translation>Memory Pool</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>Current number of transactions</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Memory usage</translation> + </message> + <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</translation> + </message> + <message> + <source>Received</source> + <translation>Received</translation> + </message> + <message> + <source>Sent</source> + <translation>Sent</translation> + </message> + <message> + <source>&Peers</source> + <translation>&Peers</translation> + </message> + <message> + <source>Banned peers</source> + <translation>Banned peers</translation> + </message> + <message> + <source>Select a peer to view detailed information.</source> + <translation>Select a peer to view detailed information.</translation> + </message> + <message> + <source>Whitelisted</source> + <translation>Whitelisted</translation> + </message> + <message> + <source>Direction</source> + <translation>Direction</translation> + </message> + <message> + <source>Version</source> + <translation>Version</translation> + </message> + <message> + <source>Starting Block</source> + <translation>Starting Block</translation> + </message> + <message> + <source>Synced Headers</source> + <translation>Synced Headers</translation> + </message> + <message> + <source>Synced Blocks</source> + <translation>Synced Blocks</translation> + </message> + <message> + <source>User Agent</source> + <translation>User Agent</translation> + </message> + <message> + <source>Services</source> + <translation>Services</translation> + </message> + <message> + <source>Ban Score</source> + <translation>Ban Score</translation> + </message> + <message> + <source>Connection Time</source> + <translation>Connection Time</translation> + </message> + <message> + <source>Last Send</source> + <translation>Last Send</translation> + </message> + <message> + <source>Last Receive</source> + <translation>Last Receive</translation> + </message> + <message> + <source>Ping Time</source> + <translation>Ping Time</translation> + </message> + <message> + <source>The duration of a currently outstanding ping.</source> + <translation>The duration of a currently outstanding ping.</translation> + </message> + <message> + <source>Ping Wait</source> + <translation>Ping Wait</translation> + </message> + <message> + <source>Time Offset</source> + <translation>Time Offset</translation> + </message> + <message> + <source>Last block time</source> + <translation>Last block time</translation> + </message> + <message> + <source>&Open</source> + <translation>&Open</translation> + </message> + <message> + <source>&Console</source> + <translation>&Console</translation> + </message> + <message> + <source>&Network Traffic</source> + <translation>&Network Traffic</translation> + </message> + <message> + <source>&Clear</source> + <translation>&Clear</translation> + </message> + <message> + <source>Totals</source> + <translation>Totals</translation> + </message> + <message> + <source>In:</source> + <translation>In:</translation> + </message> + <message> + <source>Out:</source> + <translation>Out:</translation> + </message> + <message> + <source>Build date</source> + <translation>Build date</translation> + </message> + <message> + <source>Debug log file</source> + <translation>Debug log file</translation> + </message> + <message> + <source>Clear console</source> + <translation>Clear console</translation> + </message> + <message> + <source>&Disconnect Node</source> + <translation>&Disconnect Node</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Ban Node for</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &hour</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &day</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &week</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &year</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>&Unban Node</translation> + </message> + <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Welcome to the Bitcoin Core RPC console.</translation> + </message> + <message> + <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> + <translation>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</translation> + </message> + <message> + <source>Type <b>help</b> for an overview of available commands.</source> + <translation>Type <b>help</b> for an overview of available commands.</translation> + </message> + <message> + <source>%1 B</source> + <translation>%1 B</translation> + </message> + <message> + <source>%1 KB</source> + <translation>%1 KB</translation> + </message> + <message> + <source>%1 MB</source> + <translation>%1 MB</translation> + </message> + <message> + <source>%1 GB</source> + <translation>%1 GB</translation> + </message> + <message> + <source>(node id: %1)</source> + <translation>(node id: %1)</translation> + </message> + <message> + <source>via %1</source> + <translation>via %1</translation> + </message> + <message> + <source>never</source> + <translation>never</translation> + </message> + <message> + <source>Inbound</source> + <translation>Inbound</translation> + </message> + <message> + <source>Outbound</source> + <translation>Outbound</translation> + </message> + <message> + <source>Yes</source> + <translation>Yes</translation> + </message> + <message> + <source>No</source> + <translation>No</translation> + </message> + <message> + <source>Unknown</source> + <translation>Unknown</translation> + </message> +</context> +<context> + <name>ReceiveCoinsDialog</name> + <message> + <source>&Amount:</source> + <translation>&Amount:</translation> + </message> + <message> + <source>&Label:</source> + <translation>&Label:</translation> + </message> + <message> + <source>&Message:</source> + <translation>&Message:</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>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.</translation> + </message> + <message> + <source>R&euse an existing receiving address (not recommended)</source> + <translation>R&euse an existing receiving address (not recommended)</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>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.</translation> + </message> + <message> + <source>An optional label to associate with the new receiving address.</source> + <translation>An optional label to associate with the new receiving address.</translation> + </message> + <message> + <source>Use this form to request payments. All fields are <b>optional</b>.</source> + <translation>Use this form to request payments. All fields are <b>optional</b>.</translation> + </message> + <message> + <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source> + <translation>An optional amount to request. Leave this empty or zero to not request a specific amount.</translation> + </message> + <message> + <source>Clear all fields of the form.</source> + <translation>Clear all fields of the form.</translation> + </message> + <message> + <source>Clear</source> + <translation>Clear</translation> + </message> + <message> + <source>Requested payments history</source> + <translation>Requested payments history</translation> + </message> + <message> + <source>&Request payment</source> + <translation>&Request payment</translation> + </message> + <message> + <source>Show the selected request (does the same as double clicking an entry)</source> + <translation>Show the selected request (does the same as double clicking an entry)</translation> + </message> + <message> + <source>Show</source> + <translation>Show</translation> + </message> + <message> + <source>Remove the selected entries from the list</source> + <translation>Remove the selected entries from the list</translation> + </message> + <message> + <source>Remove</source> + <translation>Remove</translation> + </message> + <message> + <source>Copy label</source> + <translation>Copy label</translation> + </message> + <message> + <source>Copy message</source> + <translation>Copy message</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Copy amount</translation> + </message> +</context> +<context> + <name>ReceiveRequestDialog</name> + <message> + <source>QR Code</source> + <translation>QR Code</translation> + </message> + <message> + <source>Copy &URI</source> + <translation>Copy &URI</translation> + </message> + <message> + <source>Copy &Address</source> + <translation>Copy &Address</translation> + </message> + <message> + <source>&Save Image...</source> + <translation>&Save Image...</translation> + </message> + <message> + <source>Request payment to %1</source> + <translation>Request payment to %1</translation> + </message> + <message> + <source>Payment information</source> + <translation>Payment information</translation> + </message> + <message> + <source>URI</source> + <translation>URI</translation> + </message> + <message> + <source>Address</source> + <translation>Address</translation> + </message> + <message> + <source>Amount</source> + <translation>Amount</translation> + </message> + <message> + <source>Label</source> + <translation>Label</translation> + </message> + <message> + <source>Message</source> + <translation>Message</translation> + </message> + <message> + <source>Resulting URI too long, try to reduce the text for label / message.</source> + <translation>Resulting URI too long, try to reduce the text for label / message.</translation> + </message> + <message> + <source>Error encoding URI into QR Code.</source> + <translation>Error encoding URI into QR Code.</translation> + </message> +</context> +<context> + <name>RecentRequestsTableModel</name> + <message> + <source>Date</source> + <translation>Date</translation> + </message> + <message> + <source>Label</source> + <translation>Label</translation> + </message> + <message> + <source>Message</source> + <translation>Message</translation> + </message> + <message> + <source>Amount</source> + <translation>Amount</translation> + </message> + <message> + <source>(no label)</source> + <translation>(no label)</translation> + </message> + <message> + <source>(no message)</source> + <translation>(no message)</translation> + </message> + <message> + <source>(no amount)</source> + <translation>(no amount)</translation> + </message> +</context> +<context> + <name>SendCoinsDialog</name> + <message> + <source>Send Coins</source> + <translation>Send Coins</translation> + </message> + <message> + <source>Coin Control Features</source> + <translation>Coin Control Features</translation> + </message> + <message> + <source>Inputs...</source> + <translation>Inputs...</translation> + </message> + <message> + <source>automatically selected</source> + <translation>automatically selected</translation> + </message> + <message> + <source>Insufficient funds!</source> + <translation>Insufficient funds!</translation> + </message> + <message> + <source>Quantity:</source> + <translation>Quantity:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Bytes:</translation> + </message> + <message> + <source>Amount:</source> + <translation>Amount:</translation> + </message> + <message> + <source>Priority:</source> + <translation>Priority:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Fee:</translation> + </message> + <message> + <source>After Fee:</source> + <translation>After Fee:</translation> + </message> + <message> + <source>Change:</source> + <translation>Change:</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>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</translation> + </message> + <message> + <source>Custom change address</source> + <translation>Custom change address</translation> + </message> + <message> + <source>Transaction Fee:</source> + <translation>Transaction Fee:</translation> + </message> + <message> + <source>Choose...</source> + <translation>Choose...</translation> + </message> + <message> + <source>collapse fee-settings</source> + <translation>collapse fee-settings</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>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.</translation> + </message> + <message> + <source>Hide</source> + <translation>Hide</translation> + </message> + <message> + <source>total at least</source> + <translation>total at least</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>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.</translation> + </message> + <message> + <source>(read the tooltip)</source> + <translation>(read the tooltip)</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Recommended:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Custom:</translation> + </message> + <message> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation>(Smart fee not initialised yet. This usually takes a few blocks...)</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Confirmation time:</translation> + </message> + <message> + <source>normal</source> + <translation>normal</translation> + </message> + <message> + <source>fast</source> + <translation>fast</translation> + </message> + <message> + <source>Send as zero-fee transaction if possible</source> + <translation>Send as zero-fee transaction if possible</translation> + </message> + <message> + <source>(confirmation may take longer)</source> + <translation>(confirmation may take longer)</translation> + </message> + <message> + <source>Send to multiple recipients at once</source> + <translation>Send to multiple recipients at once</translation> + </message> + <message> + <source>Add &Recipient</source> + <translation>Add &Recipient</translation> + </message> + <message> + <source>Clear all fields of the form.</source> + <translation>Clear all fields of the form.</translation> + </message> + <message> + <source>Dust:</source> + <translation>Dust:</translation> + </message> + <message> + <source>Clear &All</source> + <translation>Clear &All</translation> + </message> + <message> + <source>Balance:</source> + <translation>Balance:</translation> + </message> + <message> + <source>Confirm the send action</source> + <translation>Confirm the send action</translation> + </message> + <message> + <source>S&end</source> + <translation>S&end</translation> + </message> + <message> + <source>Confirm send coins</source> + <translation>Confirm send coins</translation> + </message> + <message> + <source>%1 to %2</source> + <translation>%1 to %2</translation> + </message> + <message> + <source>Copy quantity</source> + <translation>Copy quantity</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Copy amount</translation> + </message> + <message> + <source>Copy fee</source> + <translation>Copy fee</translation> + </message> + <message> + <source>Copy after fee</source> + <translation>Copy after fee</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Copy bytes</translation> + </message> + <message> + <source>Copy priority</source> + <translation>Copy priority</translation> + </message> + <message> + <source>Copy change</source> + <translation>Copy change</translation> + </message> + <message> + <source>Total Amount %1</source> + <translation>Total Amount %1</translation> + </message> + <message> + <source>or</source> + <translation>or</translation> + </message> + <message> + <source>The amount to pay must be larger than 0.</source> + <translation>The amount to pay must be larger than 0.</translation> + </message> + <message> + <source>The amount exceeds your balance.</source> + <translation>The amount exceeds your balance.</translation> + </message> + <message> + <source>The total exceeds your balance when the %1 transaction fee is included.</source> + <translation>The total exceeds your balance when the %1 transaction fee is included.</translation> + </message> + <message> + <source>Transaction creation failed!</source> + <translation>Transaction creation failed!</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>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.</translation> + </message> + <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>A fee higher than %1 is considered an absurdly high fee.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Payment request expired.</translation> + </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>Pay only the required fee of %1</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Estimated to begin confirmation within %n block.</numerusform><numerusform>Estimated to begin confirmation within %n blocks.</numerusform></translation> + </message> + <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>The recipient address is not valid. Please recheck.</translation> + </message> + <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Duplicate address found: addresses should only be used once each.</translation> + </message> + <message> + <source>Warning: Invalid Bitcoin address</source> + <translation>Warning: Invalid Bitcoin address</translation> + </message> + <message> + <source>(no label)</source> + <translation>(no label)</translation> + </message> + <message> + <source>Warning: Unknown change address</source> + <translation>Warning: Unknown change address</translation> + </message> + <message> + <source>Copy dust</source> + <translation>Copy dust</translation> + </message> + <message> + <source>Are you sure you want to send?</source> + <translation>Are you sure you want to send?</translation> + </message> + <message> + <source>added as transaction fee</source> + <translation>added as transaction fee</translation> + </message> +</context> +<context> + <name>SendCoinsEntry</name> + <message> + <source>A&mount:</source> + <translation>A&mount:</translation> + </message> + <message> + <source>Pay &To:</source> + <translation>Pay &To:</translation> + </message> + <message> + <source>Enter a label for this address to add it to your address book</source> + <translation>Enter a label for this address to add it to your address book</translation> + </message> + <message> + <source>&Label:</source> + <translation>&Label:</translation> + </message> + <message> + <source>Choose previously used address</source> + <translation>Choose previously used address</translation> + </message> + <message> + <source>This is a normal payment.</source> + <translation>This is a normal payment.</translation> + </message> + <message> + <source>The Bitcoin address to send the payment to</source> + <translation>The Bitcoin address to send the payment to</translation> + </message> + <message> + <source>Alt+A</source> + <translation>Alt+A</translation> + </message> + <message> + <source>Paste address from clipboard</source> + <translation>Paste address from clipboard</translation> + </message> + <message> + <source>Alt+P</source> + <translation>Alt+P</translation> + </message> + <message> + <source>Remove this entry</source> + <translation>Remove this entry</translation> + </message> + <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>S&ubtract fee from amount</translation> + </message> + <message> + <source>Message:</source> + <translation>Message:</translation> + </message> + <message> + <source>This is an unauthenticated payment request.</source> + <translation>This is an unauthenticated payment request.</translation> + </message> + <message> + <source>This is an authenticated payment request.</source> + <translation>This is an authenticated payment request.</translation> + </message> + <message> + <source>Enter a label for this address to add it to the list of used addresses</source> + <translation>Enter a label for this address to add it to the list of used addresses</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>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.</translation> + </message> + <message> + <source>Pay To:</source> + <translation>Pay To:</translation> + </message> + <message> + <source>Memo:</source> + <translation>Memo:</translation> + </message> +</context> +<context> + <name>ShutdownWindow</name> + <message> + <source>Bitcoin Core is shutting down...</source> + <translation>Bitcoin Core is shutting down...</translation> + </message> + <message> + <source>Do not shut down the computer until this window disappears.</source> + <translation>Do not shut down the computer until this window disappears.</translation> + </message> +</context> +<context> + <name>SignVerifyMessageDialog</name> + <message> + <source>Signatures - Sign / Verify a Message</source> + <translation>Signatures - Sign / Verify a Message</translation> + </message> + <message> + <source>&Sign Message</source> + <translation>&Sign Message</translation> + </message> + <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</translation> + </message> + <message> + <source>The Bitcoin address to sign the message with</source> + <translation>The Bitcoin address to sign the message with</translation> + </message> + <message> + <source>Choose previously used address</source> + <translation>Choose previously used address</translation> + </message> + <message> + <source>Alt+A</source> + <translation>Alt+A</translation> + </message> + <message> + <source>Paste address from clipboard</source> + <translation>Paste address from clipboard</translation> + </message> + <message> + <source>Alt+P</source> + <translation>Alt+P</translation> + </message> + <message> + <source>Enter the message you want to sign here</source> + <translation>Enter the message you want to sign here</translation> + </message> + <message> + <source>Signature</source> + <translation>Signature</translation> + </message> + <message> + <source>Copy the current signature to the system clipboard</source> + <translation>Copy the current signature to the system clipboard</translation> + </message> + <message> + <source>Sign the message to prove you own this Bitcoin address</source> + <translation>Sign the message to prove you own this Bitcoin address</translation> + </message> + <message> + <source>Sign &Message</source> + <translation>Sign &Message</translation> + </message> + <message> + <source>Reset all sign message fields</source> + <translation>Reset all sign message fields</translation> + </message> + <message> + <source>Clear &All</source> + <translation>Clear &All</translation> + </message> + <message> + <source>&Verify Message</source> + <translation>&Verify Message</translation> + </message> + <message> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</translation> + </message> + <message> + <source>The Bitcoin address the message was signed with</source> + <translation>The Bitcoin address the message was signed with</translation> + </message> + <message> + <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> + <translation>Verify the message to ensure it was signed with the specified Bitcoin address</translation> + </message> + <message> + <source>Verify &Message</source> + <translation>Verify &Message</translation> + </message> + <message> + <source>Reset all verify message fields</source> + <translation>Reset all verify message fields</translation> + </message> + <message> + <source>Click "Sign Message" to generate signature</source> + <translation>Click "Sign Message" to generate signature</translation> + </message> + <message> + <source>The entered address is invalid.</source> + <translation>The entered address is invalid.</translation> + </message> + <message> + <source>Please check the address and try again.</source> + <translation>Please check the address and try again.</translation> + </message> + <message> + <source>The entered address does not refer to a key.</source> + <translation>The entered address does not refer to a key.</translation> + </message> + <message> + <source>Wallet unlock was cancelled.</source> + <translation>Wallet unlock was cancelled.</translation> + </message> + <message> + <source>Private key for the entered address is not available.</source> + <translation>Private key for the entered address is not available.</translation> + </message> + <message> + <source>Message signing failed.</source> + <translation>Message signing failed.</translation> + </message> + <message> + <source>Message signed.</source> + <translation>Message signed.</translation> + </message> + <message> + <source>The signature could not be decoded.</source> + <translation>The signature could not be decoded.</translation> + </message> + <message> + <source>Please check the signature and try again.</source> + <translation>Please check the signature and try again.</translation> + </message> + <message> + <source>The signature did not match the message digest.</source> + <translation>The signature did not match the message digest.</translation> + </message> + <message> + <source>Message verification failed.</source> + <translation>Message verification failed.</translation> + </message> + <message> + <source>Message verified.</source> + <translation>Message verified.</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>The Bitcoin Core developers</translation> + </message> + <message> + <source>[testnet]</source> + <translation>[testnet]</translation> + </message> +</context> +<context> + <name>TrafficGraphWidget</name> + <message> + <source>KB/s</source> + <translation>KB/s</translation> + </message> +</context> +<context> + <name>TransactionDesc</name> + <message> + <source>Open until %1</source> + <translation>Open until %1</translation> + </message> + <message> + <source>conflicted</source> + <translation>conflicted</translation> + </message> + <message> + <source>%1/offline</source> + <translation>%1/offline</translation> + </message> + <message> + <source>%1/unconfirmed</source> + <translation>%1/unconfirmed</translation> + </message> + <message> + <source>%1 confirmations</source> + <translation>%1 confirmations</translation> + </message> + <message> + <source>Status</source> + <translation>Status</translation> + </message> + <message numerus="yes"> + <source>, broadcast through %n node(s)</source> + <translation><numerusform>, broadcast through %n node</numerusform><numerusform>, broadcast through %n nodes</numerusform></translation> + </message> + <message> + <source>Date</source> + <translation>Date</translation> + </message> + <message> + <source>Source</source> + <translation>Source</translation> + </message> + <message> + <source>Generated</source> + <translation>Generated</translation> + </message> + <message> + <source>From</source> + <translation>From</translation> + </message> + <message> + <source>To</source> + <translation>To</translation> + </message> + <message> + <source>own address</source> + <translation>own address</translation> + </message> + <message> + <source>watch-only</source> + <translation>watch-only</translation> + </message> + <message> + <source>label</source> + <translation>label</translation> + </message> + <message> + <source>Credit</source> + <translation>Credit</translation> + </message> + <message numerus="yes"> + <source>matures in %n more block(s)</source> + <translation><numerusform>matures in %n more block</numerusform><numerusform>matures in %n more blocks</numerusform></translation> + </message> + <message> + <source>not accepted</source> + <translation>not accepted</translation> + </message> + <message> + <source>Debit</source> + <translation>Debit</translation> + </message> + <message> + <source>Total debit</source> + <translation>Total debit</translation> + </message> + <message> + <source>Total credit</source> + <translation>Total credit</translation> + </message> + <message> + <source>Transaction fee</source> + <translation>Transaction fee</translation> + </message> + <message> + <source>Net amount</source> + <translation>Net amount</translation> + </message> + <message> + <source>Message</source> + <translation>Message</translation> + </message> + <message> + <source>Comment</source> + <translation>Comment</translation> + </message> + <message> + <source>Transaction ID</source> + <translation>Transaction ID</translation> + </message> + <message> + <source>Merchant</source> + <translation>Merchant</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>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.</translation> + </message> + <message> + <source>Debug information</source> + <translation>Debug information</translation> + </message> + <message> + <source>Transaction</source> + <translation>Transaction</translation> + </message> + <message> + <source>Inputs</source> + <translation>Inputs</translation> + </message> + <message> + <source>Amount</source> + <translation>Amount</translation> + </message> + <message> + <source>true</source> + <translation>true</translation> + </message> + <message> + <source>false</source> + <translation>false</translation> + </message> + <message> + <source>, has not been successfully broadcast yet</source> + <translation>, has not been successfully broadcast yet</translation> + </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Open for %n more block</numerusform><numerusform>Open for %n more blocks</numerusform></translation> + </message> + <message> + <source>unknown</source> + <translation>unknown</translation> + </message> +</context> +<context> + <name>TransactionDescDialog</name> + <message> + <source>Transaction details</source> + <translation>Transaction details</translation> + </message> + <message> + <source>This pane shows a detailed description of the transaction</source> + <translation>This pane shows a detailed description of the transaction</translation> + </message> +</context> +<context> + <name>TransactionTableModel</name> + <message> + <source>Date</source> + <translation>Date</translation> + </message> + <message> + <source>Type</source> + <translation>Type</translation> + </message> + <message> + <source>Immature (%1 confirmations, will be available after %2)</source> + <translation>Immature (%1 confirmations, will be available after %2)</translation> + </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Open for %n more block</numerusform><numerusform>Open for %n more blocks</numerusform></translation> + </message> + <message> + <source>Open until %1</source> + <translation>Open until %1</translation> + </message> + <message> + <source>Confirmed (%1 confirmations)</source> + <translation>Confirmed (%1 confirmations)</translation> + </message> + <message> + <source>This block was not received by any other nodes and will probably not be accepted!</source> + <translation>This block was not received by any other nodes and will probably not be accepted!</translation> + </message> + <message> + <source>Generated but not accepted</source> + <translation>Generated but not accepted</translation> + </message> + <message> + <source>Offline</source> + <translation>Offline</translation> + </message> + <message> + <source>Label</source> + <translation>Label</translation> + </message> + <message> + <source>Unconfirmed</source> + <translation>Unconfirmed</translation> + </message> + <message> + <source>Confirming (%1 of %2 recommended confirmations)</source> + <translation>Confirming (%1 of %2 recommended confirmations)</translation> + </message> + <message> + <source>Conflicted</source> + <translation>Conflicted</translation> + </message> + <message> + <source>Received with</source> + <translation>Received with</translation> + </message> + <message> + <source>Received from</source> + <translation>Received from</translation> + </message> + <message> + <source>Sent to</source> + <translation>Sent to</translation> + </message> + <message> + <source>Payment to yourself</source> + <translation>Payment to yourself</translation> + </message> + <message> + <source>Mined</source> + <translation>Mined</translation> + </message> + <message> + <source>watch-only</source> + <translation>watch-only</translation> + </message> + <message> + <source>(n/a)</source> + <translation>(n/a)</translation> + </message> + <message> + <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> + <message> + <source>Date and time that the transaction was received.</source> + <translation>Date and time that the transaction was received.</translation> + </message> + <message> + <source>Type of transaction.</source> + <translation>Type of transaction.</translation> + </message> + <message> + <source>Whether or not a watch-only address is involved in this transaction.</source> + <translation>Whether or not a watch-only address is involved in this transaction.</translation> + </message> + <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>User-defined intent/purpose of the transaction.</translation> + </message> + <message> + <source>Amount removed from or added to balance.</source> + <translation>Amount removed from or added to balance.</translation> + </message> +</context> +<context> + <name>TransactionView</name> + <message> + <source>All</source> + <translation>All</translation> + </message> + <message> + <source>Today</source> + <translation>Today</translation> + </message> + <message> + <source>This week</source> + <translation>This week</translation> + </message> + <message> + <source>This month</source> + <translation>This month</translation> + </message> + <message> + <source>Last month</source> + <translation>Last month</translation> + </message> + <message> + <source>This year</source> + <translation>This year</translation> + </message> + <message> + <source>Range...</source> + <translation>Range...</translation> + </message> + <message> + <source>Received with</source> + <translation>Received with</translation> + </message> + <message> + <source>Sent to</source> + <translation>Sent to</translation> + </message> + <message> + <source>To yourself</source> + <translation>To yourself</translation> + </message> + <message> + <source>Mined</source> + <translation>Mined</translation> + </message> + <message> + <source>Other</source> + <translation>Other</translation> + </message> + <message> + <source>Enter address or label to search</source> + <translation>Enter address or label to search</translation> + </message> + <message> + <source>Min amount</source> + <translation>Min amount</translation> + </message> + <message> + <source>Copy address</source> + <translation>Copy address</translation> + </message> + <message> + <source>Copy label</source> + <translation>Copy label</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Copy amount</translation> + </message> + <message> + <source>Copy transaction ID</source> + <translation>Copy transaction ID</translation> + </message> + <message> + <source>Copy raw transaction</source> + <translation>Copy raw transaction</translation> + </message> + <message> + <source>Edit label</source> + <translation>Edit label</translation> + </message> + <message> + <source>Show transaction details</source> + <translation>Show transaction details</translation> + </message> + <message> + <source>Export Transaction History</source> + <translation>Export Transaction History</translation> + </message> + <message> + <source>Watch-only</source> + <translation>Watch-only</translation> + </message> + <message> + <source>Exporting Failed</source> + <translation>Exporting Failed</translation> + </message> + <message> + <source>There was an error trying to save the transaction history to %1.</source> + <translation>There was an error trying to save the transaction history to %1.</translation> + </message> + <message> + <source>Exporting Successful</source> + <translation>Exporting Successful</translation> + </message> + <message> + <source>The transaction history was successfully saved to %1.</source> + <translation>The transaction history was successfully saved to %1.</translation> + </message> + <message> + <source>Comma separated file (*.csv)</source> + <translation>Comma separated file (*.csv)</translation> + </message> + <message> + <source>Confirmed</source> + <translation>Confirmed</translation> + </message> + <message> + <source>Date</source> + <translation>Date</translation> + </message> + <message> + <source>Type</source> + <translation>Type</translation> + </message> + <message> + <source>Label</source> + <translation>Label</translation> + </message> + <message> + <source>Address</source> + <translation>Address</translation> + </message> + <message> + <source>ID</source> + <translation>ID</translation> + </message> + <message> + <source>Range:</source> + <translation>Range:</translation> + </message> + <message> + <source>to</source> + <translation>to</translation> + </message> +</context> +<context> + <name>UnitDisplayStatusBarControl</name> + <message> + <source>Unit to show amounts in. Click to select another unit.</source> + <translation>Unit to show amounts in. Click to select another unit.</translation> + </message> +</context> +<context> + <name>WalletFrame</name> + <message> + <source>No wallet has been loaded.</source> + <translation>No wallet has been loaded.</translation> + </message> +</context> +<context> + <name>WalletModel</name> + <message> + <source>Send Coins</source> + <translation>Send Coins</translation> + </message> +</context> +<context> + <name>WalletView</name> + <message> + <source>&Export</source> + <translation>&Export</translation> + </message> + <message> + <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> + <message> + <source>Backup Wallet</source> + <translation>Backup Wallet</translation> + </message> + <message> + <source>Wallet Data (*.dat)</source> + <translation>Wallet Data (*.dat)</translation> + </message> + <message> + <source>Backup Failed</source> + <translation>Backup Failed</translation> + </message> + <message> + <source>There was an error trying to save the wallet data to %1.</source> + <translation>There was an error trying to save the wallet data to %1.</translation> + </message> + <message> + <source>The wallet data was successfully saved to %1.</source> + <translation>The wallet data was successfully saved to %1.</translation> + </message> + <message> + <source>Backup Successful</source> + <translation>Backup Successful</translation> + </message> +</context> +<context> + <name>bitcoin-core</name> + <message> + <source>Options:</source> + <translation>Options:</translation> + </message> + <message> + <source>Specify data directory</source> + <translation>Specify data directory</translation> + </message> + <message> + <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> + <source>Specify your own public address</source> + <translation>Specify your own public address</translation> + </message> + <message> + <source>Accept command line and JSON-RPC commands</source> + <translation>Accept command line and JSON-RPC commands</translation> + </message> + <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>If <category> is not supplied or if <category> = 1, output all debugging information.</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>Prune configured below the minimum of %d MiB. Please use a higher number.</translation> + </message> + <message> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Error: A fatal internal error occurred, see debug.log for details</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Fee (in %s/kB) to add to transactions you send (default: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Pruning blockstore...</translation> + </message> + <message> + <source>Run in the background as a daemon and accept commands</source> + <translation>Run in the background as a daemon and accept commands</translation> + </message> + <message> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>Unable to start HTTP server. See debug log for details.</translation> + </message> + <message> + <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> + <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> + <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> + <translation>Delete all wallet transactions and only recover those parts of the blockchain through -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>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</translation> + </message> + <message> + <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> + <translation>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</translation> + </message> + <message> + <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> + <translation>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</translation> + </message> + <message> + <source>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</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>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</translation> + </message> + <message> + <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source> + <translation>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</translation> + </message> + <message> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</translation> + </message> + <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</translation> + </message> + <message> + <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> + <translation>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</translation> + </message> + <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>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</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>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> + <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source> + <translation>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</translation> + </message> + <message> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool must be at least %d MB</translation> + </message> + <message> + <source><category> can be:</source> + <translation><category> can be:</translation> + </message> + <message> + <source>Block creation options:</source> + <translation>Block creation options:</translation> + </message> + <message> + <source>Connect only to the specified node(s)</source> + <translation>Connect only to the specified node(s)</translation> + </message> + <message> + <source>Connection options:</source> + <translation>Connection options:</translation> + </message> + <message> + <source>Corrupted block database detected</source> + <translation>Corrupted block database detected</translation> + </message> + <message> + <source>Debugging/Testing options:</source> + <translation>Debugging/Testing options:</translation> + </message> + <message> + <source>Do not load the wallet and disable wallet RPC calls</source> + <translation>Do not load the wallet and disable wallet RPC calls</translation> + </message> + <message> + <source>Do you want to rebuild the block database now?</source> + <translation>Do you want to rebuild the block database now?</translation> + </message> + <message> + <source>Enable publish hash block in <address></source> + <translation>Enable publish hash block in <address></translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>Enable publish hash transaction in <address></translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>Enable publish raw block in <address></translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation>Enable publish raw transaction in <address></translation> + </message> + <message> + <source>Error initializing block database</source> + <translation>Error initialising block database</translation> + </message> + <message> + <source>Error initializing wallet database environment %s!</source> + <translation>Error initialising wallet database environment %s!</translation> + </message> + <message> + <source>Error loading block database</source> + <translation>Error loading block database</translation> + </message> + <message> + <source>Error opening block database</source> + <translation>Error opening block database</translation> + </message> + <message> + <source>Error: Disk space is low!</source> + <translation>Error: Disk space is low!</translation> + </message> + <message> + <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> + <source>Importing...</source> + <translation>Importing...</translation> + </message> + <message> + <source>Incorrect or no genesis block found. Wrong datadir for network?</source> + <translation>Incorrect or no genesis block found. Wrong datadir for network?</translation> + </message> + <message> + <source>Invalid -onion address: '%s'</source> + <translation>Invalid -onion address: '%s'</translation> + </message> + <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>Keep the transaction memory pool below <n> megabytes (default: %u)</translation> + </message> + <message> + <source>Not enough file descriptors available.</source> + <translation>Not enough file descriptors available.</translation> + </message> + <message> + <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> + <translation>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</translation> + </message> + <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>Prune cannot be configured with a negative value.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Prune mode is incompatible with -txindex.</translation> + </message> + <message> + <source>Set database cache size in megabytes (%d to %d, default: %d)</source> + <translation>Set database cache size in megabytes (%d to %d, default: %d)</translation> + </message> + <message> + <source>Set maximum block size in bytes (default: %d)</source> + <translation>Set maximum block size in bytes (default: %d)</translation> + </message> + <message> + <source>Specify wallet file (within data directory)</source> + <translation>Specify wallet file (within data directory)</translation> + </message> + <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Unsupported argument -benchmark ignored, use -debug=bench.</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Unsupported argument -debugnet ignored, use -debug=net.</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>Unsupported argument -tor found, use -onion.</translation> + </message> + <message> + <source>Use UPnP to map the listening port (default: %u)</source> + <translation>Use UPnP to map the listening port (default: %u)</translation> + </message> + <message> + <source>User Agent comment (%s) contains unsafe characters.</source> + <translation>User Agent comment (%s) contains unsafe characters.</translation> + </message> + <message> + <source>Verifying blocks...</source> + <translation>Verifying blocks...</translation> + </message> + <message> + <source>Verifying wallet...</source> + <translation>Verifying wallet...</translation> + </message> + <message> + <source>Wallet %s resides outside data directory %s</source> + <translation>Wallet %s resides outside data directory %s</translation> + </message> + <message> + <source>Wallet options:</source> + <translation>Wallet options:</translation> + </message> + <message> + <source>Warning: This version is obsolete; upgrade required!</source> + <translation>Warning: This version is obsolete; upgrade required!</translation> + </message> + <message> + <source>You need to rebuild the database using -reindex to change -txindex</source> + <translation>You need to rebuild the database using -reindex to change -txindex</translation> + </message> + <message> + <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>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</translation> + </message> + <message> + <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> + <translation>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for 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>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)</translation> + </message> + <message> + <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> + <translation>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</translation> + </message> + <message> + <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> + <translation>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</translation> + </message> + <message> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</translation> + </message> + <message> + <source>Error: Listening for incoming connections failed (listen returned error %s)</source> + <translation>Error: Listening for incoming connections failed (listen returned error %s)</translation> + </message> + <message> + <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source> + <translation>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</translation> + </message> + <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</translation> + </message> + <message> + <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> + <translation>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</translation> + </message> + <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> + <translation>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</translation> + </message> + <message> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>Maximum size of data in data carrier transactions we relay and mine (default: %u)</translation> + </message> + <message> + <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> + <translation>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</translation> + </message> + <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Randomise credentials for every proxy connection. This enables Tor stream isolation (default: %u)</translation> + </message> + <message> + <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> + <translation>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</translation> + </message> + <message> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <translation>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</translation> + </message> + <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>The transaction amount is too small to send after the fee has been deducted</translation> + </message> + <message> + <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> + <translation>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</translation> + </message> + <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>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</translation> + </message> + <message> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(default: %u)</translation> + </message> + <message> + <source>Accept public REST requests (default: %u)</source> + <translation>Accept public REST requests (default: %u)</translation> + </message> + <message> + <source>Activating best chain...</source> + <translation>Activating best chain...</translation> + </message> + <message> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>Always relay transactions received from whitelisted peers (default: %d)</translation> + </message> + <message> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Attempt to recover private keys from a corrupt wallet.dat on startup</translation> + </message> + <message> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Automatically create Tor hidden service (default: %d)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Cannot resolve -whitebind address: '%s'</translation> + </message> + <message> + <source>Connect through SOCKS5 proxy</source> + <translation>Connect through SOCKS5 proxy</translation> + </message> + <message> + <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> + <translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation> + </message> + <message> + <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> + <translation>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</translation> + </message> + <message> + <source>Error reading from database, shutting down.</source> + <translation>Error reading from database, shutting down.</translation> + </message> + <message> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Imports blocks from external blk000??.dat file on startup</translation> + </message> + <message> + <source>Information</source> + <translation>Information</translation> + </message> + <message> + <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source> + <translation>Initialisation sanity check failed. Bitcoin Core is shutting down.</translation> + </message> + <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Invalid amount for -maxtxfee=<amount>: '%s'</translation> + </message> + <message> + <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> + <translation>Invalid amount for -minrelaytxfee=<amount>: '%s'</translation> + </message> + <message> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>Invalid amount for -mintxfee=<amount>: '%s'</translation> + </message> + <message> + <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> + <translation>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</translation> + </message> + <message> + <source>Invalid netmask specified in -whitelist: '%s'</source> + <translation>Invalid netmask specified in -whitelist: '%s'</translation> + </message> + <message> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Keep at most <n> unconnectable transactions in memory (default: %u)</translation> + </message> + <message> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>Need to specify a port with -whitebind: '%s'</translation> + </message> + <message> + <source>Node relay options:</source> + <translation>Node relay options:</translation> + </message> + <message> + <source>RPC server options:</source> + <translation>RPC server options:</translation> + </message> + <message> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Rebuild block chain index from current blk000??.dat files on startup</translation> + </message> + <message> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Receive and display P2P network alerts (default: %u)</translation> + </message> + <message> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> + <translation>Reducing -maxconnections from %d to %d, because of system limitations.</translation> + </message> + <message> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Rescan the block chain for missing wallet transactions on startup</translation> + </message> + <message> + <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> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Send transactions as zero-fee transactions if possible (default: %u)</translation> + </message> + <message> + <source>Show all debugging options (usage: --help -help-debug)</source> + <translation>Show all debugging options (usage: --help -help-debug)</translation> + </message> + <message> + <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> + <translation>Shrink debug.log file on client startup (default: 1 when no -debug)</translation> + </message> + <message> + <source>Signing transaction failed</source> + <translation>Signing transaction failed</translation> + </message> + <message> + <source>The transaction amount is too small to pay the fee</source> + <translation>The transaction amount is too small to pay the fee</translation> + </message> + <message> + <source>This is experimental software.</source> + <translation>This is experimental software.</translation> + </message> + <message> + <source>Tor control port password (default: empty)</source> + <translation>Tor control port password (default: empty)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>Tor control port to use if onion listening enabled (default: %s)</translation> + </message> + <message> + <source>Transaction amount too small</source> + <translation>Transaction amount too small</translation> + </message> + <message> + <source>Transaction amounts must be positive</source> + <translation>Transaction amounts must be positive</translation> + </message> + <message> + <source>Transaction too large for fee policy</source> + <translation>Transaction too large for fee policy</translation> + </message> + <message> + <source>Transaction too large</source> + <translation>Transaction too large</translation> + </message> + <message> + <source>Unable to bind to %s on this computer (bind returned error %s)</source> + <translation>Unable to bind to %s on this computer (bind returned error %s)</translation> + </message> + <message> + <source>Upgrade wallet to latest format on startup</source> + <translation>Upgrade wallet to latest format on startup</translation> + </message> + <message> + <source>Username for JSON-RPC connections</source> + <translation>Username for JSON-RPC connections</translation> + </message> + <message> + <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source> + <translation>Wallet needed to be rewritten: restart Bitcoin Core to complete</translation> + </message> + <message> + <source>Warning</source> + <translation>Warning</translation> + </message> + <message> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>Whether to operate in a blocks only mode (default: %u)</translation> + </message> + <message> + <source>Zapping all transactions from wallet...</source> + <translation>Zapping all transactions from wallet...</translation> + </message> + <message> + <source>ZeroMQ notification options:</source> + <translation>ZeroMQ notification options:</translation> + </message> + <message> + <source>wallet.dat corrupt, salvage failed</source> + <translation>wallet.dat corrupt, salvage failed</translation> + </message> + <message> + <source>Password for JSON-RPC connections</source> + <translation>Password for JSON-RPC connections</translation> + </message> + <message> + <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> + <source>This help message</source> + <translation>This help message</translation> + </message> + <message> + <source>Allow DNS lookups for -addnode, -seednode and -connect</source> + <translation>Allow DNS lookups for -addnode, -seednode and -connect</translation> + </message> + <message> + <source>Loading addresses...</source> + <translation>Loading addresses...</translation> + </message> + <message> + <source>Error loading wallet.dat: Wallet corrupted</source> + <translation>Error loading wallet.dat: Wallet corrupted</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 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</translation> + </message> + <message> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</translation> + </message> + <message> + <source>-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> + <translation>-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</translation> + </message> + <message> + <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>Do not keep transactions in the mempool longer than <n> hours (default: %u)</translation> + </message> + <message> + <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> + <translation>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</translation> + </message> + <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</translation> + </message> + <message> + <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> + <translation>How thorough the block verification of -checkblocks is (0-4, default: %u)</translation> + </message> + <message> + <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source> + <translation>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</translation> + </message> + <message> + <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> + <translation>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</translation> + </message> + <message> + <source>Output debugging information (default: %u, supplying <category> is optional)</source> + <translation>Output debugging information (default: %u, supplying <category> is optional)</translation> + </message> + <message> + <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> + <translation>Support filtering of blocks and transaction with bloom filters (default: %u)</translation> + </message> + <message> + <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> + <translation>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</translation> + </message> + <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</translation> + </message> + <message> + <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</translation> + </message> + <message> + <source>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source> + <translation>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</translation> + </message> + <message> + <source>(default: %s)</source> + <translation>(default: %s)</translation> + </message> + <message> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <translation>Always query for peer addresses via DNS lookup (default: %u)</translation> + </message> + <message> + <source>Error loading wallet.dat</source> + <translation>Error loading wallet.dat</translation> + </message> + <message> + <source>Generate coins (default: %u)</source> + <translation>Generate coins (default: %u)</translation> + </message> + <message> + <source>How many blocks to check at startup (default: %u, 0 = all)</source> + <translation>How many blocks to check at startup (default: %u, 0 = all)</translation> + </message> + <message> + <source>Include IP addresses in debug output (default: %u)</source> + <translation>Include IP addresses in debug output (default: %u)</translation> + </message> + <message> + <source>Invalid -proxy address: '%s'</source> + <translation>Invalid -proxy address: '%s'</translation> + </message> + <message> + <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> + <translation>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</translation> + </message> + <message> + <source>Listen for connections on <port> (default: %u or testnet: %u)</source> + <translation>Listen for connections on <port> (default: %u or testnet: %u)</translation> + </message> + <message> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Maintain at most <n> connections to peers (default: %u)</translation> + </message> + <message> + <source>Make the wallet broadcast transactions</source> + <translation>Make the wallet broadcast transactions</translation> + </message> + <message> + <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> + <translation>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</translation> + </message> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <translation>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</translation> + </message> + <message> + <source>Prepend debug output with timestamp (default: %u)</source> + <translation>Prepend debug output with timestamp (default: %u)</translation> + </message> + <message> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Relay and mine data carrier transactions (default: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <translation>Relay non-P2SH multisig (default: %u)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Set key pool size to <n> (default: %u)</translation> + </message> + <message> + <source>Set minimum block size in bytes (default: %u)</source> + <translation>Set minimum block size in bytes (default: %u)</translation> + </message> + <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <translation>Set the number of threads to service RPC calls (default: %d)</translation> + </message> + <message> + <source>Specify configuration file (default: %s)</source> + <translation>Specify configuration file (default: %s)</translation> + </message> + <message> + <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> + <translation>Specify connection timeout in milliseconds (minimum: 1, default: %d)</translation> + </message> + <message> + <source>Specify pid file (default: %s)</source> + <translation>Specify pid file (default: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <translation>Spend unconfirmed change when sending transactions (default: %u)</translation> + </message> + <message> + <source>Threshold for disconnecting misbehaving peers (default: %u)</source> + <translation>Threshold for disconnecting misbehaving peers (default: %u)</translation> + </message> + <message> + <source>Unknown network specified in -onlynet: '%s'</source> + <translation>Unknown network specified in -onlynet: '%s'</translation> + </message> + <message> + <source>Cannot resolve -bind address: '%s'</source> + <translation>Cannot resolve -bind address: '%s'</translation> + </message> + <message> + <source>Cannot resolve -externalip address: '%s'</source> + <translation>Cannot resolve -externalip address: '%s'</translation> + </message> + <message> + <source>Invalid amount for -paytxfee=<amount>: '%s'</source> + <translation>Invalid amount for -paytxfee=<amount>: '%s'</translation> + </message> + <message> + <source>Insufficient funds</source> + <translation>Insufficient funds</translation> + </message> + <message> + <source>Loading block index...</source> + <translation>Loading block index...</translation> + </message> + <message> + <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> + <source>Loading wallet...</source> + <translation>Loading wallet...</translation> + </message> + <message> + <source>Cannot downgrade wallet</source> + <translation>Cannot downgrade wallet</translation> + </message> + <message> + <source>Cannot write default address</source> + <translation>Cannot write default address</translation> + </message> + <message> + <source>Rescanning...</source> + <translation>Rescanning...</translation> + </message> + <message> + <source>Done loading</source> + <translation>Done loading</translation> + </message> + <message> + <source>Error</source> + <translation>Error</translation> + </message> +</context> +</TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts index 17ce494f91..ab8dd65f81 100644 --- a/src/qt/locale/bitcoin_eo.ts +++ b/src/qt/locale/bitcoin_eo.ts @@ -1,4 +1,4 @@ -<TS language="eo" version="2.0"> +<TS language="eo" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -209,6 +209,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -406,10 +409,22 @@ <source>No block source available...</source> <translation>Neniu fonto de blokoj trovebla...</translation> </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n tago</numerusform><numerusform>%n tagoj</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n semajno</numerusform><numerusform>%n semajnoj</numerusform></translation> + </message> <message> <source>%1 and %2</source> <translation>%1 kaj %2</translation> </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n jaro</numerusform><numerusform>%n jaroj</numerusform></translation> + </message> <message> <source>%1 behind</source> <translation>mankas %1</translation> @@ -443,6 +458,30 @@ <translation>Ĝisdatigante...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Dato: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Sumo: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tipo: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Etikedo: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Sendita transakcio</translation> </message> @@ -773,7 +812,7 @@ <source>command-line options</source> <translation>komandliniaj agordaĵoj</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -851,6 +890,14 @@ <translation>MB</translation> </message> <message> + <source>Accept connections from outside</source> + <translation>Akcepti konektojn el ekstere</translation> + </message> + <message> + <source>Allow incoming connections</source> + <translation>Permesi envenantajn konektojn</translation> + </message> + <message> <source>Reset all client options to default.</source> <translation>Reagordi ĉion al defaŭlataj valoroj.</translation> </message> @@ -863,6 +910,10 @@ <translation>&Reto</translation> </message> <message> + <source>W&allet</source> + <translation>Monujo</translation> + </message> + <message> <source>Expert</source> <translation>Fakulo</translation> </message> @@ -887,6 +938,14 @@ <translation>la pordo de la prokurilo (ekz. 9050)</translation> </message> <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> <source>&Window</source> <translation>&Fenestro</translation> </message> @@ -974,6 +1033,10 @@ <translation>Minita saldo, kiu ankoraŭ ne maturiĝis</translation> </message> <message> + <source>Balances</source> + <translation>Saldoj</translation> + </message> + <message> <source>Total:</source> <translation>Totalo:</translation> </message> @@ -981,6 +1044,14 @@ <source>Your current total balance</source> <translation>via aktuala totala saldo</translation> </message> + <message> + <source>Spendable:</source> + <translation>Elspezebla:</translation> + </message> + <message> + <source>Recent transactions</source> + <translation>Lastaj transakcioj</translation> + </message> </context> <context> <name>PaymentServer</name> @@ -1043,6 +1114,10 @@ <translation>%1 m</translation> </message> <message> + <source>None</source> + <translation>Neniu</translation> + </message> + <message> <source>N/A</source> <translation>neaplikebla</translation> </message> @@ -1121,8 +1196,20 @@ <translation>Aktuala nombro de blokoj</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Bajtoj Senditaj:</translation> + <source>Received</source> + <translation>Ricevita</translation> + </message> + <message> + <source>Sent</source> + <translation>Sendita</translation> + </message> + <message> + <source>Version</source> + <translation>Versio</translation> + </message> + <message> + <source>Services</source> + <translation>Servoj</translation> </message> <message> <source>Last block time</source> @@ -1377,6 +1464,10 @@ <translation>Restmono:</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Krompago:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Sendi samtempe al pluraj ricevantoj</translation> </message> @@ -1445,10 +1536,6 @@ <translation>Kopii restmonon</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Totala Sumo %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>aŭ</translation> </message> @@ -2103,10 +2190,6 @@ <translation>Ruli fone kiel demono kaj akcepti komandojn</translation> </message> <message> - <source>Use the test network</source> - <translation>Uzi la test-reton</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Akcepti konektojn el ekstere (defaŭlte: 1 se ne estas -proxy nek -connect)</translation> </message> @@ -2123,10 +2206,6 @@ <translation>Tiu ĉi estas antaŭeldona testa versio - uzu laŭ via propra risko - ne uzu por minado aŭ por aplikaĵoj por vendistoj</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>Averto: -paytxfee estas agordita per tre alta valoro! Tio estas la krompago, kion vi pagos se vi sendas la transakcion.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Averto: La reto ne tute konsentas! Kelkaj minantoj ŝajne spertas problemojn aktuale.</translation> </message> @@ -2135,10 +2214,6 @@ <translation>Averto: ŝajne ni ne tute konsentas kun niaj samtavolanoj! Eble vi devas ĝisdatigi vian klienton, aŭ eble aliaj nodoj faru same.</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>Averto: okazis eraro dum lego de wallet.dat! Ĉiuj ŝlosiloj sukcese legiĝis, sed la transakciaj datumoj aŭ la adresaro eble mankas aŭ malĝustas.</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>Averto: via wallet.dat estas difektita, sed la datumoj sukcese saviĝis! La originala wallet.dat estas nun konservita kiel wallet.{timestamp}.bak en %s; se via saldo aŭ transakcioj estas malĝustaj vi devus restaŭri per alia sekurkopio.</translation> </message> @@ -2147,10 +2222,6 @@ <translation><category> povas esti:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Provo ripari privatajn ŝlosilojn el difektita wallet.dat</translation> - </message> - <message> <source>Block creation options:</source> <translation>Blok-kreaj agordaĵoj:</translation> </message> @@ -2227,22 +2298,22 @@ <translation>Vi devas rekontrui la datumbazon kun -reindex por ŝanĝi -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importas blokojn el ekstera dosiero blk000??.dat</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>Plenumi komandon kiam rilata alerto riceviĝas, aŭ kiam ni vidas tre longan forkon (%s en cms anstataŭiĝas per mesaĝo)</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Elekti dosierujon por datumoj dum lanĉo (defaŭlte: 0)</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Ne eblas trovi la adreson -whitebind: '%s'</translation> </message> <message> <source>Information</source> <translation>Informoj</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Nevalida sumo por -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Nevalida sumo por -minrelaytxfee=<amount>: '%s'</translation> </message> @@ -2255,14 +2326,6 @@ <translation>Sendi spurajn/sencimigajn informojn al la konzolo anstataŭ al dosiero debug.log</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Agordi lingvon, ekzemple "de_DE" (defaŭlte: tiu de la sistemo)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Montri salutŝildon dum lanĉo (defaŭlte: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Malpligrandigi la sencimigan protokol-dosieron kiam kliento lanĉiĝas (defaŭlte: 1 kiam mankas -debug)</translation> </message> @@ -2271,10 +2334,6 @@ <translation>Subskriba transakcio fiaskis</translation> </message> <message> - <source>Start minimized</source> - <translation>Lanĉiĝi plejete</translation> - </message> - <message> <source>This is experimental software.</source> <translation>ĝi estas eksperimenta programo</translation> </message> @@ -2291,10 +2350,6 @@ <translation>Transakcio estas tro granda</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> - <message> <source>Username for JSON-RPC connections</source> <translation>Salutnomo por konektoj JSON-RPC</translation> </message> @@ -2315,18 +2370,6 @@ <translation>Plenumi komandon kiam plej bona bloko ŝanĝiĝas (%s en cmd anstataŭiĝas per bloka haketaĵo)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Ĝisdatigi monujon al plej lasta formato</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Reskani la blokĉenon por mankantaj monujaj transakcioj</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Uzi OpenSSL (https) por konektoj JSON-RPC</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 de55496c09..936074210a 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -1,4 +1,4 @@ -<TS language="es" version="2.0"> +<TS language="es" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -23,7 +23,7 @@ </message> <message> <source>C&lose</source> - <translation>&Cerrar</translation> + <translation>C&errar</translation> </message> <message> <source>&Copy Address</source> @@ -55,7 +55,7 @@ </message> <message> <source>C&hoose</source> - <translation>&Escoger</translation> + <translation>E&scoger</translation> </message> <message> <source>Sending addresses</source> @@ -93,7 +93,11 @@ <source>Exporting Failed</source> <translation>Fallo al exportar</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Hubo un error al tratar de guardar en la lista de direcciones a %1 . Por favor, vuelve a intentarlo .</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -217,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/Máscara</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Bloqueado Hasta</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -248,7 +263,7 @@ </message> <message> <source>E&xit</source> - <translation>&Salir</translation> + <translation>S&alir</translation> </message> <message> <source>Quit application</source> @@ -867,7 +882,23 @@ <source>command-line options</source> <translation>opciones de la consola de comandos</translation> </message> -</context> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Elegir directorio de datos al iniciar (predeterminado: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Arrancar minimizado</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Establecer los certificados raíz SSL para solicitudes de pago (predeterminado: -system-)</translation> + </message> + </context> <context> <name>Intro</name> <message> @@ -1065,6 +1096,22 @@ <translation>Puerto del servidor proxy (ej. 9050)</translation> </message> <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Usar distintos proxys SOCKS5 para comunicarse vía Tor de forma anónima:</translation> + </message> + <message> <source>&Window</source> <translation>&Ventana</translation> </message> @@ -1283,10 +1330,6 @@ <translation>La petición de pago %1 es demasiado grande (%2 bytes, permitidos %3 bytes).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation> Solicitud pago de protección DoS</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Error en la comunicación con %1: %2</translation> </message> @@ -1455,6 +1498,10 @@ <translation>&Pares</translation> </message> <message> + <source>Banned peers</source> + <translation>Peers Bloqueados</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Seleccionar un par para ver su información detallada.</translation> </message> @@ -1467,20 +1514,24 @@ <translation>Versión</translation> </message> <message> - <source>User Agent</source> - <translation>User Agent</translation> + <source>Starting Block</source> + <translation>Importando bloques...</translation> </message> <message> - <source>Services</source> - <translation>Servicios</translation> + <source>Synced Headers</source> + <translation>Sincronizar Cabeceras</translation> + </message> + <message> + <source>Synced Blocks</source> + <translation>Bloques Sincronizados</translation> </message> <message> - <source>Starting Height</source> - <translation>Altura de comienzo</translation> + <source>User Agent</source> + <translation>User Agent</translation> </message> <message> - <source>Sync Height</source> - <translation>Altura de sincronización</translation> + <source>Services</source> + <translation>Servicios</translation> </message> <message> <source>Ban Score</source> @@ -1499,14 +1550,6 @@ <translation>Ultima recepción</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Bytes enviados</translation> - </message> - <message> - <source>Bytes Received</source> - <translation>Bytes recibidos</translation> - </message> - <message> <source>Ping Time</source> <translation>Ping</translation> </message> @@ -1559,6 +1602,26 @@ <translation>Borrar consola</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>Nodo &Desconectado</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &hora</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &día</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &semana</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &año</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Bienvenido a la consola RPC de Bitcoin Core.</translation> </message> @@ -1587,6 +1650,10 @@ <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(nodo: %1)</translation> + </message> + <message> <source>via %1</source> <translation>via %1</translation> </message> @@ -1603,12 +1670,16 @@ <translation>Saliente</translation> </message> <message> - <source>Unknown</source> - <translation>Desconocido</translation> + <source>Yes</source> + <translation>Sí</translation> + </message> + <message> + <source>No</source> + <translation>No</translation> </message> <message> - <source>Fetching...</source> - <translation>Adquiriendo....</translation> + <source>Unknown</source> + <translation>Desconocido</translation> </message> </context> <context> @@ -1975,8 +2046,8 @@ <translation>Copiar Cambio</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Cuantía Total %1 (=%2)</translation> + <source>Total Amount %1</source> + <translation>Monto Total %1</translation> </message> <message> <source>or</source> @@ -2003,18 +2074,22 @@ <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>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Una comisión mayor al %1 se considera demasiado alta.</translation> + </message> + <message> <source>Payment request expired.</source> <translation>Solicitud de pago caducada.</translation> </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>Paga sólo la cuota mínima de %1</translation> + </message> <message numerus="yes"> <source>Estimated to begin confirmation within %n block(s).</source> <translation><numerusform>Estimado para empezar la confirmación dentro de %n bloque.</numerusform><numerusform>Estimado para empezar la confirmación dentro de %n bloques.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Paga sólo la cuota mínima de %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>La dirección del destinatario no es válida. Por favor, compruébela de nuevo.</translation> </message> @@ -2795,14 +2870,25 @@ </translation> </message> <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Un error interno fatal ocurrió, ver debug.log para detalles</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Comisión (en %s/KB) para agregar a las transacciones que envíe (por defecto: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Poda blockstore ...</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>Ejecutar en segundo plano como daemon y aceptar comandos </translation> </message> <message> - <source>Use the test network</source> - <translation>Usar la red de pruebas -</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>No se ha podido comenzar el servidor HTTP. Ver debug log para detalles.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2825,14 +2911,6 @@ <translation>Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Maximo Comisión totales para usar en una sola transacción billetera; establecer esta demasiado bajo puede abortar transacciones grandes (por defecto: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Reducir los requerimientos de almacenamiento mediante la poda (borrado) bloquea viejos. Este modo desactiva el apoyo cartera y es incompatible con -txindex. Advertencia: Revertir esta configuración requiere volver a descargar toda la blockchain. (por defecto: 0 = desactivar bloques de poda, >%u = tamaño de destino en MiB de usar para los archivos de bloques)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <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> @@ -2853,10 +2931,6 @@ <translation>ADVERTENCIA: comprueba tu conexión de red, %d bloques recibidos en las últimas %d horas (%d esperados)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Aviso: ¡-paytxfee tiene un valor muy alto! Esta es la comisión que pagará si envía una transacción.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Atención: ¡Parece que la red no está totalmente de acuerdo! Algunos mineros están presentando inconvenientes.</translation> </message> @@ -2865,10 +2939,6 @@ <translation>Atención: ¡Parece que no estamos completamente de acuerdo con nuestros pares! Podría necesitar una actualización, u otros nodos podrían necesitarla.</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>Aviso: ¡Error al leer wallet.dat! Todas las claves se han leído correctamente, pero podrían faltar o ser incorrectos los datos de transacciones o las entradas de la libreta de direcciones.</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>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> @@ -2877,18 +2947,14 @@ <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: 1)</source> - <translation>(predeterminado: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool debe ser por lo menos de %d MB</translation> </message> <message> <source><category> can be:</source> <translation><category> puede ser:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Intento de recuperar claves privadas de un wallet.dat corrupto</translation> - </message> - <message> <source>Block creation options:</source> <translation>Opciones de creación de bloques:</translation> </message> @@ -2933,10 +2999,6 @@ <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> @@ -2945,10 +3007,6 @@ <translation>Ha fallado la escucha en todos los puertos. Use -listen=0 si desea esto.</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> - <message> <source>Importing...</source> <translation>Importando...</translation> </message> @@ -3017,18 +3075,10 @@ <translation>Usted necesita reconstruir la base de datos utilizando -reindex para cambiar -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <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> @@ -3053,28 +3103,20 @@ <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>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>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Si el pago de comisión no está establecido, incluir la cuota suficiente para que las transacciones comiencen la confirmación en una media de n bloques ( por defecto :%u)</translation> </message> <message> - <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> - <translation>El tamaño máximo de los datos en las operaciones de transporte de datos que transmitimos y el mio (default: %u)</translation> + <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> + <translation>Cantidad no válida para -maxtxfee=<amount>: '%s' (debe ser por lo menos la cuota de comisión mínima de %s para prevenir transacciones atascadas)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>Pode configurado por debajo del mínimo de %d MB. Por favor, use un número más alto.</translation> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>El tamaño máximo de los datos en las operaciones de transporte de datos que transmitimos y el mio (default: %u)</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> @@ -3101,38 +3143,6 @@ <translation>Este producto incluye software desarrollado por el OpenSSL Project para su uso en OpenSSL Toolkit <https://www.openssl.org/>, software de cifrado escrito por Eric Young y software UPnP escrito por Thomas Bernard.</translation> </message> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>Para utilizar bitcoind, o la -opción servidor a bitcoin-qt, debes establecer una rpcpassword en el fichero de configuración: -%s -Se recomienda utilizar la siguiente contraseña aleatoria: -rpcuser=bitcoinrpc -rpcpassword=%s -(no es necesario que recuerdes esta contraseña) -El nombre de usuario y contraseña NO DEBEN ser la misma. -Si no existe el archivo, crearlo con los permisos de archivos de propietarios de -sólo lectura-. -También se recomienda establecer una notificación de alerta para ser notificado de problemas; -por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Advertencia: ¡-maxtxfee se establece muy alta! Esta gran tarifa podría ser pagada en una sola transacción .</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>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> @@ -3153,16 +3163,16 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Activando la mejor cadena...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>No se puede ejecutar con un monedero en modo recorte.</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Intento de recuperar claves privadas de un wallet.dat corrupto</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>No se puede resolver -whitebind address: '%s'</translation> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Automáticamente crea el servicio Tor oculto (por defecto: %d)</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Elegir directorio de datos al iniciar (predeterminado: 0)</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>No se puede resolver -whitebind address: '%s'</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3173,10 +3183,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>No se pudo analizar -rpcbind valor%s como dirección de red</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> @@ -3185,12 +3191,8 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Error al leer la base de datos, cerrando.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Error: Argumento encontrado -tor no soportado, utilice -onion</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> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Importa los bloques desde un archivo externo blk000?.dat</translation> </message> <message> <source>Information</source> @@ -3233,18 +3235,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Opciones de nodos de retransmisión:</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> - <message> <source>RPC server options:</source> <translation>Opciones de servidor RPC:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>Soporte RPC para conexiones HTTP persistentes (por defecto: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Reconstruir el índice de la cadena de bloques en el arranque desde los actuales ficheros blk000??.dat</translation> </message> @@ -3253,6 +3247,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Recibir y mostrar alertas de red P2P (default: %u)</translation> </message> <message> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Rescanea la cadena de bloques para transacciones perdidas de la cartera</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> @@ -3261,22 +3259,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Mandar transacciones como comisión-cero si es posible (por defecto: %u)</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Establecer los certificados raíz SSL para solicitudes de pago (predeterminado: -system-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Muestra todas las opciones de depuración (uso: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostrar pantalla de bienvenida en el inicio (predeterminado: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Reducir el archivo debug.log al iniciar el cliente (predeterminado: 1 sin -debug)</translation> </message> @@ -3285,10 +3271,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Transacción falló</translation> </message> <message> - <source>Start minimized</source> - <translation>Arrancar minimizado</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>Cantidad de la transacción demasiado pequeña para pagar la comisión</translation> </message> @@ -3313,16 +3295,12 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Transacción demasiado grande</translation> </message> <message> - <source>UI Options:</source> - <translation>Opciones de interfaz de usuario</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>No es posible conectar con %s en este sistema (bind ha dado el error %s)</translation> </message> <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> + <source>Upgrade wallet to latest format on startup</source> + <translation>Actualizar el monedero al último formato</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3338,22 +3316,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Aviso</translation> </message> <message> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation>Advertencia: Argumento no soportado -benchmark ignored, use -debug=bench.</translation> - </message> - <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> <message> - <source>on startup</source> - <translation>al iniciar</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat corrupto. Ha fallado la recuperación.</translation> </message> @@ -3367,19 +3333,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Ejecutar un comando cuando cambia el mejor bloque (%s en cmd se sustituye por el hash de bloque)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Actualizar el monedero al último formato</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Usar OpenSSL (https) para las conexiones JSON-RPC -</translation> - </message> - <message> <source>This help message</source> <translation>Este mensaje de ayuda </translation> @@ -3425,10 +3378,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <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> @@ -3489,14 +3438,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com <translation>Relay non-P2SH multisig (default: %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> diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index c35acf2c67..e6d48a29f0 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.0"> +<TS language="es_CL" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -165,6 +165,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -299,6 +302,10 @@ <translation>bitcoin core</translation> </message> <message> + <source>%1 and %2</source> + <translation>%1 y %2</translation> + </message> + <message> <source>Error</source> <translation>Error</translation> </message> @@ -349,6 +356,10 @@ <translation>Cantidad:</translation> </message> <message> + <source>Priority:</source> + <translation>prioridad:</translation> + </message> + <message> <source>Amount</source> <translation>Cantidad</translation> </message> @@ -503,6 +514,10 @@ <translation>&Red</translation> </message> <message> + <source>W&allet</source> + <translation>Cartera</translation> + </message> + <message> <source>Expert</source> <translation>experto</translation> </message> @@ -634,6 +649,10 @@ <translation>&Información</translation> </message> <message> + <source>Debug window</source> + <translation>Ventana Debug</translation> + </message> + <message> <source>General</source> <translation>General</translation> </message> @@ -682,6 +701,10 @@ <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>Cantidad:</translation> + </message> + <message> <source>&Label:</source> <translation>&Etiqueta:</translation> </message> @@ -759,10 +782,22 @@ <translation>Enviar monedas</translation> </message> <message> + <source>Insufficient funds!</source> + <translation>Fondos insuficientes</translation> + </message> + <message> <source>Amount:</source> <translation>Cantidad:</translation> </message> <message> + <source>Priority:</source> + <translation>prioridad:</translation> + </message> + <message> + <source>Transaction Fee:</source> + <translation>Comisión transacción:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Enviar a múltiples destinatarios</translation> </message> @@ -845,6 +880,10 @@ <source>Message:</source> <translation>Mensaje:</translation> </message> + <message> + <source>Pay To:</source> + <translation>Pagar a:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -900,6 +939,10 @@ <translation>Click en "Firmar Mensage" para conseguir firma</translation> </message> <message> + <source>The entered address is invalid.</source> + <translation>La dirección introducida no es una valida.</translation> + </message> + <message> <source>Please check the address and try again.</source> <translation>Por favor, revise la dirección Bitcoin e inténtelo denuevo</translation> </message> @@ -1289,15 +1332,6 @@ </translation> </message> <message> - <source>Use the test network</source> - <translation>Usa la red de pruebas -</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>Precaución: -paytxfee es muy alta. Esta es la comisión que pagarás si envias una transacción.</translation> - </message> - <message> <source>Connect only to the specified node(s)</source> <translation>Conecta solo al nodo especificado </translation> @@ -1311,25 +1345,24 @@ <translation>Atención: Poco espacio en el disco duro</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importar bloques desde el archivo externo blk000??.dat </translation> - </message> - <message> <source>Information</source> <translation>Información</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Enviar informacion de seguimiento a la consola en vez del archivo debug.log</translation> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Cantidad inválida para -maxtxfee=<amount>: '%s'</translation> </message> <message> - <source>Start minimized</source> - <translation>Arranca minimizado -</translation> + <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> + <translation>Cantidad inválida para -minrelaytxfee=<amount>: '%s'</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> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>Cantidad inválida para -mintxfee=<amount>: '%s'</translation> + </message> + <message> + <source>Send trace/debug info to console instead of debug.log file</source> + <translation>Enviar informacion de seguimiento a la consola en vez del archivo debug.log</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -1350,20 +1383,6 @@ </translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Actualizar billetera al formato actual</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> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Usa OpenSSL (https) para las conexiones JSON-RPC -</translation> - </message> - <message> <source>This help message</source> <translation>Este mensaje de ayuda </translation> @@ -1390,6 +1409,14 @@ <translation>Dirección -proxy invalida: '%s'</translation> </message> <message> + <source>Cannot resolve -bind address: '%s'</source> + <translation>No se pudo resolver la dirección fija: '%s'</translation> + </message> + <message> + <source>Cannot resolve -externalip address: '%s'</source> + <translation>No se pudo resolver la dirección ip: '%s'</translation> + </message> + <message> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> <translation>Cantidad inválida para -paytxfee=<amount>: '%s'</translation> </message> @@ -1410,6 +1437,14 @@ <translation>Cargando cartera...</translation> </message> <message> + <source>Cannot downgrade wallet</source> + <translation>No es posible desactualizar la billetera</translation> + </message> + <message> + <source>Cannot write default address</source> + <translation>No se pudo escribir la dirección por defecto</translation> + </message> + <message> <source>Rescanning...</source> <translation>Rescaneando...</translation> </message> diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts index 6071702989..0463c0f6e1 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.0"> +<TS language="es_DO" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -201,6 +201,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -737,7 +740,7 @@ <source>command-line options</source> <translation>opciones de la línea de órdenes</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -827,6 +830,10 @@ <translation>&Red</translation> </message> <message> + <source>W&allet</source> + <translation>Monedero</translation> + </message> + <message> <source>Expert</source> <translation>Experto</translation> </message> @@ -1365,6 +1372,10 @@ <translation>Dirección propia</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Comisión de transacción:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Enviar a múltiples destinatarios de una vez</translation> </message> @@ -1429,10 +1440,6 @@ <translation>Copiar Cambio</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Cuantía Total %1 (=%2)</translation> - </message> - <message> <source>or</source> <translation>o</translation> </message> @@ -1520,6 +1527,10 @@ <translation>Eliminar esta transacción</translation> </message> <message> + <source>Message:</source> + <translation>Mensaje:</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Introduce una etiqueta para esta dirección para añadirla a la lista de direcciones utilizadas</translation> </message> @@ -2106,11 +2117,6 @@ </translation> </message> <message> - <source>Use the test network</source> - <translation>Usar la red de pruebas -</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Aceptar conexiones desde el exterior (predeterminado: 1 si no -proxy o -connect)</translation> </message> @@ -2127,10 +2133,6 @@ <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>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> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Atención: ¡Parece que la red no está totalmente de acuerdo! Algunos mineros están presentando inconvenientes.</translation> </message> @@ -2139,10 +2141,6 @@ <translation>Atención: ¡Parece que no estamos completamente de acuerdo con nuestros pares! Podría necesitar una actualización, u otros nodos podrían necesitarla.</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>Aviso: ¡Error al leer wallet.dat! Todas las claves se han leído correctamente, pero podrían faltar o ser incorrectos los datos de transacciones o las entradas de la libreta de direcciones.</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>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> @@ -2151,10 +2149,6 @@ <translation><category> puede ser:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Intento de recuperar claves privadas de un wallet.dat corrupto</translation> - </message> - <message> <source>Block creation options:</source> <translation>Opciones de creación de bloques:</translation> </message> @@ -2195,10 +2189,6 @@ <translation>Ha fallado la escucha en todos los puertos. Use -listen=0 si desea esto.</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> - <message> <source>Incorrect or no genesis block found. Wrong datadir for network?</source> <translation>Incorrecto o bloque de génesis no encontrado. Datadir equivocada para la red?</translation> </message> @@ -2235,10 +2225,6 @@ <translation>Usted necesita reconstruir la base de datos utilizando -reindex para cambiar -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importa los bloques desde un archivo blk000??.dat externo</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> @@ -2247,14 +2233,18 @@ <translation>Establecer tamaño máximo de las transacciones de alta prioridad/comisión baja en bytes (por defecto: %d)</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Elegir directorio de datos al iniciar (predeterminado: 0)</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>No se puede resolver la dirección de -whitebind: '%s'</translation> </message> <message> <source>Information</source> <translation>Información</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Inválido por el monto -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Inválido por el monto -minrelaytxfee=<amount>: '%s'</translation> </message> @@ -2263,10 +2253,6 @@ <translation>Inválido por el monto -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> - <translation>Opciones RPC SSL: (Vea la Wiki de Bitcoin para las instrucciones de la configuración de SSL)</translation> - </message> - <message> <source>RPC server options:</source> <translation>Opciones del sservidor RPC:</translation> </message> @@ -2275,18 +2261,10 @@ <translation>Enviar información de trazas/depuración a la consola en lugar de al archivo debug.log</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Mostrar todas las opciones de depuración (uso: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostrar pantalla de bienvenida en el inicio (predeterminado: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Reducir el archivo debug.log al iniciar el cliente (predeterminado: 1 sin -debug)</translation> </message> @@ -2295,10 +2273,6 @@ <translation>Transacción falló</translation> </message> <message> - <source>Start minimized</source> - <translation>Arrancar minimizado</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Monto de la transacción muy pequeño</translation> </message> @@ -2311,10 +2285,6 @@ <translation>Transacción demasiado grande</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> - <message> <source>Username for JSON-RPC connections</source> <translation>Nombre de usuario para las conexiones JSON-RPC </translation> @@ -2324,10 +2294,6 @@ <translation>Aviso</translation> </message> <message> - <source>on startup</source> - <translation>al iniciar</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat corrupto. Ha fallado la recuperación.</translation> </message> @@ -2341,19 +2307,6 @@ <translation>Ejecutar un comando cuando cambia el mejor bloque (%s en cmd se sustituye por el hash de bloque)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Actualizar el monedero al último formato</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Usar OpenSSL (https) para las conexiones JSON-RPC -</translation> - </message> - <message> <source>This help message</source> <translation>Este mensaje de ayuda </translation> diff --git a/src/qt/locale/bitcoin_es_ES.ts b/src/qt/locale/bitcoin_es_ES.ts new file mode 100644 index 0000000000..bdbfed4ec6 --- /dev/null +++ b/src/qt/locale/bitcoin_es_ES.ts @@ -0,0 +1,481 @@ +<TS language="es_ES" version="2.1"> +<context> + <name>AddressBookPage</name> + <message> + <source>Right-click to edit address or label</source> + <translation>Haz clic derecho para editar la dirección o la etiqueta</translation> + </message> + <message> + <source>Create a new address</source> + <translation>Crea una nueva direccióon</translation> + </message> + <message> + <source>&New</source> + <translation>&Nuevo</translation> + </message> + <message> + <source>Copy the currently selected address to the system clipboard</source> + <translation>Copia la direccón seleccionada al portapapeles del sistema</translation> + </message> + <message> + <source>&Copy</source> + <translation>&Copiar</translation> + </message> + <message> + <source>C&lose</source> + <translation>C&errar</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>&Copiar Direccón</translation> + </message> + <message> + <source>Delete the currently selected address from the list</source> + <translation>Elimina la dirección seleccionada de la lista</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Exporta los datos de la pestaña actual a un archivo</translation> + </message> + <message> + <source>&Export</source> + <translation>&Exportar</translation> + </message> + <message> + <source>&Delete</source> + <translation>&Eliminar</translation> + </message> + <message> + <source>Choose the address to send coins to</source> + <translation>Elige la dirección a la que enviar las monedas</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>Elige la direccón con la que recibir monedas</translation> + </message> + <message> + <source>C&hoose</source> + <translation>E&legir</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Enviando direcciones</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Recibiendo direcciones</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>Estas son tus direcciones de Bitcoin para enviar pagos. Comprueba siempre la cantidad y la dirección receptora antes de enviar monedas.</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>Estas son tus direcciones de Bitcoin para recibir pagos. Se recomienda usar una nueva dirección receptora para cada transacción</translation> + </message> + <message> + <source>Copy &Label</source> + <translation>Copiar &Etiqueta</translation> + </message> + <message> + <source>&Edit</source> + <translation>&Editar</translation> + </message> + <message> + <source>Export Address List</source> + <translation>Exportar Lista de Direcciones</translation> + </message> + <message> + <source>Comma separated file (*.csv)</source> + <translation>Archivo separado por comas (*.csv)</translation> + </message> + <message> + <source>Exporting Failed</source> + <translation>Exportacón Fallida</translation> + </message> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Ha ocurrido un error intentando guardar la lista de direcciones en %1. Por favor intentalo de nuevo.</translation> + </message> +</context> +<context> + <name>AddressTableModel</name> + <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> + <source>Address</source> + <translation>Dirección</translation> + </message> + <message> + <source>(no label)</source> + <translation>(sin etiqueta)</translation> + </message> +</context> +<context> + <name>AskPassphraseDialog</name> + <message> + <source>Passphrase Dialog</source> + <translation>Dialogo de Contraseña</translation> + </message> + <message> + <source>Enter passphrase</source> + <translation>Introduzca la contraseña</translation> + </message> + <message> + <source>New passphrase</source> + <translation>Nueva contraseña</translation> + </message> + <message> + <source>Repeat new passphrase</source> + <translation>Repite la nueva contraseña</translation> + </message> + <message> + <source>Encrypt wallet</source> + <translation>Encriptar cartera</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to unlock the wallet.</source> + <translation>Esta operacón necesita tu contraseña de la cartera para desbloquear la cartera.</translation> + </message> + <message> + <source>Unlock wallet</source> + <translation>Desbloquear cartera</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to decrypt the wallet.</source> + <translation>Esta operación requiere tu contraseña de la cartera para desencriptar la cartera.</translation> + </message> + <message> + <source>Decrypt wallet</source> + <translation>Desencriptar cartera</translation> + </message> + <message> + <source>Change passphrase</source> + <translation>Cambiar contraseña</translation> + </message> + <message> + <source>Confirm wallet encryption</source> + <translation>Confirmar encriptación de la cartera</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>Advertencia: Si encriptas tu cartera y pierdes tu contraseña, <b>PERDERÁS TODOS TUS BITCOINS</B></translation> + </message> + <message> + <source>Are you sure you wish to encrypt your wallet?</source> + <translation>Estás seguro ue deseas encriptar tu cartera?</translation> + </message> + <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Bitcoin Core se cerrará ahora para finalizar el proceso de encriptación. Recuerda que encriptar tu cartera no protege completamente tus bitcoins de ser robados por malware infectando tu ordenador.</translation> + </message> + <message> + <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> + <translation>IMPORTANTE: Cualquier copia de seguridad anterior del archivo de tu cartera debería ser remplazado con el nuevo archivo encriptado. Por motivos de seguridad, las copias de seguridad anteriores de la cartera desencriptada quedaran inusables tan pronto como empieces a usar la nueva cartera encriptada.</translation> + </message> + <message> + <source>Warning: The Caps Lock key is on!</source> + <translation>Advertencia: La Tecla de Bloqueo de Mayusculas esta activada!</translation> + </message> + <message> + <source>Wallet encrypted</source> + <translation>Cartera 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>Introduzca la nueva contraseña de la cartera. <br/>Por favor utilice una contraseña de <b>diez o mas caracteres aleatorios</b>, o <b>ocho o mas palabras</b>.</translation> + </message> + <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Introduzca la antigua contraseña y la nueva contraseña en la cartera.</translation> + </message> + <message> + <source>Wallet encryption failed</source> + <translation>Encriptación de la cartera fallida</translation> + </message> + <message> + <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> + <translation>La encriptación de la cartera ha fallado debido a un error interno. Tu cartera no ha sido encriptada.</translation> + </message> + <message> + <source>The supplied passphrases do not match.</source> + <translation>Las contraseñas proporcianadas no se corresponden.</translation> + </message> + <message> + <source>Wallet unlock failed</source> + <translation>Desbloqueo de la cartera fallido</translation> + </message> + <message> + <source>The passphrase entered for the wallet decryption was incorrect.</source> + <translation>La contraseña introducida para desencriptar la cartera es incorrecta.</translation> + </message> + <message> + <source>Wallet decryption failed</source> + <translation>Desencriptación de la cartera fallida</translation> + </message> + <message> + <source>Wallet passphrase was successfully changed.</source> + <translation>Contraseña de la cartera cambiada correctamente</translation> + </message> +</context> +<context> + <name>BanTableModel</name> + </context> +<context> + <name>BitcoinGUI</name> + <message> + <source>Sign &message...</source> + <translation>Firmar &mensaje...</translation> + </message> + <message> + <source>Synchronizing with network...</source> + <translation>Sincronizando con la red...</translation> + </message> + <message> + <source>&Overview</source> + <translation>&Vista general</translation> + </message> + <message> + <source>Node</source> + <translation>Nodo</translation> + </message> + <message> + <source>Show general overview of wallet</source> + <translation>Mostrar vista general de la cartera</translation> + </message> + <message> + <source>&Transactions</source> + <translation>&Transacciones</translation> + </message> + <message> + <source>Browse transaction history</source> + <translation>Navegar historial de transacciones</translation> + </message> + <message> + <source>E&xit</source> + <translation>S&alir</translation> + </message> + <message> + <source>Quit application</source> + <translation>Salir de la aplicación</translation> + </message> + <message> + <source>About &Qt</source> + <translation>Acerca de &Qt</translation> + </message> + <message> + <source>Show information about Qt</source> + <translation>Muestra información acerca de Qt</translation> + </message> + <message> + <source>&Options...</source> + <translation>&Opciones...</translation> + </message> + <message> + <source>&Encrypt Wallet...</source> + <translation>&Encriptar Cartera...</translation> + </message> + <message> + <source>&Backup Wallet...</source> + <translation>&Hacer copia de seguridad de la cartera...</translation> + </message> + <message> + <source>&Change Passphrase...</source> + <translation>&Cambiar contraseña...</translation> + </message> + <message> + <source>&Sending addresses...</source> + <translation>&Enviando direcciones...</translation> + </message> + <message> + <source>&Receiving addresses...</source> + <translation>&Recibiendo direcciones..</translation> + </message> + <message> + <source>Open &URI...</source> + <translation>Abrir &URI...</translation> + </message> + <message> + <source>Bitcoin Core client</source> + <translation>Cliente Bitcoin Core</translation> + </message> + <message> + <source>Importing blocks from disk...</source> + <translation>Importando bloques desde disco...</translation> + </message> + <message> + <source>Reindexing blocks on disk...</source> + <translation>Reindexando bloques en el disco...</translation> + </message> + <message> + <source>Send coins to a Bitcoin address</source> + <translation>Envia monedas a una dirección Bitcoin</translation> + </message> + <message> + <source>Backup wallet to another location</source> + <translation>Crea una copia de seguridad de tu cartera en otra ubicación</translation> + </message> + </context> +<context> + <name>ClientModel</name> + </context> +<context> + <name>CoinControlDialog</name> + <message> + <source>(no label)</source> + <translation>(sin etiqueta)</translation> + </message> + </context> +<context> + <name>EditAddressDialog</name> + <message> + <source>&Label</source> + <translation>Etiqueta</translation> + </message> + <message> + <source>&Address</source> + <translation>Dirección</translation> + </message> + </context> +<context> + <name>FreespaceChecker</name> + </context> +<context> + <name>HelpMessageDialog</name> + </context> +<context> + <name>Intro</name> + </context> +<context> + <name>OpenURIDialog</name> + </context> +<context> + <name>OptionsDialog</name> + </context> +<context> + <name>OverviewPage</name> + </context> +<context> + <name>PaymentServer</name> + </context> +<context> + <name>PeerTableModel</name> + </context> +<context> + <name>QObject</name> + </context> +<context> + <name>QRImageWidget</name> + </context> +<context> + <name>RPCConsole</name> + </context> +<context> + <name>ReceiveCoinsDialog</name> + </context> +<context> + <name>ReceiveRequestDialog</name> + <message> + <source>Copy &Address</source> + <translation>&Copiar Direccón</translation> + </message> + <message> + <source>Address</source> + <translation>Dirección</translation> + </message> + <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + </context> +<context> + <name>RecentRequestsTableModel</name> + <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> + <source>(no label)</source> + <translation>(sin etiqueta)</translation> + </message> + </context> +<context> + <name>SendCoinsDialog</name> + <message> + <source>(no label)</source> + <translation>(sin etiqueta)</translation> + </message> + </context> +<context> + <name>SendCoinsEntry</name> + </context> +<context> + <name>ShutdownWindow</name> + </context> +<context> + <name>SignVerifyMessageDialog</name> + </context> +<context> + <name>SplashScreen</name> + </context> +<context> + <name>TrafficGraphWidget</name> + </context> +<context> + <name>TransactionDesc</name> + </context> +<context> + <name>TransactionDescDialog</name> + </context> +<context> + <name>TransactionTableModel</name> + <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + </context> +<context> + <name>TransactionView</name> + <message> + <source>Exporting Failed</source> + <translation>Exportacón Fallida</translation> + </message> + <message> + <source>Comma separated file (*.csv)</source> + <translation>Archivo separado por comas (*.csv)</translation> + </message> + <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> + <source>Address</source> + <translation>Dirección</translation> + </message> + </context> +<context> + <name>UnitDisplayStatusBarControl</name> + </context> +<context> + <name>WalletFrame</name> + </context> +<context> + <name>WalletModel</name> + </context> +<context> + <name>WalletView</name> + <message> + <source>&Export</source> + <translation>&Exportar</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Exporta los datos de la pestaña actual a un archivo</translation> + </message> + </context> +<context> + <name>bitcoin-core</name> + </context> +</TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts index 258308598e..fa2b3c0623 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.0"> +<TS language="es_MX" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -11,7 +11,7 @@ </message> <message> <source>Copy the currently selected address to the system clipboard</source> - <translation>Copiar el domicilio seleccionado al portapapeles del sistema</translation> + <translation>Copiar la dirección seleccionada al portapapeles del sistema</translation> </message> <message> <source>&Copy</source> @@ -83,7 +83,7 @@ </message> <message> <source>Comma separated file (*.csv)</source> - <translation>Arhchivo separado por comas (*.CSV)</translation> + <translation>Archivo separado por comas (*.CSV)</translation> </message> <message> <source>Exporting Failed</source> @@ -98,7 +98,7 @@ </message> <message> <source>Address</source> - <translation>Domicilio</translation> + <translation>Dirección</translation> </message> <message> <source>(no label)</source> @@ -165,7 +165,7 @@ </message> <message> <source>Wallet encryption failed</source> - <translation>Encriptación de la cartera fallida</translation> + <translation>La encriptación de la cartera fallo</translation> </message> <message> <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> @@ -181,7 +181,7 @@ </message> <message> <source>The passphrase entered for the wallet decryption was incorrect.</source> - <translation>La contraseña ingresada para la desencriptación de la cartera es incorrecto</translation> + <translation>La contraseña ingresada para la desencriptación de la cartera es incorrecta</translation> </message> <message> <source>Wallet decryption failed</source> @@ -193,10 +193,13 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> - <translation>Sign &mensaje</translation> + <translation>Firmar &mensaje</translation> </message> <message> <source>Synchronizing with network...</source> @@ -256,17 +259,21 @@ </message> <message> <source>&Sending addresses...</source> - <translation>&Enviando direcciones...</translation> + <translation>Direcciones de &envío...</translation> </message> <message> <source>&Receiving addresses...</source> - <translation>&Recibiendo direcciones...</translation> + <translation>Direcciones de &recepción...</translation> </message> <message> <source>Open &URI...</source> <translation>Abrir &URL...</translation> </message> <message> + <source>Bitcoin Core client</source> + <translation>cliente Bitcoin Core</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>Importando bloques desde el disco...</translation> </message> @@ -292,13 +299,29 @@ </message> <message> <source>Open debugging and diagnostic console</source> - <translation>Abrir la consola de depuración y disgnostico</translation> + <translation>Abrir consola de depuración y diagnostico</translation> </message> <message> <source>&Verify message...</source> <translation>&Verificar mensaje...</translation> </message> <message> + <source>Bitcoin</source> + <translation>Bitcoin</translation> + </message> + <message> + <source>Wallet</source> + <translation>Cartera</translation> + </message> + <message> + <source>&Send</source> + <translation>&Enviar</translation> + </message> + <message> + <source>&Receive</source> + <translation>&Recibir</translation> + </message> + <message> <source>&File</source> <translation>&Archivo</translation> </message> @@ -319,6 +342,10 @@ <translation>nucleo Bitcoin</translation> </message> <message> + <source>&About Bitcoin Core</source> + <translation>Acerca de Bitcoin Core</translation> + </message> + <message> <source>&Command-line options</source> <translation>opciones de la &Linea de comandos</translation> </message> @@ -332,7 +359,7 @@ </message> <message> <source>Catching up...</source> - <translation>Resiviendo...</translation> + <translation>Recibiendo...</translation> </message> <message> <source>Sent transaction</source> @@ -385,40 +412,44 @@ <translation>Confirmado </translation> </message> <message> + <source>Priority</source> + <translation>Prioridad</translation> + </message> + <message> <source>Copy address</source> <translation>Copiar dirección </translation> </message> <message> <source>Copy label</source> - <translation>Copiar capa </translation> + <translation>Copiar etiqueta</translation> </message> <message> <source>Copy amount</source> - <translation>copiar monto</translation> + <translation>Copiar monto</translation> </message> <message> <source>Copy quantity</source> - <translation>copiar cantidad</translation> + <translation>Copiar cantidad</translation> </message> <message> <source>Copy fee</source> - <translation>copiar cuota</translation> + <translation>Copiar cuota</translation> </message> <message> <source>Copy after fee</source> - <translation>copiar despues de cuota</translation> + <translation>Copiar después de cuota</translation> </message> <message> <source>Copy bytes</source> - <translation>copiar bytes</translation> + <translation>Copiar bytes</translation> </message> <message> <source>Copy priority</source> - <translation>copiar prioridad</translation> + <translation>Copiar prioridad</translation> </message> <message> <source>Copy change</source> - <translation>copiar cambio</translation> + <translation>Copiar cambio</translation> </message> <message> <source>(no label)</source> @@ -441,23 +472,23 @@ </message> <message> <source>New receiving address</source> - <translation>Nueva dirección de entregas</translation> + <translation>Nueva dirección de recepción</translation> </message> <message> <source>New sending address</source> - <translation>Nueva dirección de entregas</translation> + <translation>Nueva dirección de envío</translation> </message> <message> <source>Edit receiving address</source> - <translation>Editar dirección de entregas</translation> + <translation>Editar dirección de recepción</translation> </message> <message> <source>Edit sending address</source> - <translation>Editar dirección de envios</translation> + <translation>Editar dirección de envío</translation> </message> <message> <source>The entered address "%1" is already in the address book.</source> - <translation>El domicilio ingresado "%1" ya existe en la libreta de direcciones</translation> + <translation>La dirección ingresada "%1" ya existe en la libreta de direcciones</translation> </message> <message> <source>Could not unlock wallet.</source> @@ -479,7 +510,7 @@ </message> <message> <source>version</source> - <translation>Versión</translation> + <translation>versión</translation> </message> <message> <source>(%1-bit)</source> @@ -490,6 +521,10 @@ <translation>Acerca de Bitcoin Core</translation> </message> <message> + <source>Command-line options</source> + <translation>opciones de la Linea de comandos</translation> + </message> + <message> <source>Usage:</source> <translation>Uso:</translation> </message> @@ -497,7 +532,7 @@ <source>command-line options</source> <translation>Opciones de comando de lineas</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -518,6 +553,10 @@ <source>Active command-line options that override above options:</source> <translation>Activar las opciones de linea de comando que sobre escriben las siguientes opciones:</translation> </message> + <message> + <source>W&allet</source> + <translation>Cartera</translation> + </message> </context> <context> <name>OverviewPage</name> @@ -544,14 +583,26 @@ </context> <context> <name>RPCConsole</name> + <message> + <source>Debug window</source> + <translation>Depurar ventana</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>Monto:</translation> + </message> + <message> <source>&Label:</source> <translation>&Etiqueta</translation> </message> <message> + <source>&Message:</source> + <translation>Mensaje:</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>Mensaje opcional para agregar a la solicitud de pago, el cual será mostrado cuando la solicitud este abierta. Nota: El mensaje no se manda con el pago a travéz de la red de Bitcoin.</translation> </message> @@ -565,18 +616,22 @@ </message> <message> <source>Copy label</source> - <translation>Copiar capa </translation> + <translation>Copiar etiqueta</translation> </message> <message> <source>Copy amount</source> - <translation>copiar monto</translation> + <translation>Copiar monto</translation> </message> </context> <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>&Copiar dirección</translation> + </message> + <message> <source>Address</source> - <translation>Domicilio</translation> + <translation>Dirección</translation> </message> <message> <source>Amount</source> @@ -586,6 +641,10 @@ <source>Label</source> <translation>Etiqueta</translation> </message> + <message> + <source>Message</source> + <translation>Mensaje</translation> + </message> </context> <context> <name>RecentRequestsTableModel</name> @@ -598,6 +657,10 @@ <translation>Etiqueta</translation> </message> <message> + <source>Message</source> + <translation>Mensaje</translation> + </message> + <message> <source>Amount</source> <translation>Monto</translation> </message> @@ -610,7 +673,7 @@ <name>SendCoinsDialog</name> <message> <source>Send Coins</source> - <translation>Mandar monedas</translation> + <translation>Enviar monedas</translation> </message> <message> <source>Bytes:</source> @@ -629,6 +692,10 @@ <translation>Cuota:</translation> </message> <message> + <source>fast</source> + <translation>rápido</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Enviar a múltiples receptores a la vez</translation> </message> @@ -642,39 +709,35 @@ </message> <message> <source>Confirm send coins</source> - <translation>Confirme para mandar monedas</translation> + <translation>Confirme para enviar monedas</translation> </message> <message> <source>Copy quantity</source> - <translation>copiar cantidad</translation> + <translation>Copiar cantidad</translation> </message> <message> <source>Copy amount</source> - <translation>copiar monto</translation> + <translation>Copiar monto</translation> </message> <message> <source>Copy fee</source> - <translation>copiar cuota</translation> + <translation>Copiar cuota</translation> </message> <message> <source>Copy after fee</source> - <translation>copiar despues de cuota</translation> + <translation>Copiar después de cuota</translation> </message> <message> <source>Copy bytes</source> - <translation>copiar bytes</translation> + <translation>Copiar bytes</translation> </message> <message> <source>Copy priority</source> - <translation>copiar prioridad</translation> + <translation>Copiar prioridad</translation> </message> <message> <source>Copy change</source> - <translation>copiar cambio</translation> - </message> - <message> - <source>Total Amount %1 (= %2)</source> - <translation>Monto total %1(=%2)</translation> + <translation>Copiar cambio</translation> </message> <message> <source>or</source> @@ -686,7 +749,7 @@ </message> <message> <source>Transaction creation failed!</source> - <translation>¡La creación de transacion falló!</translation> + <translation>¡La creación de la transación falló!</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> @@ -777,12 +840,16 @@ <source>Alt+P</source> <translation>Alt+P</translation> </message> + <message> + <source>Signature</source> + <translation>Firma</translation> + </message> </context> <context> <name>SplashScreen</name> <message> <source>Bitcoin Core</source> - <translation>nucleo Bitcoin</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>The Bitcoin Core developers</source> @@ -807,14 +874,42 @@ <translation>%1 confirmaciones</translation> </message> <message> + <source>Status</source> + <translation>Estado</translation> + </message> + <message> <source>Date</source> <translation>Fecha</translation> </message> <message> + <source>From</source> + <translation>De</translation> + </message> + <message> + <source>To</source> + <translation>Para</translation> + </message> + <message> + <source>label</source> + <translation>etiqueta</translation> + </message> + <message> + <source>Message</source> + <translation>Mensaje</translation> + </message> + <message> + <source>Comment</source> + <translation>Comentario</translation> + </message> + <message> <source>Transaction ID</source> <translation>ID</translation> </message> <message> + <source>Transaction</source> + <translation>Transacción</translation> + </message> + <message> <source>Amount</source> <translation>Monto</translation> </message> @@ -870,7 +965,7 @@ </message> <message> <source>Received with</source> - <translation>Recivido con</translation> + <translation>Recibido con</translation> </message> <message> <source>Sent to</source> @@ -929,7 +1024,7 @@ </message> <message> <source>Received with</source> - <translation>Recivido con</translation> + <translation>Recibido con</translation> </message> <message> <source>Sent to</source> @@ -988,6 +1083,10 @@ <translation>Exportacion satisfactoria</translation> </message> <message> + <source>The transaction history was successfully saved to %1.</source> + <translation>el historial de transaciones ha sido guardado exitosamente en %1</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Arhchivo separado por comas (*.CSV)</translation> </message> @@ -1051,32 +1150,32 @@ <source>There was an error trying to save the wallet data to %1.</source> <translation>Ocurrio un error tratando de guardar la información de la cartera %1</translation> </message> + <message> + <source>The wallet data was successfully saved to %1.</source> + <translation>La información de la cartera fué guardada exitosamente a %1</translation> + </message> </context> <context> <name>bitcoin-core</name> <message> - <source><category> can be:</source> - <translation><categoria> puede ser:</translation> - </message> - <message> - <source>Wallet options:</source> - <translation>Opciones de cartera:</translation> + <source>Options:</source> + <translation>Opciones:</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Escojer el directorio de información al iniciar (por defecto : 0)</translation> + <source><category> can be:</source> + <translation><categoria> puede ser:</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Definir idioma, por ejemplo "de_DE" (por defecto: Sistema local)</translation> + <source>Verifying blocks...</source> + <translation>Verificando bloques...</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostrar pantalla de arraque al iniciar (por defecto: 1)</translation> + <source>Verifying wallet...</source> + <translation>Verificando cartera...</translation> </message> <message> - <source>Start minimized</source> - <translation>Iniciar minimizado</translation> + <source>Wallet options:</source> + <translation>Opciones de cartera:</translation> </message> <message> <source>Loading addresses...</source> diff --git a/src/qt/locale/bitcoin_es_UY.ts b/src/qt/locale/bitcoin_es_UY.ts index bb99466619..32d433d6ec 100644 --- a/src/qt/locale/bitcoin_es_UY.ts +++ b/src/qt/locale/bitcoin_es_UY.ts @@ -1,22 +1,71 @@ -<TS language="es_UY" version="2.0"> +<TS language="es_UY" version="2.1"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Clic derecho para editar dirección o etiqueta</translation> + </message> + <message> <source>Create a new address</source> <translation>Crear una nueva dirección </translation> </message> <message> + <source>&New</source> + <translation>Nuevo</translation> + </message> + <message> <source>Copy the currently selected address to the system clipboard</source> <translation>Copia la dirección seleccionada al portapapeles del sistema</translation> </message> <message> + <source>&Copy</source> + <translation>Copiar</translation> + </message> + <message> + <source>C&lose</source> + <translation>Cerrar</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>Copiar Dirección</translation> + </message> + <message> + <source>&Export</source> + <translation>Exportar</translation> + </message> + <message> <source>&Delete</source> <translation>&Borrar</translation> </message> <message> + <source>Choose the address to send coins to</source> + <translation>Elige una dirección donde enviar monedas a</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Enviando direcciones</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Recibiendo direcciones +</translation> + </message> + <message> + <source>&Edit</source> + <translation>Editar</translation> + </message> + <message> + <source>Export Address List</source> + <translation>Exportar Lista de Direcciones</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Archivos separados por coma (*.csv)</translation> </message> + <message> + <source>Exporting Failed</source> + <translation>Exportación fallida</translation> + </message> </context> <context> <name>AddressTableModel</name> @@ -76,6 +125,14 @@ <translation>Confirme el cifrado del monedero</translation> </message> <message> + <source>Are you sure you wish to encrypt your wallet?</source> + <translation>Estas seguro que deseas encriptar tu billetera?</translation> + </message> + <message> + <source>Warning: The Caps Lock key is on!</source> + <translation>Atención: la tecla Mayusculas esta activa!</translation> + </message> + <message> <source>Wallet encrypted</source> <translation>Monedero cifrado</translation> </message> @@ -105,6 +162,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Synchronizing with network...</source> @@ -127,18 +187,58 @@ <translation>Buscar en el historial de transacciones</translation> </message> <message> + <source>E&xit</source> + <translation>Salida</translation> + </message> + <message> <source>Quit application</source> <translation>Salir de la aplicacion </translation> </message> <message> + <source>Show information about Qt</source> + <translation>Mostrar informacioón sobre</translation> + </message> + <message> <source>&Options...</source> <translation>&Opciones...</translation> </message> <message> + <source>&Backup Wallet...</source> + <translation>Respaldar Billetera</translation> + </message> + <message> + <source>&Change Passphrase...</source> + <translation>Cambiar contraseña</translation> + </message> + <message> + <source>&Sending addresses...</source> + <translation>Enviando direcciones</translation> + </message> + <message> + <source>&Receiving addresses...</source> + <translation>Recibiendo direcciones</translation> + </message> + <message> + <source>Send coins to a Bitcoin address</source> + <translation>Enviar monedas a una dirección BItCoin</translation> + </message> + <message> <source>Change the passphrase used for wallet encryption</source> <translation>Cambie la clave utilizada para el cifrado del monedero</translation> </message> <message> + <source>Bitcoin</source> + <translation>Bitcoin</translation> + </message> + <message> + <source>Wallet</source> + <translation>Billetera</translation> + </message> + <message> + <source>&Show / Hide</source> + <translation>Mostrar / Ocultar</translation> + </message> + <message> <source>&File</source> <translation>&Archivo</translation> </message> @@ -155,6 +255,18 @@ <translation>Barra de herramientas</translation> </message> <message> + <source>Error</source> + <translation>Error</translation> + </message> + <message> + <source>Warning</source> + <translation>Alerta</translation> + </message> + <message> + <source>Information</source> + <translation>Información</translation> + </message> + <message> <source>Up to date</source> <translation>A la fecha</translation> </message> @@ -163,6 +275,17 @@ <translation>Ponerse al dia...</translation> </message> <message> + <source>Type: %1 +</source> + <translation>Tipo: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Dirección: %1</translation> + </message> + <message> <source>Sent transaction</source> <translation>Transaccion enviada</translation> </message> @@ -185,10 +308,38 @@ <context> <name>CoinControlDialog</name> <message> + <source>Quantity:</source> + <translation>Cantidad:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Bytes:</translation> + </message> + <message> + <source>Amount:</source> + <translation>AMonto:</translation> + </message> + <message> + <source>Priority:</source> + <translation>Prioridad:</translation> + </message> + <message> + <source>Change:</source> + <translation>Cambio:</translation> + </message> + <message> <source>Date</source> <translation>Fecha</translation> </message> <message> + <source>Confirmed</source> + <translation>Confirmado</translation> + </message> + <message> + <source>Priority</source> + <translation>Prioridad</translation> + </message> + <message> <source>(no label)</source> <translation>(Sin etiqueta)</translation> </message> @@ -224,6 +375,10 @@ <translation>Editar dirección de envío </translation> </message> <message> + <source>The entered address "%1" is already in the address book.</source> + <translation>La dirección introducida "%1" ya está en la libreta de direcciones.</translation> + </message> + <message> <source>Could not unlock wallet.</source> <translation>No se puede abrir el monedero.</translation> </message> @@ -240,6 +395,10 @@ </context> <context> <name>Intro</name> + <message> + <source>Error</source> + <translation>Error</translation> + </message> </context> <context> <name>OpenURIDialog</name> @@ -250,6 +409,10 @@ <source>Options</source> <translation>Opciones</translation> </message> + <message> + <source>W&allet</source> + <translation>Billetera</translation> + </message> </context> <context> <name>OverviewPage</name> @@ -272,6 +435,10 @@ </context> <context> <name>RPCConsole</name> + <message> + <source>&Information</source> + <translation>Información</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -283,6 +450,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>Copiar Dirección</translation> + </message> + <message> <source>Address</source> <translation>Direccion </translation> </message> @@ -313,6 +484,26 @@ <translation>Enviar monedas</translation> </message> <message> + <source>Quantity:</source> + <translation>Cantidad:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Bytes:</translation> + </message> + <message> + <source>Amount:</source> + <translation>AMonto:</translation> + </message> + <message> + <source>Priority:</source> + <translation>Prioridad:</translation> + </message> + <message> + <source>Change:</source> + <translation>Cambio:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Enviar a varios destinatarios a la vez</translation> </message> @@ -367,6 +558,10 @@ <source>Alt+P</source> <translation>Alt+P</translation> </message> + <message> + <source>Pay To:</source> + <translation>Pagar A:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -407,6 +602,10 @@ <translation>Fecha</translation> </message> <message> + <source>Transaction</source> + <translation>Transaccion</translation> + </message> + <message> <source>unknown</source> <translation>desconocido</translation> </message> @@ -432,10 +631,18 @@ <context> <name>TransactionView</name> <message> + <source>Exporting Failed</source> + <translation>Exportación fallida</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Archivos separados por coma (*.csv)</translation> </message> <message> + <source>Confirmed</source> + <translation>Confirmado</translation> + </message> + <message> <source>Date</source> <translation>Fecha</translation> </message> @@ -463,8 +670,28 @@ </context> <context> <name>WalletView</name> + <message> + <source>&Export</source> + <translation>Exportar</translation> + </message> </context> <context> <name>bitcoin-core</name> - </context> + <message> + <source>Options:</source> + <translation>Opciones:</translation> + </message> + <message> + <source>Information</source> + <translation>Información</translation> + </message> + <message> + <source>Warning</source> + <translation>Alerta</translation> + </message> + <message> + <source>Error</source> + <translation>Error</translation> + </message> +</context> </TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_es_VE.ts b/src/qt/locale/bitcoin_es_VE.ts new file mode 100644 index 0000000000..582e728846 --- /dev/null +++ b/src/qt/locale/bitcoin_es_VE.ts @@ -0,0 +1,1133 @@ +<TS language="es_VE" version="2.1"> +<context> + <name>AddressBookPage</name> + <message> + <source>Right-click to edit address or label</source> + <translation>Click derecho para editar la dirección o etiqueta</translation> + </message> + <message> + <source>Create a new address</source> + <translation>Crear una nueva dirección</translation> + </message> + <message> + <source>&New</source> + <translation>&Nuevo</translation> + </message> + <message> + <source>Copy the currently selected address to the system clipboard</source> + <translation>Copie las direcciones seleccionadas actualmente al portapapeles del sistema</translation> + </message> + <message> + <source>&Copy</source> + <translation>&Copiar</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>&Copiar Dirección</translation> + </message> + <message> + <source>Delete the currently selected address from the list</source> + <translation>Borrar las direcciones seleccionadas recientemente de la lista</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Exportar los datos en la pestaña actual a un archivo</translation> + </message> + <message> + <source>&Export</source> + <translation>&Exportar</translation> + </message> + <message> + <source>&Delete</source> + <translation>&Borrar</translation> + </message> + <message> + <source>Choose the address to send coins to</source> + <translation>Elige la dirección para enviar monedas</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>Elige la dirección para recibir monedas</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Envío de direcciones</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Recepción de direcciones</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>Estas son tus direcciones Bitcoin para realizar pagos. Siempre checa el monto y la dirección de recepción antes de enviar monedas.</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>Estas son tus direcciones Bitcoin para recibir pagos. Es recomendable usar una nueva dirección para cada transacción.</translation> + </message> + <message> + <source>Copy &Label</source> + <translation>Copiar &Etiqueta</translation> + </message> + <message> + <source>&Edit</source> + <translation>&Editar</translation> + </message> + <message> + <source>Export Address List</source> + <translation>Exportar lista de direcciones</translation> + </message> + <message> + <source>Comma separated file (*.csv)</source> + <translation>Archivo separado por comas (*.csv)</translation> + </message> + <message> + <source>Exporting Failed</source> + <translation>Exportación fallida</translation> + </message> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Hubo un error intentando guardar la lista de direcciones al %1. Por favor intente nuevamente.</translation> + </message> +</context> +<context> + <name>AddressTableModel</name> + <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> + <source>Address</source> + <translation>Dirección</translation> + </message> + <message> + <source>(no label)</source> + <translation>(sin etiqueta)</translation> + </message> +</context> +<context> + <name>AskPassphraseDialog</name> + <message> + <source>Passphrase Dialog</source> + <translation>Diálogo contraseña</translation> + </message> + <message> + <source>Enter passphrase</source> + <translation>Ingresa frase de contraseña</translation> + </message> + <message> + <source>New passphrase</source> + <translation>Nueva frase de contraseña</translation> + </message> + <message> + <source>Repeat new passphrase</source> + <translation>Repetir nueva frase de contraseña</translation> + </message> + <message> + <source>Encrypt wallet</source> + <translation>Encriptar billetera</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to unlock the wallet.</source> + <translation>Esta operación necesita tu frase de contraseña de la billetera para desbloquearla.</translation> + </message> + <message> + <source>Unlock wallet</source> + <translation>Desbloquear billetera</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to decrypt the wallet.</source> + <translation>Esta operacción necesita tu frase de contraseña para desepcriptar la billetera</translation> + </message> + <message> + <source>Decrypt wallet</source> + <translation>Desencriptar billetera</translation> + </message> + <message> + <source>Change passphrase</source> + <translation>Cambiar frase secreta</translation> + </message> + <message> + <source>Confirm wallet encryption</source> + <translation>Confirmar encriptación de billetera</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>Aviso: Si encriptas tu billetera y pierdes tu frase secreta, ¡PERDERÁS TODOS TUS BITCOINS!</translation> + </message> + <message> + <source>Are you sure you wish to encrypt your wallet?</source> + <translation>¿Está seguro que desea encriptar su billetera?</translation> + </message> + <message> + <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source> + <translation>IMPORTANTE: Algunas copias de seguridad que hayas hecho de tu archivo de billetera deberían ser reemplazadas con la billetera encriptada generada recientemente. Por razones de seguridad, las copias de seguridad previas del archivo de billetera sin cifrar serán inútiles tan pronto uses la nueva billetera encriptada.</translation> + </message> + <message> + <source>Warning: The Caps Lock key is on!</source> + <translation>Aviso: El bloqueo de mayúsculas está activado.</translation> + </message> + <message> + <source>Wallet encrypted</source> + <translation>Billetera 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>Introduce la nueva frase secreta a la billetera. Por favor use una frase secreta de diez o más caracteres aleatorios, u ocho o más palabras.</translation> + </message> + <message> + <source>Wallet encryption failed</source> + <translation>Encriptación de billetera fallida</translation> + </message> + <message> + <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> + <translation>Encriptación de billetera fallida debido a un error interno. Tu billetera no fue encriptada.</translation> + </message> + <message> + <source>The supplied passphrases do not match.</source> + <translation>Las frases secretas introducidas no concuerdan.</translation> + </message> + <message> + <source>Wallet unlock failed</source> + <translation>Desbloqueo de billetera fallido</translation> + </message> + <message> + <source>The passphrase entered for the wallet decryption was incorrect.</source> + <translation>La frase secreta introducida para la desencriptación de la billetera fué incorrecta.</translation> + </message> + <message> + <source>Wallet decryption failed</source> + <translation>Desencriptación de billetera fallida</translation> + </message> + <message> + <source>Wallet passphrase was successfully changed.</source> + <translation>La frase secreta de la billetera fué cambiada exitosamente.</translation> + </message> +</context> +<context> + <name>BanTableModel</name> + </context> +<context> + <name>BitcoinGUI</name> + <message> + <source>Sign &message...</source> + <translation>Firmar &mensaje...</translation> + </message> + <message> + <source>Synchronizing with network...</source> + <translation>Sincronizando con la red...</translation> + </message> + <message> + <source>Node</source> + <translation>Nodo</translation> + </message> + <message> + <source>Show general overview of wallet</source> + <translation>Mostrar visión general de la billetera</translation> + </message> + <message> + <source>&Transactions</source> + <translation>&Transacciones</translation> + </message> + <message> + <source>Browse transaction history</source> + <translation>Buscar historial de transacciones</translation> + </message> + <message> + <source>Quit application</source> + <translation>Quitar aplicación</translation> + </message> + <message> + <source>&Receiving addresses...</source> + <translation>Recepción de direcciones</translation> + </message> + <message> + <source>Bitcoin Core client</source> + <translation>Cliente Bitcoin Core</translation> + </message> + <message> + <source>Importing blocks from disk...</source> + <translation>Importando bloques desde el disco...</translation> + </message> + <message> + <source>Reindexing blocks on disk...</source> + <translation>Reindexando bloques en el disco...</translation> + </message> + <message> + <source>Send coins to a Bitcoin address</source> + <translation>Enviar monedas a una dirección Bitcoin</translation> + </message> + <message> + <source>Backup wallet to another location</source> + <translation>Respaldar billetera en otra ubicación</translation> + </message> + <message> + <source>Change the passphrase used for wallet encryption</source> + <translation>Cambiar frase secreta usada para la encriptación de la billetera</translation> + </message> + <message> + <source>Open debugging and diagnostic console</source> + <translation>Abre la consola de depuración y diágnostico</translation> + </message> + <message> + <source>Bitcoin</source> + <translation>Bitcoin</translation> + </message> + <message> + <source>Wallet</source> + <translation>Billetera</translation> + </message> + <message> + <source>&Send</source> + <translation>&Enviar</translation> + </message> + <message> + <source>&Receive</source> + <translation>&Recibir</translation> + </message> + <message> + <source>Show information about Bitcoin Core</source> + <translation>Mostrar información acerca de Bitcoin Core</translation> + </message> + <message> + <source>&Show / Hide</source> + <translation>&Mostar / Ocultar</translation> + </message> + <message> + <source>Show or hide the main Window</source> + <translation>Mostar u ocultar la ventana principal</translation> + </message> + <message> + <source>Encrypt the private keys that belong to your wallet</source> + <translation>Encriptar las llaves privadas que pertenecen a tu billetera</translation> + </message> + <message> + <source>Sign messages with your Bitcoin addresses to prove you own them</source> + <translation>Firma mensajes con tus direcciones Bitcoin para probar que eres dueño de ellas</translation> + </message> + <message> + <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source> + <translation>Verificar mensajes para asegurar que estaban firmados con direcciones Bitcoin especificas</translation> + </message> + <message> + <source>&File</source> + <translation>&Archivo</translation> + </message> + <message> + <source>&Settings</source> + <translation>&Configuración</translation> + </message> + <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>&About Bitcoin Core</source> + <translation>Acerca de Bitcoin Core</translation> + </message> + <message> + <source>&Command-line options</source> + <translation>Opciones de línea de comandos</translation> + </message> + <message> + <source>%1 and %2</source> + <translation>%1 y %2</translation> + </message> + <message> + <source>%1 behind</source> + <translation>%1 detrás</translation> + </message> + <message> + <source>Last received block was generated %1 ago.</source> + <translation>El último bloque recibido fue generado hace %1 hora(s).</translation> + </message> + <message> + <source>Transactions after this will not yet be visible.</source> + <translation>Transacciones después de esta no serán visibles todavía.</translation> + </message> + <message> + <source>Error</source> + <translation>Error</translation> + </message> + <message> + <source>Warning</source> + <translation>Advertencia</translation> + </message> + <message> + <source>Information</source> + <translation>Información</translation> + </message> + <message> + <source>Up to date</source> + <translation>Al día</translation> + </message> + <message> + <source>Catching up...</source> + <translation>Alcanzando...</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Transacción enviada</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Transacción entrante</translation> + </message> + <message> + <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> + <translation>La billetera está encriptada y desbloqueada recientemente</translation> + </message> + <message> + <source>Wallet is <b>encrypted</b> and currently <b>locked</b></source> + <translation>La billetera está encriptada y bloqueada recientemente</translation> + </message> +</context> +<context> + <name>ClientModel</name> + <message> + <source>Network Alert</source> + <translation>Alerta de red</translation> + </message> +</context> +<context> + <name>CoinControlDialog</name> + <message> + <source>Coin Selection</source> + <translation>Selección de moneda</translation> + </message> + <message> + <source>Quantity:</source> + <translation>Cantidad:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Bytes:</translation> + </message> + <message> + <source>Amount:</source> + <translation>Monto:</translation> + </message> + <message> + <source>Priority:</source> + <translation>Prioridad:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Comisión:</translation> + </message> + <message> + <source>Dust:</source> + <translation>Polvo:</translation> + </message> + <message> + <source>Change:</source> + <translation>Cambio:</translation> + </message> + <message> + <source>(un)select all</source> + <translation>(de)seleccionar todo</translation> + </message> + <message> + <source>Tree mode</source> + <translation>Modo de árbol</translation> + </message> + <message> + <source>List mode</source> + <translation>Modo de lista</translation> + </message> + <message> + <source>Amount</source> + <translation>Monto</translation> + </message> + <message> + <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> + <translation>Fecha</translation> + </message> + <message> + <source>Confirmations</source> + <translation>Confirmaciones</translation> + </message> + <message> + <source>Confirmed</source> + <translation>Confirmado</translation> + </message> + <message> + <source>Priority</source> + <translation>Prioridad</translation> + </message> + <message> + <source>Copy address</source> + <translation>Copiar dirección</translation> + </message> + <message> + <source>Copy label</source> + <translation>Copiar etiqueta</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Copiar monto</translation> + </message> + <message> + <source>Copy transaction ID</source> + <translation>Copiar ID de la transacción</translation> + </message> + <message> + <source>Lock unspent</source> + <translation>Bloqueo no gastado</translation> + </message> + <message> + <source>Unlock unspent</source> + <translation>Desbloqueo no gastado</translation> + </message> + <message> + <source>Copy quantity</source> + <translation>Copiar cantidad</translation> + </message> + <message> + <source>Copy fee</source> + <translation>Copiar comisión</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Copiar bytes</translation> + </message> + <message> + <source>Copy priority</source> + <translation>Copiar prioridad</translation> + </message> + <message> + <source>Copy dust</source> + <translation>Copiar dust</translation> + </message> + <message> + <source>Copy change</source> + <translation>Copiar cambio</translation> + </message> + <message> + <source>highest</source> + <translation>Más alto</translation> + </message> + <message> + <source>higher</source> + <translation>superior</translation> + </message> + <message> + <source>high</source> + <translation>alto</translation> + </message> + <message> + <source>medium-high</source> + <translation>medio-alto</translation> + </message> + <message> + <source>medium</source> + <translation>medio</translation> + </message> + <message> + <source>low-medium</source> + <translation>bajo-medio</translation> + </message> + <message> + <source>low</source> + <translation>bajo</translation> + </message> + <message> + <source>lower</source> + <translation>inferior</translation> + </message> + <message> + <source>lowest</source> + <translation>más bajo</translation> + </message> + <message> + <source>(%1 locked)</source> + <translation>(%1 bloqueado)</translation> + </message> + <message> + <source>none</source> + <translation>ninguno</translation> + </message> + <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>Puede variar +/- %1 satoshi(s) por entrada.</translation> + </message> + <message> + <source>yes</source> + <translation>si</translation> + </message> + <message> + <source>no</source> + <translation>no</translation> + </message> + <message> + <source>This means a fee of at least %1 per kB is required.</source> + <translation>Esto significa que se requiere al menos de una comisión de %1 por kB</translation> + </message> + <message> + <source>Can vary +/- 1 byte per input.</source> + <translation>Puede variar +/- 1 byte por entrada.</translation> + </message> + <message> + <source>Transactions with higher priority are more likely to get included into a block.</source> + <translation>Transacciones con mayor prioridad son más probables de ser incluidas en un bloque.</translation> + </message> + <message> + <source>(no label)</source> + <translation>(sin etiqueta)</translation> + </message> + <message> + <source>change from %1 (%2)</source> + <translation>Cambio desde %1 (%2)</translation> + </message> + <message> + <source>(change)</source> + <translation>(cambio)</translation> + </message> +</context> +<context> + <name>EditAddressDialog</name> + <message> + <source>Edit Address</source> + <translation>Editar dirección</translation> + </message> + <message> + <source>&Label</source> + <translation>&Etiqueta</translation> + </message> + <message> + <source>The label associated with this address list entry</source> + <translation>La etiqueta asociada con esta entrada de la lista de direcciones</translation> + </message> + <message> + <source>The address associated with this address list entry. This can only be modified for sending addresses.</source> + <translation>La dirección asociada con esta entrada de la lista de direcciones. Esta puede ser modificada solo para el envío de direcciones.</translation> + </message> + <message> + <source>&Address</source> + <translation>&Dirección</translation> + </message> + <message> + <source>New receiving address</source> + <translation>Nueva dirección de recibo</translation> + </message> + <message> + <source>New sending address</source> + <translation>Nueva dirección de envío</translation> + </message> + <message> + <source>Edit receiving address</source> + <translation>Editar dirección de envío</translation> + </message> + <message> + <source>Edit sending address</source> + <translation>Editar dirección de envío</translation> + </message> + <message> + <source>The entered address "%1" is already in the address book.</source> + <translation>La dirección introducida "%1" ya está en el libro de direcciones.</translation> + </message> + <message> + <source>The entered address "%1" is not a valid Bitcoin address.</source> + <translation>La dirección introducida "%1" no es una dirección Bitcoin válida.</translation> + </message> + <message> + <source>Could not unlock wallet.</source> + <translation>No se pudo desbloquear la billetera.</translation> + </message> + <message> + <source>New key generation failed.</source> + <translation>Creación de la nueva llave fallida</translation> + </message> +</context> +<context> + <name>FreespaceChecker</name> + <message> + <source>A new data directory will be created.</source> + <translation>Un nuevo directorio de datos será creado.</translation> + </message> + <message> + <source>name</source> + <translation>nombre</translation> + </message> + <message> + <source>Directory already exists. Add %1 if you intend to create a new directory here.</source> + <translation>El directorio ya existe. Agrega %1 si tiene la intención de crear un nuevo directorio aquí.</translation> + </message> + <message> + <source>Path already exists, and is not a directory.</source> + <translation>La ruta ya existe, y no es un directorio.</translation> + </message> + <message> + <source>Cannot create data directory here.</source> + <translation>No puede crear directorio de datos aquí.</translation> + </message> +</context> +<context> + <name>HelpMessageDialog</name> + <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>version</source> + <translation>versión</translation> + </message> + <message> + <source>(%1-bit)</source> + <translation>(%1-bit)</translation> + </message> + <message> + <source>About Bitcoin Core</source> + <translation>Acerca de Bitcoin Core</translation> + </message> + <message> + <source>Command-line options</source> + <translation>Opciones de línea de comandos</translation> + </message> + <message> + <source>Usage:</source> + <translation>Uso:</translation> + </message> + <message> + <source>command-line options</source> + <translation>opciones de línea de comandos</translation> + </message> + </context> +<context> + <name>Intro</name> + <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 descargará y almacenará una copia de la cadena de bloques Bitcoin. Al menos %1GB de datos serán almacenados en este directorio, y crecerá con el tiempo. La billetera será también almacenada en este directorio.</translation> + </message> + <message> + <source>Use the default data directory</source> + <translation>Usar el directorio de datos por defecto</translation> + </message> + <message> + <source>Use a custom data directory:</source> + <translation>Usa un directorio de datos personalizado:</translation> + </message> + <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>Error: Specified data directory "%1" cannot be created.</source> + <translation>Error: Directorio de datos especificado "%1" no puede ser creado.</translation> + </message> + <message> + <source>Error</source> + <translation>Error</translation> + </message> + </context> +<context> + <name>OpenURIDialog</name> + <message> + <source>Open URI</source> + <translation>Abrir URI</translation> + </message> + <message> + <source>Open payment request from URI or file</source> + <translation>Abrir solicitud de pago desde URI o archivo</translation> + </message> + <message> + <source>URI:</source> + <translation>URI:</translation> + </message> + <message> + <source>Select payment request file</source> + <translation>Seleccionar archivo de solicitud de pago</translation> + </message> + <message> + <source>Select payment request file to open</source> + <translation>Seleccionar archivo de solicitud de pago para abrir</translation> + </message> +</context> +<context> + <name>OptionsDialog</name> + <message> + <source>Options</source> + <translation>Opciones</translation> + </message> + <message> + <source>&Main</source> + <translation>&Main</translation> + </message> + <message> + <source>W&allet</source> + <translation>Billetera</translation> + </message> + <message> + <source>none</source> + <translation>ninguno</translation> + </message> + </context> +<context> + <name>OverviewPage</name> + </context> +<context> + <name>PaymentServer</name> + </context> +<context> + <name>PeerTableModel</name> + </context> +<context> + <name>QObject</name> + <message> + <source>Amount</source> + <translation>Monto</translation> + </message> + </context> +<context> + <name>QRImageWidget</name> + </context> +<context> + <name>RPCConsole</name> + <message> + <source>&Information</source> + <translation>Información</translation> + </message> + </context> +<context> + <name>ReceiveCoinsDialog</name> + <message> + <source>&Amount:</source> + <translation>Monto:</translation> + </message> + <message> + <source>&Label:</source> + <translation>&Etiqueta:</translation> + </message> + <message> + <source>Copy label</source> + <translation>Copiar etiqueta</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Copiar monto</translation> + </message> +</context> +<context> + <name>ReceiveRequestDialog</name> + <message> + <source>Copy &Address</source> + <translation>&Copiar Dirección</translation> + </message> + <message> + <source>Address</source> + <translation>Dirección</translation> + </message> + <message> + <source>Amount</source> + <translation>Monto</translation> + </message> + <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + </context> +<context> + <name>RecentRequestsTableModel</name> + <message> + <source>Date</source> + <translation>Fecha</translation> + </message> + <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> + <source>Amount</source> + <translation>Monto</translation> + </message> + <message> + <source>(no label)</source> + <translation>(sin etiqueta)</translation> + </message> + </context> +<context> + <name>SendCoinsDialog</name> + <message> + <source>Quantity:</source> + <translation>Cantidad:</translation> + </message> + <message> + <source>Bytes:</source> + <translation>Bytes:</translation> + </message> + <message> + <source>Amount:</source> + <translation>Monto:</translation> + </message> + <message> + <source>Priority:</source> + <translation>Prioridad:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Comisión:</translation> + </message> + <message> + <source>Change:</source> + <translation>Cambio:</translation> + </message> + <message> + <source>Dust:</source> + <translation>Polvo:</translation> + </message> + <message> + <source>Copy quantity</source> + <translation>Copiar cantidad</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Copiar monto</translation> + </message> + <message> + <source>Copy fee</source> + <translation>Copiar comisión</translation> + </message> + <message> + <source>Copy bytes</source> + <translation>Copiar bytes</translation> + </message> + <message> + <source>Copy priority</source> + <translation>Copiar prioridad</translation> + </message> + <message> + <source>Copy change</source> + <translation>Copiar cambio</translation> + </message> + <message> + <source>(no label)</source> + <translation>(sin etiqueta)</translation> + </message> + <message> + <source>Copy dust</source> + <translation>Copiar dust</translation> + </message> + </context> +<context> + <name>SendCoinsEntry</name> + <message> + <source>A&mount:</source> + <translation>Monto:</translation> + </message> + <message> + <source>&Label:</source> + <translation>&Etiqueta:</translation> + </message> + </context> +<context> + <name>ShutdownWindow</name> + </context> +<context> + <name>SignVerifyMessageDialog</name> + </context> +<context> + <name>SplashScreen</name> + <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + </context> +<context> + <name>TrafficGraphWidget</name> + </context> +<context> + <name>TransactionDesc</name> + <message> + <source>Date</source> + <translation>Fecha</translation> + </message> + <message> + <source>Transaction</source> + <translation>Transacción</translation> + </message> + <message> + <source>Amount</source> + <translation>Monto</translation> + </message> + </context> +<context> + <name>TransactionDescDialog</name> + </context> +<context> + <name>TransactionTableModel</name> + <message> + <source>Date</source> + <translation>Fecha</translation> + </message> + <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + </context> +<context> + <name>TransactionView</name> + <message> + <source>Copy address</source> + <translation>Copiar dirección</translation> + </message> + <message> + <source>Copy label</source> + <translation>Copiar etiqueta</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Copiar monto</translation> + </message> + <message> + <source>Copy transaction ID</source> + <translation>Copiar ID de la transacción</translation> + </message> + <message> + <source>Exporting Failed</source> + <translation>Exportación fallida</translation> + </message> + <message> + <source>Comma separated file (*.csv)</source> + <translation>Archivo separado por comas (*.csv)</translation> + </message> + <message> + <source>Confirmed</source> + <translation>Confirmado</translation> + </message> + <message> + <source>Date</source> + <translation>Fecha</translation> + </message> + <message> + <source>Label</source> + <translation>Etiqueta</translation> + </message> + <message> + <source>Address</source> + <translation>Dirección</translation> + </message> + </context> +<context> + <name>UnitDisplayStatusBarControl</name> + </context> +<context> + <name>WalletFrame</name> + </context> +<context> + <name>WalletModel</name> + </context> +<context> + <name>WalletView</name> + <message> + <source>&Export</source> + <translation>&Exportar</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Exportar los datos en la pestaña actual a un archivo</translation> + </message> + <message> + <source>Backup Failed</source> + <translation>Copia de seguridad fallida</translation> + </message> + <message> + <source>There was an error trying to save the wallet data to %1.</source> + <translation>Hubo un error intentando guardar los datos de la billetera al %1</translation> + </message> + <message> + <source>The wallet data was successfully saved to %1.</source> + <translation>Los datos de la billetera fueron guardados exitosamente al %1</translation> + </message> + <message> + <source>Backup Successful</source> + <translation>Copia de seguridad completada</translation> + </message> +</context> +<context> + <name>bitcoin-core</name> + <message> + <source>Options:</source> + <translation>Opciones:</translation> + </message> + <message> + <source>Specify data directory</source> + <translation>Especifique directorio de datos</translation> + </message> + <message> + <source>Connect to a node to retrieve peer addresses, and disconnect</source> + <translation>Conecte un nodo para recuperar direcciones pares, y desconecte</translation> + </message> + <message> + <source>Specify your own public address</source> + <translation>Especifique su propia dirección pública</translation> + </message> + <message> + <source>Accept command line and JSON-RPC commands</source> + <translation>Aceptar linea de comando y comandos JSON-RPC</translation> + </message> + <message> + <source>Run in the background as a daemon and accept commands</source> + <translation>Correr en segundo plano como daemon y aceptar comandos</translation> + </message> + <message> + <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source> + <translation>Enlazar dirección dada y siempre escuchar en ella. Usar [host]:port notación para IPv6</translation> + </message> + <message> + <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> + <translation>Borrar todas las transacciones de la billetera y solo recuperar aquellas partes de la cadena de bloques a través de -rescan en el inicio del sistema.</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 licensia de software MIT, ver el archivo adjunto COPYING o <http://www.opensource.org/licenses/mit-license.php>.</translation> + </message> + <message> + <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> + <translation>Ejecutar comando cuando una transacción de la billetera cambia (%s en cmd es reemplazado por TxID)</translation> + </message> + <message> + <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> + <translation>Fija el número de verificación de hilos de script (%u a %d, 0 = auto, <0 = leave that many cores free, default: %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>Esta es una compilación de prueba pre-lanzamiento - use bajo su propio riesgo - no utilizar para aplicaciones de minería o mercantes</translation> + </message> + <message> + <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source> + <translation>Deshabilitar para enlezar a %s en esta computadora. Bitcoin Core probablemente ya está ejecutándose.</translation> + </message> + <message> + <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> + <translation>Aviso: ¡La red no parece estar totalmente de acuerdo! Algunos mineros parecen estar teniendo inconvenientes.</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>Aviso: ¡No parecen estar totalmente de acuerdo con nuestros compañeros! Puede que tengas que actualizar, u otros nodos tengan que actualizarce.</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>Aviso: wallet.dat está corrupto, ¡datos salvados! wallet.dat original guardado como wallet.{timestamp}.bak en %s; si tus transacciones o balance está incorrecto deberías restaurarlo desde una copia de seguridad.</translation> + </message> + <message> + <source>Information</source> + <translation>Información</translation> + </message> + <message> + <source>Warning</source> + <translation>Advertencia</translation> + </message> + <message> + <source>Error</source> + <translation>Error</translation> + </message> +</context> +</TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index c746107bc7..945e4cfa58 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -1,4 +1,4 @@ -<TS language="et" version="2.0"> +<TS language="et" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -177,6 +177,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -326,6 +329,14 @@ <source>Bitcoin Core</source> <translation>Bitcoini tuumik</translation> </message> + <message> + <source>&About Bitcoin Core</source> + <translation>Kirjeldus Bitcoini Tuumast</translation> + </message> + <message> + <source>&Command-line options</source> + <translation>Käsurea valikud</translation> + </message> <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n tund</numerusform><numerusform>%n tundi</numerusform></translation> @@ -603,7 +614,7 @@ <source>command-line options</source> <translation>käsurea valikud</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -637,6 +648,10 @@ <translation>Valikud</translation> </message> <message> + <source>&Main</source> + <translation>&Peamine</translation> + </message> + <message> <source>MB</source> <translation>MB</translation> </message> @@ -807,6 +822,10 @@ <translation>&Informatsioon</translation> </message> <message> + <source>Debug window</source> + <translation>Debugimise aken</translation> + </message> + <message> <source>General</source> <translation>Üldine</translation> </message> @@ -945,6 +964,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>&Kopeeri Aadress</translation> + </message> + <message> <source>Address</source> <translation>Aadress</translation> </message> @@ -1007,6 +1030,10 @@ <translation>Müntide saatmine</translation> </message> <message> + <source>Insufficient funds!</source> + <translation>Liiga suur summa</translation> + </message> + <message> <source>Quantity:</source> <translation>Kogus:</translation> </message> @@ -1019,6 +1046,10 @@ <translation>Tasu:</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Tehingu tasu:</translation> + </message> + <message> <source>Choose...</source> <translation>Vali...</translation> </message> @@ -1129,6 +1160,10 @@ <source>Message:</source> <translation>Sõnum:</translation> </message> + <message> + <source>Pay To:</source> + <translation>Maksa :</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -1281,6 +1316,10 @@ <translation>Avatud kuni %1</translation> </message> <message> + <source>%1/offline</source> + <translation>%1/offline'is</translation> + </message> + <message> <source>%1/unconfirmed</source> <translation>%1/kinnitamata</translation> </message> @@ -1657,10 +1696,6 @@ <translation>Tööta taustal ning aktsepteeri käsklusi</translation> </message> <message> - <source>Use the test network</source> - <translation>Testvõrgu kasutamine</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Luba välisühendusi (vaikeväärtus: 1 kui puudub -proxy või -connect)</translation> </message> @@ -1677,22 +1712,10 @@ <translation>See on test-versioon - kasutamine omal riisikol - ära kasuta mining'uks ega kaupmeeste programmides</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>Hoiatus: -paytxfee on seatud väga kõrgeks! See on sinu poolt makstav tehingu lisatasu.</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>Hoiatus: ilmnes tõrge wallet.dat faili lugemisel! Võtmed on terved, kuid tehingu andmed või aadressiraamatu kirjed võivad olla kadunud või vigased.</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>Hoiatus: toimus wallet.dat faili andmete päästmine! Originaal wallet.dat nimetati kaustas %s ümber wallet.{ajatempel}.bak'iks, jäägi või tehingute ebakõlade puhul tuleks teha backup'ist taastamine.</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Püüa vigasest wallet.dat failist taastada turvavõtmed</translation> - </message> - <message> <source>Block creation options:</source> <translation>Blokeeri loomise valikud:</translation> </message> @@ -1745,28 +1768,36 @@ <translation>Rahakoti valikud:</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Impordi blokid välisest blk000??.dat failist</translation> + <source>(default: %u)</source> + <translation>(vaikimisi: %u)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Tundmatu -whitebind aadress: '%s'</translation> </message> <message> <source>Information</source> <translation>Informatsioon</translation> </message> <message> - <source>RPC server options:</source> - <translation>RPC serveri valikud:</translation> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>-maxtxfee=<amount> jaoks vigane kogus: '%s'</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> + <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> + <translation>-minrelaytxfee=<amount> jaoks vigane kogus: '%s'</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Keele valik, nt "ee_ET" (vaikeväärtus: system locale)</translation> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>-mintxfee=<amount> jaoks vigane kogus: '%s'</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Käivitamisel teabeakna kuvamine (vaikeväärtus: 1)</translation> + <source>RPC server options:</source> + <translation>RPC serveri valikud:</translation> + </message> + <message> + <source>Send trace/debug info to console instead of debug.log file</source> + <translation>Saada jälitus/debug, debug.log faili asemel, konsooli</translation> </message> <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> @@ -1777,10 +1808,6 @@ <translation>Tehingu allkirjastamine ebaõnnestus</translation> </message> <message> - <source>Start minimized</source> - <translation>Käivitu tegumiribale</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>Tehingu summa on tasu maksmiseks liiga väikene</translation> </message> @@ -1793,14 +1820,6 @@ <translation>Tehing liiga suur</translation> </message> <message> - <source>UI Options:</source> - <translation>UI Valikud:</translation> - </message> - <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Kasuta kuulatava pordi määramiseks UPnP ühendust (vaikeväärtus: 1, kui kuulatakse)</translation> - </message> - <message> <source>Username for JSON-RPC connections</source> <translation>JSON-RPC ühenduste kasutajatunnus</translation> </message> @@ -1809,10 +1828,6 @@ <translation>Hoiatus</translation> </message> <message> - <source>on startup</source> - <translation>käivitamisel</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat fail on katki, päästmine ebaõnnestus</translation> </message> @@ -1825,18 +1840,6 @@ <translation>Käivita käsklus, kui parim plokk muutub (käskluse %s asendatakse ploki hash'iga)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Uuenda rahakott uusimasse vormingusse</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Otsi ploki jadast rahakoti kadunud tehinguid</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Kasuta JSON-RPC ühenduste jaoks OpenSSL'i (https)</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 3de9ad5a2f..ca6b6489d1 100644 --- a/src/qt/locale/bitcoin_eu_ES.ts +++ b/src/qt/locale/bitcoin_eu_ES.ts @@ -1,23 +1,103 @@ -<TS language="eu_ES" version="2.0"> +<TS language="eu_ES" version="2.1"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Eskuin-klika helbidea edo etiketa editatzeko</translation> + </message> + <message> <source>Create a new address</source> <translation>Sortu helbide berria</translation> </message> <message> + <source>&New</source> + <translation>&Berria</translation> + </message> + <message> <source>Copy the currently selected address to the system clipboard</source> <translation>Kopiatu hautatutako helbidea sistemaren arbelera</translation> </message> <message> + <source>&Copy</source> + <translation>&Kopiatu</translation> + </message> + <message> + <source>C&lose</source> + <translation>&Itxi</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>&Kopiatu helbidea</translation> + </message> + <message> + <source>Delete the currently selected address from the list</source> + <translation>Ezabatu aukeratutako helbideak listatik</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Esportatu datuak uneko fitxategian</translation> + </message> + <message> + <source>&Export</source> + <translation>&Esportatu</translation> + </message> + <message> <source>&Delete</source> <translation>&Ezabatu</translation> </message> <message> + <source>Choose the address to send coins to</source> + <translation>Aukeratu helbidea txanponak bidaltzeko</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>Aukeratu helbidea txanponak jasotzeko</translation> + </message> + <message> + <source>C&hoose</source> + <translation>&Aukeratu</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Helbideak bidaltzen</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Helbideak jasotzen</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>Hauek dira zure Bitcoin helbideak dirua bidaltzeko. Beti egiaztatu diru-kantitatea eta jasotzeko helbidea bidali baino lehen.</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>Hauek dira zure Bitcoin helbideak dirua jasotzeko. Gomendagarria da erabiltzea jasotzeko helbide berri bat operazio bakoitzeko.</translation> + </message> + <message> + <source>Copy &Label</source> + <translation>Kopiatu &Etiketa</translation> + </message> + <message> + <source>&Edit</source> + <translation>&Editatu</translation> + </message> + <message> + <source>Export Address List</source> + <translation>Esportatu helbide lista</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Komaz bereizitako artxiboa (*.csv)</translation> </message> - </context> + <message> + <source>Exporting Failed</source> + <translation>Esportatua okerra</translation> + </message> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Errakuntza bat egon da gordetzen %1 helbide listan. Mesedez, saiatu berriro.</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -36,6 +116,10 @@ <context> <name>AskPassphraseDialog</name> <message> + <source>Passphrase Dialog</source> + <translation>Pasahitza dialogoa</translation> + </message> + <message> <source>Enter passphrase</source> <translation>Sartu pasahitza</translation> </message> @@ -76,6 +160,22 @@ <translation>Berretsi zorroaren enkriptazioa</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>Abisua: Zuk enkriptatzen baduzu zure diruzorroa eta zure pasahitza galtzen baduzu, <b>BITCOIN GUZTIAK GALDUKO DITUZU</b>!</translation> + </message> + <message> + <source>Are you sure you wish to encrypt your wallet?</source> + <translation>Seguru zaude nahi duzula zure diruzorroa enkriptatu?</translation> + </message> + <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Bitcoin Core orain itxiko da enkriptazio prozezua amaitzeko. Gogoratu enkriptatzean zure diruzorroa ez duzula guztiz babesten zure Bitcoinak lapurretatik infektatzen zure ordenagailua Malwareekin.</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>GARRANTZITSUA: Aurreko seguritate-kopiak ordeztuko dire berriekin, enkriptatutak. Segurtasun arrazoigaitik, aurreko kopiak ezin dira erabili hasiko zarenean zure diruzorro enkriptatu berriarekin.</translation> + </message> + <message> <source>Wallet encrypted</source> <translation>Zorroa enkriptatuta</translation> </message> @@ -105,6 +205,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Synchronizing with network...</source> @@ -147,6 +250,10 @@ <translation>&Aukerak...</translation> </message> <message> + <source>&Receiving addresses...</source> + <translation>Helbideak jasotzen</translation> + </message> + <message> <source>Change the passphrase used for wallet encryption</source> <translation>Aldatu zorroa enkriptatzeko erabilitako pasahitza</translation> </message> @@ -312,10 +419,18 @@ <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>Kopurua</translation> + </message> + <message> <source>&Label:</source> <translation>&Etiketa:</translation> </message> <message> + <source>&Message:</source> + <translation>Mezua</translation> + </message> + <message> <source>Copy label</source> <translation>Kopiatu etiketa</translation> </message> @@ -323,6 +438,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>&Kopiatu helbidea</translation> + </message> + <message> <source>Address</source> <translation>Helbidea</translation> </message> @@ -334,6 +453,10 @@ <source>Label</source> <translation>Etiketa</translation> </message> + <message> + <source>Message</source> + <translation>Mezua</translation> + </message> </context> <context> <name>RecentRequestsTableModel</name> @@ -346,6 +469,10 @@ <translation>Etiketa</translation> </message> <message> + <source>Message</source> + <translation>Mezua</translation> + </message> + <message> <source>Amount</source> <translation>Kopurua</translation> </message> @@ -423,6 +550,10 @@ <source>Message:</source> <translation>Mezua</translation> </message> + <message> + <source>Pay To:</source> + <translation>Ordaindu honi:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -471,6 +602,14 @@ <translation>Data</translation> </message> <message> + <source>Message</source> + <translation>Mezua</translation> + </message> + <message> + <source>Transaction</source> + <translation>Transakzioaren</translation> + </message> + <message> <source>Amount</source> <translation>Kopurua</translation> </message> @@ -628,6 +767,10 @@ <translation>Kopiatu etiketa</translation> </message> <message> + <source>Exporting Failed</source> + <translation>Esportatua okerra</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Komaz bereizitako artxiboa (*.csv)</translation> </message> @@ -663,6 +806,14 @@ </context> <context> <name>WalletView</name> + <message> + <source>&Export</source> + <translation>&Esportatu</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Esportatu datuak uneko fitxategian</translation> + </message> </context> <context> <name>bitcoin-core</name> diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index 5eeea04684..7ab3b77da3 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -1,4 +1,4 @@ -<TS language="fa" version="2.0"> +<TS language="fa" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -217,6 +217,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -394,6 +397,10 @@ <source>Show the list of used receiving addresses and labels</source> <translation>نمایش لیست آدرس های دریافت و لیبل ها</translation> </message> + <message> + <source>&Command-line options</source> + <translation>گزینههای خطفرمان</translation> + </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> <translation><numerusform>%n ارتباط فعال با شبکهٔ بیتکوین</numerusform></translation> @@ -415,6 +422,14 @@ <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> @@ -709,7 +724,7 @@ <source>command-line options</source> <translation>گزینههای خط فرمان</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -740,6 +755,10 @@ <source>Error</source> <translation>خطا</translation> </message> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n گیگابایت فضا موجود است</numerusform></translation> + </message> </context> <context> <name>OpenURIDialog</name> @@ -767,6 +786,10 @@ <translation>&شبکه</translation> </message> <message> + <source>W&allet</source> + <translation>کیف پول</translation> + </message> + <message> <source>Expert</source> <translation>استخراج</translation> </message> @@ -973,6 +996,10 @@ <translation>&اطلاعات</translation> </message> <message> + <source>Debug window</source> + <translation>پنجرهٔ اشکالزدایی</translation> + </message> + <message> <source>Using OpenSSL version</source> <translation>نسخهٔ OpenSSL استفاده شده</translation> </message> @@ -1060,14 +1087,22 @@ <source>Unknown</source> <translation>ناشناخته</translation> </message> - </context> +</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>Show</source> <translation>نمایش</translation> </message> @@ -1091,6 +1126,10 @@ <translation>کد QR</translation> </message> <message> + <source>Copy &Address</source> + <translation>&کپی نشانی</translation> + </message> + <message> <source>Address</source> <translation>نشانی</translation> </message> @@ -1145,6 +1184,10 @@ <translation>ارسال سکه</translation> </message> <message> + <source>Insufficient funds!</source> + <translation>بود جه نا کافی </translation> + </message> + <message> <source>Quantity:</source> <translation>تعداد:</translation> </message> @@ -1173,6 +1216,10 @@ <translation>پول خورد:</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>هزینهٔ تراکنش:</translation> + </message> + <message> <source>fast</source> <translation>سریع</translation> </message> @@ -1287,6 +1334,10 @@ <source>Message:</source> <translation>پیام:</translation> </message> + <message> + <source>Pay To:</source> + <translation>پرداخت به:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -1613,10 +1664,18 @@ <translation>تولید شده ولی قبول نشده</translation> </message> <message> + <source>Offline</source> + <translation>آفلاین</translation> + </message> + <message> <source>Label</source> <translation>برچسب</translation> </message> <message> + <source>Unconfirmed</source> + <translation>تایید نشده</translation> + </message> + <message> <source>Received with</source> <translation>دریافتشده با</translation> </message> @@ -1851,10 +1910,6 @@ <translation>اجرا در پشت زمینه بهصورت یک سرویس و پذیرش دستورات</translation> </message> <message> - <source>Use the test network</source> - <translation>استفاده از شبکهٔ آزمایش</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>پذیرش اتصالات از بیرون (پیش فرض:1 بدون پراکسی یا اتصال)</translation> </message> @@ -1871,10 +1926,6 @@ <translation>این یک نسخه ی آزمایشی است - با مسئولیت خودتان از آن استفاده کنید - آن را در معدن و بازرگانی بکار نگیرید.</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>Block creation options:</source> <translation>بستن گزینه ایجاد</translation> </message> @@ -1903,10 +1954,6 @@ <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> @@ -1927,44 +1974,28 @@ <translation>در حال بازبینی کیف پول...</translation> </message> <message> - <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> - <translation>هشدار: تاریخ و ساعت کامپیوتر خود را بررسی کنید. اگر ساعت درست نباشد هسته بیتکوین به درستی کار نخواهد کرد.</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>انتخاب مسیر دادهها در ابتدای اجرای برنامه (پیشفرض: 0)</translation> - </message> - <message> <source>Information</source> <translation>اطلاعات</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>اطلاعات ردگیری/اشکالزدایی را به جای فایل لاگ اشکالزدایی به کنسول بفرستید</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>زبان را تنظیم کنید؛ برای مثال «de_DE» (زبان پیشفرض محلی)</translation> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>میزان وجه اشتباه برای maxtxfee=<میزان وجه>: %s</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>نمایش پنجرهٔ خوشامدگویی در ابتدای اجرای برنامه (پیشفرض: 1)</translation> + <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> + <translation>میزان وجه اشتباه برای minrelaytxfee=<میزان وجه>: %s</translation> </message> <message> - <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> - <translation>فایل debug.log را در startup مشتری کوچک کن (پیش فرض:1 اگر اشکال زدایی روی نداد)</translation> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>میزان وجه اشتباه برای mintxfee=<میزان وجه>: %s</translation> </message> <message> - <source>Start minimized</source> - <translation>اجرای برنامه به صورت کوچکشده</translation> - </message> - <message> - <source>UI Options:</source> - <translation>گزینههای رابط کاربری:</translation> + <source>Send trace/debug info to console instead of debug.log file</source> + <translation>اطلاعات ردگیری/اشکالزدایی را به جای فایل لاگ اشکالزدایی به کنسول بفرستید</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>از UPnP برای شناسایی درگاه شنیداری استفاده کنید (پیش فرض:1 در زمان شنیدن)</translation> + <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> + <translation>فایل debug.log را در startup مشتری کوچک کن (پیش فرض:1 اگر اشکال زدایی روی نداد)</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -1983,18 +2014,6 @@ <translation>زمانی که بهترین بلاک تغییر کرد، دستور را اجرا کن (%s در cmd با block hash جایگزین شده است)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>wallet را به جدیدترین فرمت روزآمد کنید</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>اسکان مجدد زنجیر بلوکها برای گم والت معامله</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>JSON-RPCبرای ارتباطات استفاده کنید OpenSSL (https)</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 1174e24b46..8bbfc72424 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.0"> +<TS language="fa_IR" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -189,6 +189,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -247,6 +250,10 @@ <translation>تغییر رمز/پَس فرِیز</translation> </message> <message> + <source>&Receiving addresses...</source> + <translation>دریافت آدرس ها</translation> + </message> + <message> <source>Backup wallet to another location</source> <translation>گرفتن نسخه پیشتیبان در آدرسی دیگر</translation> </message> @@ -389,6 +396,10 @@ <translation>ویرایش حساب ارسال کننده</translation> </message> <message> + <source>The entered address "%1" is already in the address book.</source> + <translation>حساب وارد شده «%1» از پیش در دفترچه حساب ها موجود است.</translation> + </message> + <message> <source>The entered address "%1" is not a valid Bitcoin address.</source> <translation>آدرس وارد شده "%1" یک آدرس صحیح برای bitcoin نسشت</translation> </message> @@ -432,6 +443,14 @@ <translation>انتخاب/آپشن</translation> </message> <message> + <source>&Network</source> + <translation>شبکه</translation> + </message> + <message> + <source>W&allet</source> + <translation>کیف پول</translation> + </message> + <message> <source>&OK</source> <translation>و تایید</translation> </message> @@ -501,10 +520,18 @@ <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>Copy label</source> <translation>برچسب را کپی کنید</translation> </message> @@ -516,6 +543,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>کپی آدرس</translation> + </message> + <message> <source>Address</source> <translation>حساب</translation> </message> @@ -570,6 +601,10 @@ <translation>سکه های ارسالی</translation> </message> <message> + <source>Insufficient funds!</source> + <translation>وجوه ناکافی</translation> + </message> + <message> <source>Amount:</source> <translation>میزان وجه:</translation> </message> @@ -682,6 +717,10 @@ <source>Alt+P</source> <translation>Alt و P</translation> </message> + <message> + <source>Sign &Message</source> + <translation>و امضای پیام </translation> + </message> </context> <context> <name>SplashScreen</name> @@ -993,14 +1032,22 @@ <translation>به عنوان daemon بک گراند را اجرا کنید و دستورات را قبول نمایید</translation> </message> <message> - <source>Use the test network</source> - <translation>از تستِ شبکه استفاده نمایید</translation> - </message> - <message> <source>The transaction amount is too small to send after the fee has been deducted</source> <translation>مبلغ تراکنش کمتر از آن است که پس از کسر هزینه تراکنش قابل ارسال باشد</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>میزان اشتباه است for -maxtxfee=<amount>: '%s'</translation> + </message> + <message> + <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> + <translation>میزان اشتباه است for -minrelaytxfee=<amount>: '%s'</translation> + </message> + <message> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>میزان اشتباه است for -mintxfee=<amount>: '%s'</translation> + </message> + <message> <source>RPC server options:</source> <translation>گزینه های سرویس دهنده RPC:</translation> </message> @@ -1025,18 +1072,6 @@ <translation>دستور را وقتی بهترین بلاک تغییر کرد اجرا کن (%s در دستور توسط block hash جایگزین شده است)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>wallet را به جدیدترین نسخه روزآمد کنید</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>زنجیره بلاک را برای تراکنش جا افتاده در WALLET دوباره اسکن کنید</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>برای ارتباطاتِ JSON-RPC از OpenSSL (https) استفاده کنید</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 eb90aa4281..57987b26ec 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -1,4 +1,4 @@ -<TS language="fi" version="2.0"> +<TS language="fi" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/Verkon peite</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Estetty kunnes</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -871,6 +882,34 @@ <source>command-line options</source> <translation>komentorivi parametrit</translation> </message> + <message> + <source>UI Options:</source> + <translation>Käyttöliittymän asetukset:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Valitse datahakemisto käynnistyksen yhteydessä (oletus: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Aseta kieli, esimerkiksi "de_DE" (oletus: järjestelmän kieli)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Käynnistä pienennettynä</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Aseta maksupyynnöille SSL-juurivarmenteet (oletus: -system-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Näytä aloitusruutu käynnistyksen yhteydessä (oletus: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Nollaa kaikki graafisen käyttöliittymän kautta tehdyt muutokset</translation> + </message> </context> <context> <name>Intro</name> @@ -977,6 +1016,14 @@ <translation>IP osoite proxille (esim. IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Minimoi ikkuna ohjelman sulkemisen sijasta kun ikkuna suljetaan. Kun tämä asetus on käytössä, ohjelma suljetaan vain valittaessa valikosta Poistu.</translation> + </message> + <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Käyttöliittymän kieli voidaan asettaa tässä. Tämä asetus tulee käyttöön vasta kun Bitcoin Core käynnistetään uudelleen.</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>Ulkopuoliset URL-osoitteet (esim. block explorer,) jotka esiintyvät siirrot-välilehdellä valikossa. %s URL-osoitteessa korvataan siirtotunnuksella. Useampi URL-osoite on eroteltu pystyviivalla |.</translation> </message> @@ -1061,6 +1108,34 @@ <translation>Proxyn Portti (esim. 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Vertaisten saavuttamiseen käytettävät verkkotyypit:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Ilmoittaa, mikäli oletetettua SOCKS5-välityspalvelinta käytetään tämän verkkotyypin kautta vertaisten saavuttamiseen.</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Yhdistä Bitcoin-verkkoon erillisen SOCKS5-välityspalvelimen kautta piilotettuja Tor-palveluja varten.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Käytä erillistä SOCKS5-välityspalvelinta saavuttaaksesi vertaisia piilotettujen Tor-palveluiden kautta:</translation> + </message> + <message> <source>&Window</source> <translation>&Ikkuna</translation> </message> @@ -1279,10 +1354,6 @@ <translation>Maksupyyntö %1 on liian suuri (%2 tavua, sallittu %3 tavua).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Maksupyynnön DoS-suojaus</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Virhe kommunikoidessa %1n kanssa: %2</translation> </message> @@ -1435,6 +1506,22 @@ <translation>Nykyinen Lohkojen määrä</translation> </message> <message> + <source>Memory Pool</source> + <translation>Muistiallas</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>Tämänhetkinen rahansiirtojen määrä</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Muistin käyttö</translation> + </message> + <message> + <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> + <translation>Avaa Bitcoin Coren debug-loki tämänhetkisestä datahakemistosta. Tämä voi viedä muutaman sekunnin suurille lokitiedostoille.</translation> + </message> + <message> <source>Received</source> <translation>Vastaanotetut</translation> </message> @@ -1447,10 +1534,18 @@ <translation>&Vertaiset</translation> </message> <message> + <source>Banned peers</source> + <translation>Estetyt vertaiset</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Valitse vertainen eriteltyjä tietoja varten.</translation> </message> <message> + <source>Whitelisted</source> + <translation>Sallittu</translation> + </message> + <message> <source>Direction</source> <translation>Suunta</translation> </message> @@ -1459,20 +1554,24 @@ <translation>Versio</translation> </message> <message> - <source>User Agent</source> - <translation>Käyttöliittymä</translation> + <source>Starting Block</source> + <translation>Alkaen lohkosta</translation> </message> <message> - <source>Services</source> - <translation>Palvelut</translation> + <source>Synced Headers</source> + <translation>Synkronoidut ylätunnisteet</translation> </message> <message> - <source>Starting Height</source> - <translation>Aloituskorkeus</translation> + <source>Synced Blocks</source> + <translation>Synkronoidut lohkot</translation> </message> <message> - <source>Sync Height</source> - <translation>Synkronointikorkeus</translation> + <source>User Agent</source> + <translation>Käyttöliittymä</translation> + </message> + <message> + <source>Services</source> + <translation>Palvelut</translation> </message> <message> <source>Ban Score</source> @@ -1491,16 +1590,16 @@ <translation>Viimeisin vastaanotettu</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Tavua lähetetty</translation> + <source>Ping Time</source> + <translation>Vasteaika</translation> </message> <message> - <source>Bytes Received</source> - <translation>Tavua vastaanotettu</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>Tämänhetkisen merkittävän yhteyskokeilun kesto.</translation> </message> <message> - <source>Ping Time</source> - <translation>Vasteaika</translation> + <source>Ping Wait</source> + <translation>Yhteyskokeilun odotus</translation> </message> <message> <source>Time Offset</source> @@ -1551,6 +1650,34 @@ <translation>Tyhjennä konsoli</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>&Katkaise yhteys solmukohtaan</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Estä solmukohta</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &tunti</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &päivä</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &viikko</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &vuosi</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>&Poista solmukohdan esto</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Tervetuloa Bitcoin Coren RPC-konsoliin.</translation> </message> @@ -1579,6 +1706,10 @@ <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(solmukohdan id: %1)</translation> + </message> + <message> <source>via %1</source> <translation>%1 kautta</translation> </message> @@ -1595,12 +1726,16 @@ <translation>Ulosmenevä</translation> </message> <message> - <source>Unknown</source> - <translation>Tuntematon</translation> + <source>Yes</source> + <translation>Kyllä</translation> </message> <message> - <source>Fetching...</source> - <translation>Hankitaan...</translation> + <source>No</source> + <translation>Ei</translation> + </message> + <message> + <source>Unknown</source> + <translation>Tuntematon</translation> </message> </context> <context> @@ -1955,8 +2090,8 @@ <translation>Kopioi vaihtoraha</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Yhteensä %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Kokonaismäärä %1</translation> </message> <message> <source>or</source> @@ -1991,14 +2126,22 @@ <translation>Maksupyyntö on vanhentunut.</translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Maksa vain vähimmäiskulu %1</translation> + <source>Pay only the required fee of %1</source> + <translation>Maksa vain vaadittu kulu kooltaan %1</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Vahvistuminen alkaa arviolta %n lohkon päästä.</numerusform><numerusform>Vahvistuminen alkaa arviolta %n lohkon päästä.</numerusform></translation> </message> <message> <source>The recipient address is not valid. Please recheck.</source> <translation>Vastaanottajan osoite ei ole kelvollinen. Tarkistathan uudelleen.</translation> </message> <message> + <source>Duplicate address found: addresses should only be used once each.</source> + <translation>Duplikaattiosoite löytyi: kutakin osoitetta pitäisi käyttää vain kerran.</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Varoitus: Virheellinen Bitcoin osoite</translation> </message> @@ -2527,6 +2670,10 @@ <translation>Onko rahansiirrossa mukana ainoastaan katseltava osoite vai ei.</translation> </message> <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Käyttäjän määrittämä käyttötarkoitus rahansiirrolle.</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Saldoon lisätty tai siitä vähennetty määrä.</translation> </message> @@ -2606,6 +2753,10 @@ <translation>Kopioi siirtotunnus</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>Kopioi rahansiirron raakavedos</translation> + </message> + <message> <source>Edit label</source> <translation>Muokkaa nimeä</translation> </message> @@ -2753,12 +2904,20 @@ <translation>Hyväksy merkkipohjaiset- ja JSON-RPC-käskyt</translation> </message> <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>Jos <category> on toimittamatta tai jos <category> = 1, tulosta kaikki debug-tieto.</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Virhe: Kriittinen sisäinen virhe kohdattiin, katso debug.log lisätietoja varten</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>Aja taustalla daemonina ja hyväksy komennot</translation> </message> <message> - <source>Use the test network</source> - <translation>Käytä test -verkkoa</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>HTTP-palvelinta ei voitu käynnistää. Katso debug-lokista lisätietoja.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2785,8 +2944,16 @@ <translation>Ei voida yhdistää %s tässä tietokoneessa. Bitcoin Core on luultavasti jo käynnissä.</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> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>Käytä UPnP:ta kuuntelevan portin kartoitukseen (oletus: 1 kun kuunnellaan ja -proxy ei käytössä)</translation> + </message> + <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>VAROITUS: epätavallisen monta lohkoa generoitu, vastaanotettu %d lohkoa viimeisen %d tunnin aikana (odotettavissa %d)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>VAROITUS: tarkista verkkoyhteytesi, vastaanotettu %d lohkoa viimeisen %d tunnin aikana (odotettavissa %d)</translation> </message> <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> @@ -2797,26 +2964,18 @@ <translation>Varoitus: Olemme vertaisverkon kanssa ristiriidassa! Sinun tulee päivittää tai toisten solmujen tulee päivitää.</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>Varoitus: virhe luettaessa wallet.dat-lompakkotiedostoa. Kaikki avaimet luettiin onnistuneesti, mutta siirtohistoria tai osoitekirja saattavat olla kadonneet tai virheellisiä.</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>Varoitus: wallet.dat -lompakkotiedosto on korruptoitunut, tiedot pelastettu. Alkuperäinen wallet.dat -lompakkotiedosto on tallennettu wallet.{timestamp}.bak kansioon %s; jos balanssisi tai siirtohistoria on virheellinen, sinun tulisi palauttaa lompakkotiedosto varmuuskopiosta.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(oletus: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool on oltava vähintään %d MB</translation> </message> <message> <source><category> can be:</source> <translation><category> voi olla:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Yritetään palauttaa privaattiavaimia korruptoituneesta wallet.dat -lompakkotiedostosta</translation> - </message> - <message> <source>Block creation options:</source> <translation>Lohkon luonnin asetukset:</translation> </message> @@ -2845,6 +3004,10 @@ <translation>Haluatko uudelleenrakentaa lohkotietokannan nyt?</translation> </message> <message> + <source>Enable publish raw transaction in <address></source> + <translation>Ota rahansiirtojen raakavedosten julkaisu käyttöön osoitteessa <address></translation> + </message> + <message> <source>Error initializing block database</source> <translation>Virhe alustaessa lohkotietokantaa</translation> </message> @@ -2861,10 +3024,6 @@ <translation>Virhe avattaessa lohkoindeksiä</translation> </message> <message> - <source>Error: A fatal internal error occured, see debug.log for details</source> - <translation>Virhe: Sisäinen kriittinen virhe kohdattiin, katso debug.log:sta lisätietoja</translation> - </message> - <message> <source>Error: Disk space is low!</source> <translation>Varoitus: Levytila on vähissä!</translation> </message> @@ -2873,10 +3032,6 @@ <translation>Ei onnistuttu kuuntelemaan missään portissa. Käytä -listen=0 jos haluat tätä.</translation> </message> <message> - <source>If <category> is not supplied, output all debugging information.</source> - <translation>Jos <kategoria> ei annettu, tulosta kaikki debuggaustieto.</translation> - </message> - <message> <source>Importing...</source> <translation>Tuodaan...</translation> </message> @@ -2941,10 +3096,6 @@ <translation>Sinun tulee uudelleenrakentaa tietokanta käyttäen -reindex vaihtaen -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Tuodaan lohkoja ulkoisesta blk000??.dat tiedostosta</translation> - </message> - <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Ei voida lukita data-hakemistoa %s. Bitcoin Core on luultavasti jo käynnissä.</translation> </message> @@ -2973,18 +3124,14 @@ <translation>Aktivoidaan parhainta ketjua...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>Lompakkoa ei voida ajaa karsitussa tilassa.</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Yritä palauttaa yksityiset avaimet korruptoituneesta wallet.dat-tiedostosta käynnistyksen yhteydessä</translation> </message> <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>-whitebind -osoitetta '%s' ei voida jäsentää</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Valitse data-hakemisto käynnistyksessä (oletus: 0)</translation> - </message> - <message> <source>Connect through SOCKS5 proxy</source> <translation>Yhdistä SOCKS5 proxin kautta</translation> </message> @@ -3005,6 +3152,10 @@ <translation>Tietoa</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Virheellinen määrä -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Virheellinen määrä -minrelaytxfee=<amount>: '%s'</translation> </message> @@ -3017,42 +3168,26 @@ <translation>Välityssolmukohdan asetukset:</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> - <message> <source>RPC server options:</source> <translation>RPC-palvelimen valinnat:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>RPC-tuki pysyville HTTP-yhteyksille (oletus: %d)</translation> - </message> - <message> <source>Receive and display P2P network alerts (default: %u)</source> <translation>Vastaanota ja näytä P2P-verkon hälytyksiä (oletus: %u)</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Lähetä jäljitys/debug-tieto konsoliin, debug.log-tiedoston sijaan</translation> - </message> - <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Aseta SSL root varmenne maksupyynnöille (oletus: -system-)</translation> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Uudelleenskannaa lohkoketju käynnistyksen yhteydessä puuttuvien lompakon rahansiirtojen vuoksi</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Set language, for example "de_DE" (default: system locale)</translation> + <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>Show all debugging options (usage: --help -help-debug)</source> <translation>Näytä kaikki debuggaus valinnat: (käyttö: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Näytä aloitusruutu käynnistettäessä (oletus: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Pienennä debug.log tiedosto käynnistyksen yhteydessä (vakioasetus: 1 kun ei -debug)</translation> </message> @@ -3061,14 +3196,22 @@ <translation>Siirron vahvistus epäonnistui</translation> </message> <message> - <source>Start minimized</source> - <translation>Käynnistä pienennettynä</translation> + <source>The transaction amount is too small to pay the fee</source> + <translation>Rahansiirron määrä on liian pieni kattaakseen maksukulun</translation> </message> <message> <source>This is experimental software.</source> <translation>Tämä on ohjelmistoa kokeelliseen käyttöön.</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>Tor-hallintaportin salasana (oletus: tyhjä)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>Tor-hallintaportti jota käytetään jos onion-kuuntelu on käytössä (oletus: %s)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Siirtosumma liian pieni</translation> </message> @@ -3077,16 +3220,16 @@ <translation>Siirtosumman tulee olla positiivinen</translation> </message> <message> - <source>Transaction too large</source> - <translation>Siirtosumma liian iso</translation> + <source>Transaction too large for fee policy</source> + <translation>Rahansiirto on liian suuri maksukulukäytännölle</translation> </message> <message> - <source>UI Options:</source> - <translation>Ulkoasun asetukset:</translation> + <source>Transaction too large</source> + <translation>Siirtosumma liian iso</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> + <source>Upgrade wallet to latest format on startup</source> + <translation>Päivitä lompakko viimeisimpään formaattiin käynnistyksen yhteydessä</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3101,12 +3244,16 @@ <translation>Varoitus</translation> </message> <message> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>Toimitaanko tilassa jossa ainoastaan lohkot sallitaan (oletus: %u)</translation> + </message> + <message> <source>Zapping all transactions from wallet...</source> <translation>Tyhjennetään kaikki rahansiirrot lompakosta....</translation> </message> <message> - <source>on startup</source> - <translation>käynnistyksessä</translation> + <source>ZeroMQ notification options:</source> + <translation>ZeroMQ-ilmoitusasetukset:</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3121,18 +3268,6 @@ <translation>Suorita käsky kun paras lohko muuttuu (%s cmd on vaihdettu block hashin kanssa)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Päivitä lompakko uusimpaan formaattiin</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Skannaa uudelleen lohkoketju lompakon puuttuvien rahasiirtojen vuoksi</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Käytä OpenSSL:ää (https) JSON-RPC-yhteyksille</translation> - </message> - <message> <source>This help message</source> <translation>Tämä ohjeviesti</translation> </message> @@ -3149,6 +3284,14 @@ <translation>Virhe ladattaessa wallet.dat-tiedostoa: Lompakko vioittunut</translation> </message> <message> + <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>Älä pidä rahansiirtoja muistivarannoissa kauemmin kuin <n> tuntia (oletus: %u)</translation> + </message> + <message> + <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> + <translation>Kuinka läpikäyvä lohkojen -checkblocks -todennus on (0-4, oletus: %u)</translation> + </message> + <message> <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> <translation>Käytä erillistä SOCKS5-proxyä tavoittaaksesi vertaisia Tor-piilopalveluiden kautta (oletus: %s)</translation> </message> @@ -3157,10 +3300,6 @@ <translation>(oletus: %s)</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Hyväksyttävät salaukset (oletus: %s)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Virhe ladattaessa wallet.dat-tiedostoa</translation> </message> @@ -3181,6 +3320,10 @@ <translation>Virheellinen proxy-osoite '%s'</translation> </message> <message> + <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> + <translation>Kuuntele JSON-RPC-yhteyksiä portissa <port> (oletus: %u tai testnet: %u)</translation> + </message> + <message> <source>Listen for connections on <port> (default: %u or testnet: %u)</source> <translation>Kuuntele yhteyksiä portissa <port> (oletus: %u tai testnet: %u)</translation> </message> @@ -3189,16 +3332,20 @@ <translation>Aseta lompakko kuuluttamaan rahansiirtoja</translation> </message> <message> - <source>Relay non-P2SH multisig (default: %u)</source> - <translation>Välitä ei-P2SH-multisig (oletus: %u)</translation> + <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> + <translation>Maksimi yhteyttä kohden käytettävä vastaanottopuskurin koko, <n>*1000 tavua (oletus: %u)</translation> + </message> + <message> + <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source> + <translation>Maksimi yhteyttä kohden käytettävä lähetyspuskurin koko, <n>*1000 tavua (oletus: %u)</translation> </message> <message> - <source>Server certificate file (default: %s)</source> - <translation>Palvelimen sertifikaattitiedosto (oletus: %s)</translation> + <source>Relay and mine data carrier transactions (default: %u)</source> + <translation>Välitä ja louhi dataa kantavia rahansiirtoja (oletus: %u)</translation> </message> <message> - <source>Server private key (default: %s)</source> - <translation>Palvelimen private key (oletus: %s)</translation> + <source>Relay non-P2SH multisig (default: %u)</source> + <translation>Välitä ei-P2SH-multisig (oletus: %u)</translation> </message> <message> <source>Set key pool size to <n> (default: %u)</source> diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index fe140634e6..a0b9feb9ad 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -1,4 +1,4 @@ -<TS language="fr" version="2.0"> +<TS language="fr" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/masque réseau</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Banni jusqu'au</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -723,6 +734,10 @@ <translation>Cette étiquette devient rouge si la priorité est plus basse que « moyenne ».</translation> </message> <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Cette étiquette devient rouge si un destinataire reçoit un montant inférieur à %1.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Peut varier +/- %1 satoshi(s) par entrée.</translation> </message> @@ -867,6 +882,34 @@ <source>command-line options</source> <translation>options de ligne de commande</translation> </message> + <message> + <source>UI Options:</source> + <translation>Options de l'IU :</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Choisir un répertoire de données au démarrage (par défaut : %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Définir la langue, par exemple « fr_CA » (par défaut : la langue du système)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Démarrer minimisé</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Définir les certificats SSL racine pour les requêtes de paiement (par défaut : -system-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Afficher l'écran d'accueil au démarrage (par défaut : %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Réinitialiser tous les changements de paramètres appliqués à l'IUG</translation> + </message> </context> <context> <name>Intro</name> @@ -910,7 +953,11 @@ <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> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(sur %n Go nécessaire)</numerusform><numerusform>(sur %n Go nécessaires)</numerusform></translation> + </message> +</context> <context> <name>OpenURIDialog</name> <message> @@ -1061,6 +1108,34 @@ <translation>Port du serveur mandataire (par ex. 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Utilisé pour rejoindre les pairs par :</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>S'affiche, si le mandataire SOCKS5 par défaut fourni est utilisé pour atteindre les pairs par ce type de réseau.</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Se connecter au réseau Bitcoin au travers d'un mandataire SOCKS5 séparé pour les services cachés de Tor.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Utiliser un mandataire SOCKS5 séparé pour atteindre les pairs grâce aux services cachés de Tor :</translation> + </message> + <message> <source>&Window</source> <translation>&Fenêtre</translation> </message> @@ -1279,10 +1354,6 @@ <translation>La demande de paiement %1 est trop grande (%2 octets, %3 octets permis).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Protection DdS des demandes de paiement</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Erreur de communication avec %1 : %2</translation> </message> @@ -1330,7 +1401,7 @@ </message> <message> <source>%1 d</source> - <translation>%1 d</translation> + <translation>%1 j</translation> </message> <message> <source>%1 h</source> @@ -1435,6 +1506,18 @@ <translation>Nombre actuel de blocs</translation> </message> <message> + <source>Memory Pool</source> + <translation>Réserve de mémoire</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>Nombre actuel de transactions</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Utilisation de la mémoire</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>Ouvrir le journal de débogage du répertoire de données actuel. Ceci pourrait prendre quelques secondes pour les gros fichiers de journalisation.</translation> </message> @@ -1451,10 +1534,18 @@ <translation>&Pairs</translation> </message> <message> + <source>Banned peers</source> + <translation>Pairs bannis</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Choisir un pair pour voir l'information détaillée.</translation> </message> <message> + <source>Whitelisted</source> + <translation>Dans la liste blanche</translation> + </message> + <message> <source>Direction</source> <translation>Direction</translation> </message> @@ -1463,20 +1554,24 @@ <translation>Version</translation> </message> <message> - <source>User Agent</source> - <translation>Agent utilisateur</translation> + <source>Starting Block</source> + <translation>Bloc de départ</translation> </message> <message> - <source>Services</source> - <translation>Services</translation> + <source>Synced Headers</source> + <translation>En-têtes synchronisés</translation> + </message> + <message> + <source>Synced Blocks</source> + <translation>Blocs synchronisés</translation> </message> <message> - <source>Starting Height</source> - <translation>Hauteur de démarrage</translation> + <source>User Agent</source> + <translation>Agent utilisateur</translation> </message> <message> - <source>Sync Height</source> - <translation>Hauteur de synchro</translation> + <source>Services</source> + <translation>Services</translation> </message> <message> <source>Ban Score</source> @@ -1495,16 +1590,16 @@ <translation>Dernière réception</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Octets envoyés</translation> + <source>Ping Time</source> + <translation>Temps de ping</translation> </message> <message> - <source>Bytes Received</source> - <translation>Octets reçus</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>La durée d'un ping actuellement en cours.</translation> </message> <message> - <source>Ping Time</source> - <translation>Temps de ping</translation> + <source>Ping Wait</source> + <translation>Attente du ping</translation> </message> <message> <source>Time Offset</source> @@ -1555,6 +1650,34 @@ <translation>Nettoyer la console</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>&Déconnecter le nœud</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Bannir le nœud pendant</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &heure</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &jour</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &semaine</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &an</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>&Réhabiliter le nœud</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Bienvenue dans le console RPC de Bitcoin Core.</translation> </message> @@ -1583,6 +1706,10 @@ <translation>%1 Go</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(ID de nœud : %1)</translation> + </message> + <message> <source>via %1</source> <translation>par %1</translation> </message> @@ -1599,12 +1726,16 @@ <translation>Sortant</translation> </message> <message> - <source>Unknown</source> - <translation>Inconnu</translation> + <source>Yes</source> + <translation>Oui</translation> </message> <message> - <source>Fetching...</source> - <translation>Récupération...</translation> + <source>No</source> + <translation>Non</translation> + </message> + <message> + <source>Unknown</source> + <translation>Inconnu</translation> </message> </context> <context> @@ -1971,8 +2102,8 @@ <translation>Copier la monnaie</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Montant total %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Montant total %1</translation> </message> <message> <source>or</source> @@ -2006,15 +2137,15 @@ <source>Payment request expired.</source> <translation>Demande de paiement expirée.</translation> </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>Payer seulement les frais exigés de %1</translation> + </message> <message numerus="yes"> <source>Estimated to begin confirmation within %n block(s).</source> <translation><numerusform>Il est estimé que la confirmation commencera dans %n bloc.</numerusform><numerusform>Il est estimé que la confirmation commencera dans %n blocs.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Payer seulement les frais minimum de %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>L'adresse du destinataire est invalide. Veuillez la vérifier.</translation> </message> @@ -2646,6 +2777,10 @@ <translation>Copier l'ID de la transaction</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>Copier la transaction brute</translation> + </message> + <message> <source>Edit label</source> <translation>Modifier l’étiquette</translation> </message> @@ -2793,12 +2928,52 @@ <translation>Accepter les commandes de JSON-RPC et de la ligne de commande</translation> </message> <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>Si <category> n'est pas indiqué ou si <category> = 1, extraire toutes les données de débogage.</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Frais totaux maximaux (en %s) à utiliser en une seule transaction de portefeuille. Les définir trop bas pourrait interrompre les grosses transactions (par défaut : %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Veuillez vérifier que l'heure et la date de votre ordinateur sont justes ! Si votre horloge n'est pas à l'heure, Bitcoin Core ne fonctionnera pas correctement.</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>L'élagage est configuré au-dessous du minimum de %d Mio. Veuillez utiliser un nombre plus élevé.</translation> + </message> + <message> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation>Élagage : la dernière synchronisation de portefeuille va par-delà les données élaguées. Vous devez -reindex (réindexer, télécharger de nouveau toute la chaîne de blocs en cas de nœud élagué)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Réduire les exigences de stockage en élaguant (supprimant) les anciens blocs. Ce mode est incompatible avec -txindex et -rescan. Avertissement : ramener ce paramètre à sa valeur antérieure exige un nouveau téléchargement de la chaîne de blocs en entier (par défaut : 0 = désactiver l'élagage des blocs, >%u = taille cible en Mio à utiliser pour les fichiers de blocs).</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>Les rebalayages sont impossibles en mode élagage. Vous devrez utiliser -reindex, ce qui téléchargera de nouveau la chaîne de blocs en entier.</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Erreur : une erreur interne fatale s'est produite. Voir debug.log pour plus de détails</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Les frais (en %s/ko) à ajouter aux transactions que vous envoyez (par défaut : %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Élagage du magasin de blocs...</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>Fonctionner en arrière-plan en tant que démon et accepter les commandes</translation> </message> <message> - <source>Use the test network</source> - <translation>Utiliser le réseau de test</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>Impossible de démarrer le serveur HTTP. Voir le journal de débogage pour plus de détails.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2810,7 +2985,7 @@ </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> + <translation>Supprimer toutes les transactions du portefeuille et ne récupérer que ces parties de la chaîne de blocs avec -rescan au démarrage</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> @@ -2821,18 +2996,14 @@ <translation>Exécuter la commande lorsqu'une transaction de portefeuille change (%s dans la commande est remplacée par TxID)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Total maximal des frais à utiliser en une seule transaction de portefeuille. Le définir trop bas pourrait interrompre les grosses transactions (par défaut : %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Réduire les exigences de stockage en élaguant (supprimant) les anciens blocs. Ce mode désactive la prise en charge de portefeuilles et n'est pas compatible avec -txindex. Avertissement : configurer ce paramètre à sa valeur antérieure retéléchargera complètement la chaîne de blocs (par défaut : 0 = désactiver l'élagage des blocs, >%u = taille cible en Mo à utiliser pour les fichiers de blocs).</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <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>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>La base de données de blocs contient un bloc qui semble provenir du futur. Cela pourrait être causé par la date et l'heure erronées de votre ordinateur. Ne reconstruisez la base de données de blocs que si vous êtes certain que la date et l'heure de votre ordinateur sont justes.</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> @@ -2841,6 +3012,10 @@ <translation>Impossible de se lier à %s sur cet ordinateur. Bitcoin Core fonctionne probablement déjà.</translation> </message> <message> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 lors de l'écoute et pas de mandataire -proxy)</translation> + </message> + <message> <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> <translation>AVERTISSEMENT : un nombre anormalement élevé de blocs a été généré, %d blocs reçus durant les %d dernières heures (%d attendus)</translation> </message> @@ -2849,10 +3024,6 @@ <translation>AVERTISSEMENT : vérifiez votre connexion réseau, %d blocs reçus durant les %d dernières heures (%d attendus)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Avertissement : -paytxfee est réglé sur un montant très élevé ! Il s'agit des frais de transaction que vous payerez si vous envoyez une transaction.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Avertissement : le réseau ne semble pas totalement d'accord ! Quelques mineurs semblent éprouver des difficultés.</translation> </message> @@ -2861,10 +3032,6 @@ <translation>Avertissement : nous ne semblons pas être en accord complet avec nos pairs ! Vous pourriez avoir besoin d'effectuer une mise à niveau, ou d'autres nœuds du réseau pourraient avoir besoin d'effectuer une mise à niveau.</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>Avertissement : une erreur est survenue lors de la lecture de wallet.dat ! Toutes les clefs ont été lues correctement mais les données de transaction ou les entrées du carnet d'adresses sont peut-être incorrectes ou manquantes.</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>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> @@ -2873,18 +3040,14 @@ <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: 1)</source> - <translation>(par défaut : 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool doit être d'au moins %d Mo</translation> </message> <message> <source><category> can be:</source> <translation><category> peut être :</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Tenter de récupérer les clefs privées d'un wallet.dat corrompu</translation> - </message> - <message> <source>Block creation options:</source> <translation>Options de création de bloc :</translation> </message> @@ -2913,6 +3076,22 @@ <translation>Voulez-vous reconstruire la base de données des blocs maintenant ?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation>Activer la publication du bloc de hachage dans <address></translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>Activer la publication de la transaction de hachage dans <address></translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>Activer la publication du bloc brut dans <address></translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation>Activer la publication de la transaction brute dans <address></translation> + </message> + <message> <source>Error initializing block database</source> <translation>Erreur lors de l'initialisation de la base de données des blocs</translation> </message> @@ -2929,10 +3108,6 @@ <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> @@ -2941,10 +3116,6 @@ <translation>Échec de l'écoute sur un port quelconque. Utilisez -listen=0 si vous voulez ceci.</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> - <message> <source>Importing...</source> <translation>Importation...</translation> </message> @@ -2957,6 +3128,10 @@ <translation>Adresse -onion invalide : « %s »</translation> </message> <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>Garder la réserve de mémoire transactionnelle sous <n> mégaoctets (par défaut : %u)</translation> + </message> + <message> <source>Not enough file descriptors available.</source> <translation>Pas assez de descripteurs de fichiers proposés.</translation> </message> @@ -2985,10 +3160,26 @@ <translation>Spécifiez le fichier de portefeuille (dans le répertoire de données)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Argument non pris en charge -benchmark ignoré, utiliser -debug=bench.</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Argument non pris en charge -debugnet ignoré, utiliser -debug=net.</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>Argument non pris en charge -tor trouvé, utiliser -onion</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>User Agent comment (%s) contains unsafe characters.</source> + <translation>Le commentaire d'agent utilisateur (%s) contient des caractères dangereux.</translation> + </message> + <message> <source>Verifying blocks...</source> <translation>Vérification des blocs en cours...</translation> </message> @@ -3013,18 +3204,10 @@ <translation>Vous devez reconstruire la base de données en utilisant -reindex afin de modifier -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importe des blocs depuis un fichier blk000??.dat externe</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> <message> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation>Une erreur est survenue lors de la mise en place de l'adresse %s port %u d'écoute RPC : %s</translation> - </message> - <message> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> <translation>Se lier à l'adresse donnée et aux pairs s'y connectant. Utiliser la notation [host]:port pour l'IPv6</translation> </message> @@ -3049,16 +3232,12 @@ <translation>Erreur : l'écoute des connexions entrantes a échoué (l'écoute a retourné l'erreur %s)</translation> </message> <message> - <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> - <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 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> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Les frais (en BTC/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour le relayage (par défaut : %s)</translation> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>Les frais (en %s/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour le relais, le minage et la création de transactions (par défaut : %s)</translation> </message> <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> @@ -3073,10 +3252,6 @@ <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>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>L'élagage est configuré au-dessous du minimum de %d Mo. Veuillez utiliser un nombre plus élevé.</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Demander les adresses des pairs par recherche DNS si l'on manque d'adresses (par défaut : 1 sauf si -connect)</translation> </message> @@ -3101,38 +3276,6 @@ <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> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>Pour utiliser bitcoind, ou l'option -server de bitcoin-qt, vous devez définir un mot de passe rpc dans le fichier de configuration : -%s -Il est recommandé d'utiliser le mot de passe aléatoire suivant : -rpcuser=bitcoinrpc -rpcpassword=%s -(vous n'avez pas à mémoriser ce mot de passe) -Le nom d'utilisateur et le mot de passe NE DOIVENT PAS être identiques. -Si le fichier n'existe pas, créez-le avec la permission lecture-seule-par-le-propriétaire. -Il est aussi recommandé de définir alertnotify afin que les problèmes vous soient signalés ; -par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Avertissement :-maxtxfee est défini très haut ! Des frais aussi élevés pourraient être payés sur une seule transaction.</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>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>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> @@ -3153,16 +3296,20 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Activation de la meilleure chaîne...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>L'exécution est impossible quand le portefeuille est en mode élagage.</translation> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>Toujours relayer les transactions reçues des pairs de la liste blanche (par défaut : %d)</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>Impossible de résoudre l'adresse -whitebind : « %s »</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Tenter de récupérer les clefs privées d'un wallet.dat corrompu lors du démarrage</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Choisir un répertoire de données au démarrage (par défaut : 0)</translation> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Créer automatiquement un service caché Tor (par défaut : %d)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Impossible de résoudre l'adresse -whitebind : « %s »</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3173,10 +3320,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Copyright © 2009-%i Les développeurs de Bitcoin Core</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Impossible d'analyser la valeur -rpcbind %s comme adresse réseau</translation> - </message> - <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Erreur lors du chargement de wallet.dat : le portefeuille exige une version plus récente de Bitcoin Core</translation> </message> @@ -3185,12 +3328,8 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Erreur de lecture de la base de données, fermeture en cours.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Erreur : argument non pris en charge -tor trouvé, utiliser -onion.</translation> - </message> - <message> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation>Les frais (en BTC/ko) à ajouter aux transactions que vous envoyez (par défaut : %s)</translation> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Importe des blocs depuis un fichier blk000??.dat externe lors du démarrage</translation> </message> <message> <source>Information</source> @@ -3233,18 +3372,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Options de relais du nœud :</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> - <message> <source>RPC server options:</source> <translation>Options du serveur RPC :</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>Prise en charge de RPC pour les connexions persistantes HTTP (par défaut : %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Reconstruire au démarrage l'index de la chaîne de blocs à partir des fichiers blk000??.dat actuels</translation> </message> @@ -3253,30 +3384,26 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Recevoir et afficher les alertes du réseau poste à poste (%u par défaut)</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log</translation> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> + <translation>Réduction de -maxconnections de %d à %d, due aux restrictions du système</translation> </message> <message> - <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> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Réanalyser la chaîne de blocs au démarrage, à la recherche de transactions de portefeuille manquantes</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Définir les certificats racine SSL pour les demandes de paiement (par défaut : -système-)</translation> + <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 language, for example "de_DE" (default: system locale)</source> - <translation>Définir la langue, par exemple « fr_CA » (par défaut : la langue du système)</translation> + <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> <translation>Montrer toutes les options de débogage (utilisation : --help --help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Afficher la page de garde au démarrage (par défaut : 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Réduire le fichier debug.log lors du démarrage du client (par défaut : 1 lorsque -debug n'est pas présent)</translation> </message> @@ -3285,10 +3412,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>Start minimized</source> - <translation>Démarrer minimisé</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>Le montant de la transaction est trop bas pour que les frais soient payés</translation> </message> @@ -3297,6 +3420,14 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Ceci est un logiciel expérimental.</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>Mot de passe du port de contrôle Tor (par défaut : vide)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>Port de contrôle Tor à utiliser si l'écoute onion est activée (par défaut :%s)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Montant de la transaction trop bas</translation> </message> @@ -3313,16 +3444,12 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Transaction trop volumineuse</translation> </message> <message> - <source>UI Options:</source> - <translation>Options de l'IU :</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Impossible de se lier à %s sur cet ordinateur (bind a retourné l'erreur %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 lors de l'écoute)</translation> + <source>Upgrade wallet to latest format on startup</source> + <translation>Mettre à niveau le portefeuille au démarrage vers le format le plus récent</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3337,20 +3464,16 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Avertissement</translation> </message> <message> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation>Avertissement : l'argument -benchmark non pris en charge a été ignoré, utiliser -debug=bench.</translation> - </message> - <message> - <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> - <translation>Avertissement : l'argument -debugnet non pris en charge a été ignoré, utiliser -debug=net.</translation> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>Faut-il fonctionner en mode blocs seulement (par défaut : %u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> <translation>Supprimer toutes les transactions du portefeuille...</translation> </message> <message> - <source>on startup</source> - <translation>au démarrage</translation> + <source>ZeroMQ notification options:</source> + <translation>Options de notification ZeroMQ</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3365,18 +3488,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Exécuter la commande lorsque le meilleur bloc change (%s dans cmd est remplacé par le hachage du bloc)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Mettre à niveau le portefeuille vers le format le plus récent</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Utiliser OpenSSL (https) pour les connexions JSON-RPC</translation> - </message> - <message> <source>This help message</source> <translation>Ce message d'aide</translation> </message> @@ -3397,6 +3508,26 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>(1 = conserver les métadonnées de transmission, par ex. les informations du propriétaire du compte et de la demande de paiement, 2 = abandonner les métadonnées de transmission)</translation> </message> <message> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>-maxtxfee est défini très haut ! Des frais aussi élevés pourraient être payés en une seule transaction.</translation> + </message> + <message> + <source>-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> + <translation>-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> + <message> + <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>Ne pas conserver de transactions dans la réserve de mémoire plus de <n> heures (par défaut : %u)</translation> + </message> + <message> + <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> + <translation>Une erreur est survenue lors de la lecture de wallet.dat ! Toutes les clefs ont été lues correctement, mais les données transactionnelles ou les entrées du carnet d'adresses sont peut-être manquantes ou incorrectes.</translation> + </message> + <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>Les frais (en %s/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour la création de transactions (par défaut : %s)</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> @@ -3413,16 +3544,32 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Extraire les informations de débogage (par défaut : %u, fournir <category> est optionnel)</translation> </message> <message> + <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> + <translation>Prendre en charge le filtrage des blocs et des transactions avec les filtres bloom (par défaut : %u)</translation> + </message> + <message> + <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> + <translation>La taille totale de la chaîne de version de réseau (%i) dépasse la longueur maximale (%i). Réduire le nombre ou la taille des commentaires uacomments.</translation> + </message> + <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>Tente de garder le trafic sortant sous la cible donnée (en Mio par 24 h), 0 = sans limite (par défaut : %d)</translation> + </message> + <message> + <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>L'argument non pris en charge -socks a été trouvé. Il n'est plus possible de définir la version de SOCKS, seuls les mandataires SOCKS5 sont pris en charge.</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> + <source>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source> + <translation>Nom d'utilisateur et mot de passe haché pour les connexions JSON-RPC. Le champ <userpw> vient au format : <USERNAME>:<SALT>$<HASH>. Un script python canonique est inclus dans share/rpcuser. Cette option peut être spécifiée plusieurs fois.</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Chiffrements acceptables (par défaut : %s)</translation> + <source>(default: %s)</source> + <translation>(par défaut : %s)</translation> </message> <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> @@ -3493,6 +3640,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com <translation>Définir la taille de bloc minimale en octets (par défaut : %u)</translation> </message> <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <translation>Définir le nombre d'exétrons pour desservir les appels RPC (par défaut : %d)</translation> + </message> + <message> <source>Specify configuration file (default: %s)</source> <translation>Spécifier le fichier de configuration (par défaut : %s)</translation> </message> diff --git a/src/qt/locale/bitcoin_fr_CA.ts b/src/qt/locale/bitcoin_fr_CA.ts index f4fe7d6597..7e6925f96f 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.0"> +<TS language="fr_CA" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -14,6 +14,10 @@ <translation>&Supprimer</translation> </message> <message> + <source>Sending addresses</source> + <translation>envoyer adresse de reception </translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Fichier séparé par une virgule (*.csv)</translation> </message> @@ -65,6 +69,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> </context> <context> @@ -73,12 +80,28 @@ <context> <name>CoinControlDialog</name> <message> + <source>(un)select all</source> + <translation>Toute sélectionner </translation> + </message> + <message> + <source>Copy address</source> + <translation>copier l'adresse </translation> + </message> + <message> <source>(no label)</source> <translation>(pas de record)</translation> </message> </context> <context> <name>EditAddressDialog</name> + <message> + <source>&Label</source> + <translation>Record</translation> + </message> + <message> + <source>&Address</source> + <translation>Addresse</translation> + </message> </context> <context> <name>FreespaceChecker</name> @@ -88,6 +111,10 @@ </context> <context> <name>Intro</name> + <message> + <source>Welcome</source> + <translation>Bienvenue </translation> + </message> </context> <context> <name>OpenURIDialog</name> @@ -176,6 +203,10 @@ <context> <name>TransactionView</name> <message> + <source>Copy address</source> + <translation>copier l'adresse </translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Fichier séparé par une virgule (*.csv)</translation> </message> diff --git a/src/qt/locale/bitcoin_fr_FR.ts b/src/qt/locale/bitcoin_fr_FR.ts new file mode 100644 index 0000000000..df63243353 --- /dev/null +++ b/src/qt/locale/bitcoin_fr_FR.ts @@ -0,0 +1,897 @@ +<TS language="fr_FR" version="2.1"> +<context> + <name>AddressBookPage</name> + <message> + <source>Create a new address</source> + <translation>Créer une nouvelle adresse</translation> + </message> + <message> + <source>Copy the currently selected address to the system clipboard</source> + <translation>Copier l'adresse surlignée dans votre presse-papiers</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Exporter les données de l'onglet courant vers un fichier</translation> + </message> + <message> + <source>&Delete</source> + <translation>&Supprimer</translation> + </message> + <message> + <source>Comma separated file (*.csv)</source> + <translation>Valeurs séparées par des virgules (*.csv)</translation> + </message> + </context> +<context> + <name>AddressTableModel</name> + <message> + <source>Label</source> + <translation>Étiquette</translation> + </message> + <message> + <source>Address</source> + <translation>Adresse</translation> + </message> + <message> + <source>(no label)</source> + <translation>(aucune étiquette)</translation> + </message> +</context> +<context> + <name>AskPassphraseDialog</name> + <message> + <source>Enter passphrase</source> + <translation>Entrez la phrase de passe</translation> + </message> + <message> + <source>New passphrase</source> + <translation>Nouvelle phrase de passe</translation> + </message> + <message> + <source>Repeat new passphrase</source> + <translation>Répétez la phrase de passe</translation> + </message> + <message> + <source>Encrypt wallet</source> + <translation>Chiffrer le porte-monnaie</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to unlock the wallet.</source> + <translation>Cette opération nécessite votre phrase de passe pour déverrouiller le porte-monnaie.</translation> + </message> + <message> + <source>Unlock wallet</source> + <translation>Déverrouiller le porte-monnaie</translation> + </message> + <message> + <source>This operation needs your wallet passphrase to decrypt the wallet.</source> + <translation>Cette opération nécessite votre phrase de passe pour décrypter le porte-monnaie.</translation> + </message> + <message> + <source>Decrypt wallet</source> + <translation>Décrypter le porte-monnaie</translation> + </message> + <message> + <source>Change passphrase</source> + <translation>Changer la phrase de passe</translation> + </message> + <message> + <source>Confirm wallet encryption</source> + <translation>Confirmer le chiffrement du porte-monnaie</translation> + </message> + <message> + <source>Wallet encrypted</source> + <translation>Porte-monnaie chiffré</translation> + </message> + <message> + <source>Wallet encryption failed</source> + <translation>Le chiffrement du porte-monnaie a échoué</translation> + </message> + <message> + <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> + <translation>Le chiffrement du porte-monnaie a échoué en raison d'une erreur interne. Votre porte-monnaie n'a pas été chiffré.</translation> + </message> + <message> + <source>The supplied passphrases do not match.</source> + <translation>Les phrases de passe entrées ne correspondent pas.</translation> + </message> + <message> + <source>Wallet unlock failed</source> + <translation>Le déverrouillage du porte-monnaie a échoué</translation> + </message> + <message> + <source>The passphrase entered for the wallet decryption was incorrect.</source> + <translation>La phrase de passe entrée pour décrypter le porte-monnaie était erronée.</translation> + </message> + <message> + <source>Wallet decryption failed</source> + <translation>Le décryptage du porte-monnaie a échoué</translation> + </message> + </context> +<context> + <name>BanTableModel</name> + </context> +<context> + <name>BitcoinGUI</name> + <message> + <source>Synchronizing with network...</source> + <translation>Synchronisation avec le réseau...</translation> + </message> + <message> + <source>&Overview</source> + <translation>&Vue d'ensemble</translation> + </message> + <message> + <source>Show general overview of wallet</source> + <translation>Affiche une vue d'ensemble du porte-monnaie</translation> + </message> + <message> + <source>&Transactions</source> + <translation>&Transactions</translation> + </message> + <message> + <source>Browse transaction history</source> + <translation>Permet de parcourir l'historique des transactions</translation> + </message> + <message> + <source>E&xit</source> + <translation>Qui&tter</translation> + </message> + <message> + <source>Quit application</source> + <translation>Quitter l'application</translation> + </message> + <message> + <source>About &Qt</source> + <translation>À propos de &Qt</translation> + </message> + <message> + <source>Show information about Qt</source> + <translation>Afficher des informations sur Qt</translation> + </message> + <message> + <source>&Options...</source> + <translation>&Options...</translation> + </message> + <message> + <source>Backup wallet to another location</source> + <translation>Sauvegarder le porte-monnaie à un autre emplacement</translation> + </message> + <message> + <source>Change the passphrase used for wallet encryption</source> + <translation>Modifier la phrase de passe utilisée pour le cryptage du porte-monnaie</translation> + </message> + <message> + <source>Bitcoin</source> + <translation>Bitcoin</translation> + </message> + <message> + <source>&Send</source> + <translation>&Envoyer</translation> + </message> + <message> + <source>&File</source> + <translation>&Fichier</translation> + </message> + <message> + <source>&Settings</source> + <translation>&Réglages</translation> + </message> + <message> + <source>&Help</source> + <translation>&Aide</translation> + </message> + <message> + <source>Tabs toolbar</source> + <translation>Barre d'outils des onglets</translation> + </message> + <message> + <source>Up to date</source> + <translation>À jour</translation> + </message> + <message> + <source>Catching up...</source> + <translation>Rattrapage...</translation> + </message> + <message> + <source>Sent transaction</source> + <translation>Transaction envoyée</translation> + </message> + <message> + <source>Incoming transaction</source> + <translation>Transaction entrante</translation> + </message> + <message> + <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> + <translation>Le porte-monnaie est <b>chiffré</b> et est actuellement <b>déverrouillé</b></translation> + </message> + <message> + <source>Wallet is <b>encrypted</b> and currently <b>locked</b></source> + <translation>Le porte-monnaie est <b>chiffré</b> et est actuellement <b>verrouillé</b></translation> + </message> +</context> +<context> + <name>ClientModel</name> + </context> +<context> + <name>CoinControlDialog</name> + <message> + <source>Amount:</source> + <translation>Montant :</translation> + </message> + <message> + <source>Amount</source> + <translation>Montant</translation> + </message> + <message> + <source>Date</source> + <translation>Date</translation> + </message> + <message> + <source>Confirmed</source> + <translation>Confirmée</translation> + </message> + <message> + <source>Copy address</source> + <translation>Copier l'adresse</translation> + </message> + <message> + <source>Copy label</source> + <translation>Copier l'étiquette</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Copier le montant</translation> + </message> + <message> + <source>(no label)</source> + <translation>(aucune étiquette)</translation> + </message> + </context> +<context> + <name>EditAddressDialog</name> + <message> + <source>Edit Address</source> + <translation>Éditer l'adresse</translation> + </message> + <message> + <source>&Label</source> + <translation>&Étiquette</translation> + </message> + <message> + <source>&Address</source> + <translation>&Adresse</translation> + </message> + <message> + <source>New receiving address</source> + <translation>Nouvelle adresse de réception</translation> + </message> + <message> + <source>New sending address</source> + <translation>Nouvelle adresse d'envoi</translation> + </message> + <message> + <source>Edit receiving address</source> + <translation>Éditer l'adresse de réception</translation> + </message> + <message> + <source>Edit sending address</source> + <translation>Éditer l'adresse d'envoi</translation> + </message> + <message> + <source>The entered address "%1" is already in the address book.</source> + <translation>L'adresse fournie « %1 » est déjà présente dans le carnet d'adresses.</translation> + </message> + <message> + <source>Could not unlock wallet.</source> + <translation>Impossible de déverrouiller le porte-monnaie.</translation> + </message> + <message> + <source>New key generation failed.</source> + <translation>Échec de la génération de la nouvelle clef.</translation> + </message> +</context> +<context> + <name>FreespaceChecker</name> + </context> +<context> + <name>HelpMessageDialog</name> + <message> + <source>Usage:</source> + <translation>Utilisation :</translation> + </message> + </context> +<context> + <name>Intro</name> + </context> +<context> + <name>OpenURIDialog</name> + </context> +<context> + <name>OptionsDialog</name> + <message> + <source>Options</source> + <translation>Options</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>Ouvrir le port du client Bitcoin automatiquement sur le routeur. Cela ne fonctionne que si votre routeur supporte l'UPnP et si la fonctionnalité est activée.</translation> + </message> + <message> + <source>Map port using &UPnP</source> + <translation>Ouvrir le port avec l'&UPnP</translation> + </message> + <message> + <source>&Minimize to the tray instead of the taskbar</source> + <translation>&Minimiser dans la barre système au lieu de la barre des tâches</translation> + </message> + <message> + <source>M&inimize on close</source> + <translation>Mi&nimiser lors de la fermeture</translation> + </message> + </context> +<context> + <name>OverviewPage</name> + <message> + <source>Form</source> + <translation>Formulaire</translation> + </message> + </context> +<context> + <name>PaymentServer</name> + </context> +<context> + <name>PeerTableModel</name> + </context> +<context> + <name>QObject</name> + <message> + <source>Amount</source> + <translation>Montant</translation> + </message> + </context> +<context> + <name>QRImageWidget</name> + </context> +<context> + <name>RPCConsole</name> + <message> + <source>Name</source> + <translation>Nom</translation> + </message> + </context> +<context> + <name>ReceiveCoinsDialog</name> + <message> + <source>&Amount:</source> + <translation>Montant :</translation> + </message> + <message> + <source>&Label:</source> + <translation>&Étiquette :</translation> + </message> + <message> + <source>&Message:</source> + <translation>Message :</translation> + </message> + <message> + <source>Copy label</source> + <translation>Copier l'étiquette</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Copier le montant</translation> + </message> +</context> +<context> + <name>ReceiveRequestDialog</name> + <message> + <source>QR Code</source> + <translation>QR Code</translation> + </message> + <message> + <source>Address</source> + <translation>Adresse</translation> + </message> + <message> + <source>Amount</source> + <translation>Montant</translation> + </message> + <message> + <source>Label</source> + <translation>Étiquette</translation> + </message> + <message> + <source>Message</source> + <translation>Message</translation> + </message> + </context> +<context> + <name>RecentRequestsTableModel</name> + <message> + <source>Date</source> + <translation>Date</translation> + </message> + <message> + <source>Label</source> + <translation>Étiquette</translation> + </message> + <message> + <source>Message</source> + <translation>Message</translation> + </message> + <message> + <source>Amount</source> + <translation>Montant</translation> + </message> + <message> + <source>(no label)</source> + <translation>(aucune étiquette)</translation> + </message> + </context> +<context> + <name>SendCoinsDialog</name> + <message> + <source>Send Coins</source> + <translation>Envoyer des pièces</translation> + </message> + <message> + <source>Insufficient funds!</source> + <translation>Fonds insuffisants</translation> + </message> + <message> + <source>Amount:</source> + <translation>Montant :</translation> + </message> + <message> + <source>Send to multiple recipients at once</source> + <translation>Envoyer des pièces à plusieurs destinataires à la fois</translation> + </message> + <message> + <source>Balance:</source> + <translation>Solde :</translation> + </message> + <message> + <source>Confirm the send action</source> + <translation>Confirmer l'action d'envoi</translation> + </message> + <message> + <source>Confirm send coins</source> + <translation>Confirmer l'envoi des pièces</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Copier le montant</translation> + </message> + <message> + <source>The amount to pay must be larger than 0.</source> + <translation>Le montant à payer doit être supérieur à 0.</translation> + </message> + <message> + <source>(no label)</source> + <translation>(aucune étiquette)</translation> + </message> + </context> +<context> + <name>SendCoinsEntry</name> + <message> + <source>A&mount:</source> + <translation>&Montant :</translation> + </message> + <message> + <source>Pay &To:</source> + <translation>Payer &à :</translation> + </message> + <message> + <source>Enter a label for this address to add it to your address book</source> + <translation>Entrez une étiquette pour cette adresse afin de l'ajouter à votre carnet d'adresses</translation> + </message> + <message> + <source>&Label:</source> + <translation>&Étiquette :</translation> + </message> + <message> + <source>Alt+A</source> + <translation>Alt+A</translation> + </message> + <message> + <source>Paste address from clipboard</source> + <translation>Coller une adresse depuis le presse-papiers</translation> + </message> + <message> + <source>Alt+P</source> + <translation>Alt+P</translation> + </message> + <message> + <source>Message:</source> + <translation>Message :</translation> + </message> + <message> + <source>Pay To:</source> + <translation>Payer à :</translation> + </message> + </context> +<context> + <name>ShutdownWindow</name> + </context> +<context> + <name>SignVerifyMessageDialog</name> + <message> + <source>&Sign Message</source> + <translation>&Signer le message</translation> + </message> + <message> + <source>Alt+A</source> + <translation>Alt+A</translation> + </message> + <message> + <source>Paste address from clipboard</source> + <translation>Coller une adresse depuis le presse-papiers</translation> + </message> + <message> + <source>Alt+P</source> + <translation>Alt+P</translation> + </message> + <message> + <source>Enter the message you want to sign here</source> + <translation>Entrez ici le message que vous désirez signer</translation> + </message> + <message> + <source>Sign &Message</source> + <translation>&Signer le message</translation> + </message> + </context> +<context> + <name>SplashScreen</name> + <message> + <source>[testnet]</source> + <translation>[testnet]</translation> + </message> +</context> +<context> + <name>TrafficGraphWidget</name> + </context> +<context> + <name>TransactionDesc</name> + <message> + <source>Open until %1</source> + <translation>Ouvert jusqu'à %1</translation> + </message> + <message> + <source>%1/unconfirmed</source> + <translation>%1/non confirmée</translation> + </message> + <message> + <source>%1 confirmations</source> + <translation>%1 confirmations</translation> + </message> + <message> + <source>Status</source> + <translation>État</translation> + </message> + <message> + <source>Date</source> + <translation>Date</translation> + </message> + <message> + <source>Generated</source> + <translation>Généré</translation> + </message> + <message> + <source>Credit</source> + <translation>Crédit</translation> + </message> + <message> + <source>Debit</source> + <translation>Débit</translation> + </message> + <message> + <source>Message</source> + <translation>Message</translation> + </message> + <message> + <source>Amount</source> + <translation>Montant</translation> + </message> + <message> + <source>, has not been successfully broadcast yet</source> + <translation>, n'a pas encore été diffusée avec succès</translation> + </message> + <message> + <source>unknown</source> + <translation>inconnue</translation> + </message> +</context> +<context> + <name>TransactionDescDialog</name> + <message> + <source>Transaction details</source> + <translation>Détails de la transaction</translation> + </message> + <message> + <source>This pane shows a detailed description of the transaction</source> + <translation>Ce panneau affiche une description détaillée de la transaction</translation> + </message> +</context> +<context> + <name>TransactionTableModel</name> + <message> + <source>Date</source> + <translation>Date</translation> + </message> + <message> + <source>Type</source> + <translation>Type</translation> + </message> + <message> + <source>Open until %1</source> + <translation>Ouvert jusqu'à %1</translation> + </message> + <message> + <source>Confirmed (%1 confirmations)</source> + <translation>Confirmée (%1 confirmations)</translation> + </message> + <message> + <source>This block was not received by any other nodes and will probably not be accepted!</source> + <translation>Ce bloc n'a été reçu par aucun autre nœud et ne sera probablement pas accepté !</translation> + </message> + <message> + <source>Generated but not accepted</source> + <translation>Généré mais pas accepté</translation> + </message> + <message> + <source>Label</source> + <translation>Étiquette</translation> + </message> + <message> + <source>Received with</source> + <translation>Reçues avec</translation> + </message> + <message> + <source>Received from</source> + <translation>Reçue de</translation> + </message> + <message> + <source>Sent to</source> + <translation>Envoyées à</translation> + </message> + <message> + <source>Payment to yourself</source> + <translation>Paiement à vous-même</translation> + </message> + <message> + <source>Mined</source> + <translation>Extraction</translation> + </message> + <message> + <source>(n/a)</source> + <translation>(indisponible)</translation> + </message> + <message> + <source>Transaction status. Hover over this field to show number of confirmations.</source> + <translation>État de la transaction. Laissez le pointeur de la souris sur ce champ pour voir le nombre de confirmations.</translation> + </message> + <message> + <source>Date and time that the transaction was received.</source> + <translation>Date et heure de réception de la transaction.</translation> + </message> + <message> + <source>Type of transaction.</source> + <translation>Type de transaction.</translation> + </message> + <message> + <source>Amount removed from or added to balance.</source> + <translation>Montant ajouté au ou enlevé du solde.</translation> + </message> +</context> +<context> + <name>TransactionView</name> + <message> + <source>All</source> + <translation>Toutes</translation> + </message> + <message> + <source>Today</source> + <translation>Aujourd'hui</translation> + </message> + <message> + <source>This week</source> + <translation>Cette semaine</translation> + </message> + <message> + <source>This month</source> + <translation>Ce mois</translation> + </message> + <message> + <source>Last month</source> + <translation>Mois dernier</translation> + </message> + <message> + <source>This year</source> + <translation>Cette année</translation> + </message> + <message> + <source>Range...</source> + <translation>Intervalle...</translation> + </message> + <message> + <source>Received with</source> + <translation>Reçues avec</translation> + </message> + <message> + <source>Sent to</source> + <translation>Envoyées à</translation> + </message> + <message> + <source>To yourself</source> + <translation>À vous-même</translation> + </message> + <message> + <source>Mined</source> + <translation>Extraction</translation> + </message> + <message> + <source>Other</source> + <translation>Autres</translation> + </message> + <message> + <source>Enter address or label to search</source> + <translation>Entrez une adresse ou une étiquette à rechercher</translation> + </message> + <message> + <source>Min amount</source> + <translation>Montant min</translation> + </message> + <message> + <source>Copy address</source> + <translation>Copier l'adresse</translation> + </message> + <message> + <source>Copy label</source> + <translation>Copier l'étiquette</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Copier le montant</translation> + </message> + <message> + <source>Edit label</source> + <translation>Éditer l'étiquette</translation> + </message> + <message> + <source>Comma separated file (*.csv)</source> + <translation>Valeurs séparées par des virgules (*.csv)</translation> + </message> + <message> + <source>Confirmed</source> + <translation>Confirmée</translation> + </message> + <message> + <source>Date</source> + <translation>Date</translation> + </message> + <message> + <source>Type</source> + <translation>Type</translation> + </message> + <message> + <source>Label</source> + <translation>Étiquette</translation> + </message> + <message> + <source>Address</source> + <translation>Adresse</translation> + </message> + <message> + <source>ID</source> + <translation>ID</translation> + </message> + <message> + <source>Range:</source> + <translation>Intervalle :</translation> + </message> + <message> + <source>to</source> + <translation>à</translation> + </message> +</context> +<context> + <name>UnitDisplayStatusBarControl</name> + </context> +<context> + <name>WalletFrame</name> + </context> +<context> + <name>WalletModel</name> + <message> + <source>Send Coins</source> + <translation>Envoyer des pièces</translation> + </message> +</context> +<context> + <name>WalletView</name> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Exporter les données de l'onglet courant vers un fichier</translation> + </message> + <message> + <source>Backup Wallet</source> + <translation>Sauvegarder le porte-monnaie</translation> + </message> + <message> + <source>Wallet Data (*.dat)</source> + <translation>Données de porte-monnaie (*.dat)</translation> + </message> + <message> + <source>Backup Failed</source> + <translation>La sauvegarde a échoué</translation> + </message> + </context> +<context> + <name>bitcoin-core</name> + <message> + <source>Options:</source> + <translation>Options :</translation> + </message> + <message> + <source>Specify data directory</source> + <translation>Spécifier le répertoire de données</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> + <message> + <source>Run in the background as a daemon and accept commands</source> + <translation>Fonctionner en arrière-plan en tant que démon et accepter les commandes</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>Username for JSON-RPC connections</source> + <translation>Nom d'utilisateur pour les connexions JSON-RPC</translation> + </message> + <message> + <source>Password for JSON-RPC connections</source> + <translation>Mot de passe pour les connexions JSON-RPC</translation> + </message> + <message> + <source>This help message</source> + <translation>Ce message d'aide</translation> + </message> + <message> + <source>Loading addresses...</source> + <translation>Chargement des adresses...</translation> + </message> + <message> + <source>Error loading wallet.dat: Wallet corrupted</source> + <translation>Erreur lors du chargement de wallet.dat : porte-monnaie corrompu</translation> + </message> + <message> + <source>Error loading wallet.dat</source> + <translation>Erreur lors du chargement de wallet.dat</translation> + </message> + <message> + <source>Insufficient funds</source> + <translation>Fonds insuffisants</translation> + </message> + <message> + <source>Loading block index...</source> + <translation>Chargement de l'index des blocs...</translation> + </message> + <message> + <source>Loading wallet...</source> + <translation>Chargement du porte-monnaie...</translation> + </message> + <message> + <source>Rescanning...</source> + <translation>Nouvelle analyse...</translation> + </message> + <message> + <source>Done loading</source> + <translation>Chargement terminé</translation> + </message> + </context> +</TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts index 709b17e2f7..96d4adeba9 100644 --- a/src/qt/locale/bitcoin_gl.ts +++ b/src/qt/locale/bitcoin_gl.ts @@ -1,4 +1,4 @@ -<TS language="gl" version="2.0"> +<TS language="gl" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -201,6 +201,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -259,6 +262,10 @@ <translation>&Cambiar contrasinal...</translation> </message> <message> + <source>&Receiving addresses...</source> + <translation>Direccións para recibir</translation> + </message> + <message> <source>Importing blocks from disk...</source> <translation>Importando bloques de disco...</translation> </message> @@ -367,6 +374,10 @@ <translation>Abrir un bitcoin: URI ou solicitude de pago</translation> </message> <message> + <source>&Command-line options</source> + <translation>Opcións da liña de comandos</translation> + </message> + <message> <source>No block source available...</source> <translation>Non hai orixe de bloques dispoñible...</translation> </message> @@ -693,7 +704,7 @@ <source>command-line options</source> <translation>opcións da liña de comandos</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -763,6 +774,10 @@ <translation>&Rede</translation> </message> <message> + <source>W&allet</source> + <translation>Moedeiro</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>Abrir automáticamente o porto do cliente Bitcoin no router. Esto so funciona se o teu router soporta UPnP e está habilitado.</translation> </message> @@ -965,6 +980,10 @@ <translation>&Información</translation> </message> <message> + <source>Debug window</source> + <translation>Ventana de Depuración</translation> + </message> + <message> <source>Using OpenSSL version</source> <translation>Usar versión OpenSSL</translation> </message> @@ -1185,6 +1204,10 @@ <translation>Moedas Enviadas</translation> </message> <message> + <source>Insufficient funds!</source> + <translation>Fondos insuficientes</translation> + </message> + <message> <source>Quantity:</source> <translation>Cantidade:</translation> </message> @@ -1209,6 +1232,10 @@ <translation>Cambiar:</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Tarifa de transacción:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Enviar a múltiples receptores á vez</translation> </message> @@ -1348,6 +1375,10 @@ <translation>Eliminar esta entrada</translation> </message> <message> + <source>Message:</source> + <translation>Mensaxe:</translation> + </message> + <message> <source>Enter a label for this address to add it to the list of used addresses</source> <translation>Introduce unha etiqueta para esta dirección para engadila á listaxe de direccións empregadas</translation> </message> @@ -1931,10 +1962,6 @@ <translation>Executar no fondo como un demo e aceptar comandos</translation> </message> <message> - <source>Use the test network</source> - <translation>Empregar a rede de proba</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Aceptar conexións de fóra (por defecto: 1 se non -proxy ou -connect)</translation> </message> @@ -1951,10 +1978,6 @@ <translation>Esta é unha build de test pre-lanzamento - emprégaa baixo o teu propio risco - non empregar para minado ou aplicacións de comerciantes</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>Precaución: -paytxfee está posto moi algo! Esta é a tarifa de transacción que ti pagarás se envías unha transacción.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Precaución: A rede non parece estar totalmente de acordo! Algúns mineitos parecen estar experimentando problemas.</translation> </message> @@ -1963,10 +1986,6 @@ <translation>Precaución: Non parece que esteamos totalmente de acordo cos nosos pares! Pode que precises actualizar, ou outros nodos poden precisar actualizarse.</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>Precaución: erro lendo wallet.dat! Tódalas claves lidas correctamente, pero os datos de transacción ou as entradas do libro de direccións podrían estar ausentes ou incorrectos.</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>Precaución: wallet.dat corrupto, datos salvagardados! O wallet.dat orixinal foi gardado como wallet.{timestamp}.bak en %s; se o teu balance ou transaccións son incorrectas deberías restauralas dende unha copia de seguridade.</translation> </message> @@ -1975,10 +1994,6 @@ <translation><categoría> pode ser:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Tentar recuperar claves privadas dende un wallet.dat corrupto</translation> - </message> - <message> <source>Block creation options:</source> <translation>Opcións de creación de bloque:</translation> </message> @@ -2051,22 +2066,22 @@ <translation>Precisas reconstruír a base de datos empregando -reindex para cambiar -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importa bloques dende arquivos blk000??.dat externos</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>Executar comando cando se recibe unha alerta relevante ou vemos un fork realmente longo (%s no cmd é substituído pola mensaxe)</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Escolle directorio de datos ao arrancar (por defecto: 0)</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Non se pode resolver dirección -whitebind: '%s'</translation> </message> <message> <source>Information</source> <translation>Información</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Cantidade inválida para -maxtxfee=<cantidade>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Cantidade inválida para -minrelaytxfee=<cantidade>: '%s'</translation> </message> @@ -2079,14 +2094,6 @@ <translation>Enviar traza/información de depuración á consola en lugar de ao arquivo debug.log</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Fixar idioma, por exemplo "de_DE" (por defecto: locale del sistema)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Amosar pantalla splash no arranque (por defecto: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Recortar o arquivo debug.log ao arrancar o cliente (por defecto: 1 cando no-debug)</translation> </message> @@ -2095,10 +2102,6 @@ <translation>Fallou a sinatura da transacción</translation> </message> <message> - <source>Start minimized</source> - <translation>Comezar minimizado</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>A cantidade da transacción é demasiado pequena</translation> </message> @@ -2111,10 +2114,6 @@ <translation>A transacción é demasiado grande</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> - <message> <source>Username for JSON-RPC connections</source> <translation>Nome de usuario para conexións JSON-RPC</translation> </message> @@ -2135,18 +2134,6 @@ <translation>Executar comando cando o mellor bloque cambie (%s no comando é sustituído polo hash do bloque)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Actualizar moedeiro ao formato máis recente</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Rescanear transaccións ausentes na cadea de bloques</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Empregar OpenSSL (https) para conexións JSON-RPC</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 deleted file mode 100644 index ef99b0dd39..0000000000 --- a/src/qt/locale/bitcoin_gu_IN.ts +++ /dev/null @@ -1,110 +0,0 @@ -<TS language="gu_IN" version="2.0"> -<context> - <name>AddressBookPage</name> - </context> -<context> - <name>AddressTableModel</name> - </context> -<context> - <name>AskPassphraseDialog</name> - </context> -<context> - <name>BitcoinGUI</name> - </context> -<context> - <name>ClientModel</name> - </context> -<context> - <name>CoinControlDialog</name> - </context> -<context> - <name>EditAddressDialog</name> - </context> -<context> - <name>FreespaceChecker</name> - </context> -<context> - <name>HelpMessageDialog</name> - </context> -<context> - <name>Intro</name> - </context> -<context> - <name>OpenURIDialog</name> - </context> -<context> - <name>OptionsDialog</name> - </context> -<context> - <name>OverviewPage</name> - </context> -<context> - <name>PaymentServer</name> - </context> -<context> - <name>PeerTableModel</name> - </context> -<context> - <name>QObject</name> - </context> -<context> - <name>QRImageWidget</name> - </context> -<context> - <name>RPCConsole</name> - </context> -<context> - <name>ReceiveCoinsDialog</name> - </context> -<context> - <name>ReceiveRequestDialog</name> - </context> -<context> - <name>RecentRequestsTableModel</name> - </context> -<context> - <name>SendCoinsDialog</name> - </context> -<context> - <name>SendCoinsEntry</name> - </context> -<context> - <name>ShutdownWindow</name> - </context> -<context> - <name>SignVerifyMessageDialog</name> - </context> -<context> - <name>SplashScreen</name> - </context> -<context> - <name>TrafficGraphWidget</name> - </context> -<context> - <name>TransactionDesc</name> - </context> -<context> - <name>TransactionDescDialog</name> - </context> -<context> - <name>TransactionTableModel</name> - </context> -<context> - <name>TransactionView</name> - </context> -<context> - <name>UnitDisplayStatusBarControl</name> - </context> -<context> - <name>WalletFrame</name> - </context> -<context> - <name>WalletModel</name> - </context> -<context> - <name>WalletView</name> - </context> -<context> - <name>bitcoin-core</name> - </context> -</TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts index 9c1863de8a..926d206206 100644 --- a/src/qt/locale/bitcoin_he.ts +++ b/src/qt/locale/bitcoin_he.ts @@ -1,4 +1,4 @@ -<TS language="he" version="2.0"> +<TS language="he" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -209,6 +209,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -415,6 +418,10 @@ <translation>%1 ו%2</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> @@ -621,6 +628,10 @@ <translation>הנמוך ביותר</translation> </message> <message> + <source>(%1 locked)</source> + <translation>(%1 נעול)</translation> + </message> + <message> <source>none</source> <translation>ללא</translation> </message> @@ -769,7 +780,7 @@ <source>command-line options</source> <translation>אפשרויות שורת פקודה</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -1313,14 +1324,6 @@ <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> @@ -1337,14 +1340,6 @@ <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> @@ -1433,12 +1428,16 @@ <translation>תעבורה יוצאת</translation> </message> <message> - <source>Unknown</source> - <translation>לא ידוע</translation> + <source>Yes</source> + <translation>כן</translation> </message> <message> - <source>Fetching...</source> - <translation>מתקבל…</translation> + <source>No</source> + <translation>לא</translation> + </message> + <message> + <source>Unknown</source> + <translation>לא ידוע</translation> </message> </context> <context> @@ -1669,6 +1668,10 @@ <translation>כתובת לעודף מותאמת אישית</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>עמלת העברה:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>שליחה למספר מוטבים בו־זמנית</translation> </message> @@ -1737,10 +1740,6 @@ <translation>העתקת עודף</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>הסכום הכולל %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>או</translation> </message> @@ -2495,10 +2494,6 @@ <translation>ריצה כסוכן ברקע וקבלת פקודות</translation> </message> <message> - <source>Use the test network</source> - <translation>שימוש ברשת הבדיקה</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>קבלת חיבורים מבחוץ (בררת מחדל: 1 ללא -proxy או -connect)</translation> </message> @@ -2523,10 +2518,6 @@ <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> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>אזהרה: נראה שלא כל הרשת מסכימה! נראה שישנם כורים שנתקלים בבעיות.</translation> </message> @@ -2535,26 +2526,14 @@ <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> - <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> </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> - <translation>נסה לשחזר מפתחות פרטיים מקובץ wallet.dat מושחת.</translation> - </message> - <message> <source>Block creation options:</source> <translation>אפשרויות יצירת מקטע:</translation> </message> @@ -2607,10 +2586,6 @@ <translation>האזנה נכשלה בכל פורט. השתמש ב- -listen=0 אם ברצונך בכך.</translation> </message> <message> - <source>If <category> is not supplied, output all debugging information.</source> - <translation>אם לא סופקה <קטגוריה> יש לייצא את כל פרטי הניפוי.</translation> - </message> - <message> <source>Importing...</source> <translation>מתבצע יבוא…</translation> </message> @@ -2663,26 +2638,14 @@ <translation>עליך לבנות מחדש את מסד הנתונים תוך שימוש ב־-reindex על מנת לשנות את -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>מיובאים מקטעים מקובצי blk000??.dat חיצוניים</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>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>Cannot resolve -whitebind address: '%s'</source> <translation>לא ניתן לפתור את הכתובת -whitebind: '%s'</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>בחירת תיקיית נתונים עם ההפעלה (בררת מחדל: 0)</translation> - </message> - <message> <source>Connect through SOCKS5 proxy</source> <translation>התחברות דרך מתווך SOCKS5</translation> </message> @@ -2691,22 +2654,10 @@ <translation>כל הזכויות שמורות (C) 2009-%i מתכנתי ליבת ביטקוין</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: הארנק דורש גרסה חדשה יותר של ליבת ביטקוין</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> @@ -2715,6 +2666,10 @@ <translation>בדיקת התקינות ההתחלתית נכשלה. ליבת ביטקוין תיסגר כעת.</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>כמות לא תקינה עבור -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>כמות לא תקינה עבור -paytxfee=<amount>: '%s'</translation> </message> @@ -2739,10 +2694,6 @@ <translation>אפשרויות ממסר מפרק:</translation> </message> <message> - <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> @@ -2751,22 +2702,10 @@ <translation>שלח מידע דיבאג ועקבה לקונסולה במקום לקובץ debug.log</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>הגדרות אישורי בסיס של SSL לבקשות תשלום (בררת המחדל: -מערכת-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>הגדרת שפה, למשל „he_il“ (בררת מחדל: שפת המערכת)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>הצגת כל אפשרויות הניפוי (שימוש: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>הצגת מסך פתיחה בעת הפעלה (בררת מחדל: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>כיווץ הקובץ debug.log בהפעלת הלקוח (בררת מחדל: 1 ללא -debug)</translation> </message> @@ -2775,10 +2714,6 @@ <translation>החתימה על ההעברה נכשלה</translation> </message> <message> - <source>Start minimized</source> - <translation>התחלה במצב ממוזער</translation> - </message> - <message> <source>This is experimental software.</source> <translation>זוהי תכנית נסיונית.</translation> </message> @@ -2799,10 +2734,6 @@ <translation>לא ניתן להתאגד עם הפתחה %s במחשב זה (פעולת האיגוד החזירה את השגיאה %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>יש להשתמש ב־UPnP כדי למפות את הפתחה להאזנה (בררת מחדל: 1 בעת האזנה)</translation> - </message> - <message> <source>Username for JSON-RPC connections</source> <translation>שם משתמש לחיבורי JSON-RPC</translation> </message> @@ -2815,18 +2746,6 @@ <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> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>קובץ wallet.dat מושחת, החילוץ נכשל</translation> </message> @@ -2839,18 +2758,6 @@ <translation>יש לבצע פקודה זו כשהמקטע הטוב ביותר משתנה (%s בפקודה יוחלף בגיבוב המקטע)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>שדרוג הארנק למבנה העדכני</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>יש לסרוק מחדש את שרשרת המקטעים למציאת העברות חסרות בארנק</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>שימוש ב־OpenSSL (https) עבור חיבורי JSON-RPC</translation> - </message> - <message> <source>This help message</source> <translation>הודעת העזרה הזו</translation> </message> diff --git a/src/qt/locale/bitcoin_hi_IN.ts b/src/qt/locale/bitcoin_hi_IN.ts index 01e074ffc6..377ff3a3fa 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.0"> +<TS language="hi_IN" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -117,6 +117,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Synchronizing with network...</source> @@ -332,6 +335,10 @@ <translation>विकल्प</translation> </message> <message> + <source>W&allet</source> + <translation>वॉलेट</translation> + </message> + <message> <source>&OK</source> <translation>&ओके</translation> </message> @@ -383,6 +390,10 @@ <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>राशि :</translation> + </message> + <message> <source>&Label:</source> <translation>लेबल:</translation> </message> @@ -398,6 +409,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>&पता कॉपी करे</translation> + </message> + <message> <source>Address</source> <translation>पता</translation> </message> @@ -498,6 +513,10 @@ <source>Alt+P</source> <translation>Alt-P</translation> </message> + <message> + <source>Pay To:</source> + <translation>प्राप्तकर्ता:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -814,10 +833,6 @@ <translation>बैकग्राउंड में डेमॉन बन कर रन करे तथा कमांड्स स्वीकार करें </translation> </message> <message> - <source>Use the test network</source> - <translation>टेस्ट नेटवर्क का इस्तेमाल करे </translation> - </message> - <message> <source>Verifying blocks...</source> <translation>ब्लॉक्स जाँचे जा रहा है...</translation> </message> diff --git a/src/qt/locale/bitcoin_hr.ts b/src/qt/locale/bitcoin_hr.ts index 74d380ec2b..413dc21857 100644 --- a/src/qt/locale/bitcoin_hr.ts +++ b/src/qt/locale/bitcoin_hr.ts @@ -1,4 +1,4 @@ -<TS language="hr" version="2.0"> +<TS language="hr" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -217,6 +217,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -771,7 +774,7 @@ <source>command-line options</source> <translation>opcije programa u naredbenoj liniji</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -1011,6 +1014,10 @@ <translation>&Informacije</translation> </message> <message> + <source>Debug window</source> + <translation>Konzola za dijagnostiku</translation> + </message> + <message> <source>Using OpenSSL version</source> <translation>OpenSSL verzija u upotrebi</translation> </message> @@ -1055,14 +1062,6 @@ <translation>Trajanje veze</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Bajtova poslano</translation> - </message> - <message> - <source>Bytes Received</source> - <translation>Bajtova primljeno</translation> - </message> - <message> <source>Last block time</source> <translation>Posljednje vrijeme bloka</translation> </message> @@ -1098,7 +1097,7 @@ <source>Unknown</source> <translation>Nepoznato</translation> </message> - </context> +</context> <context> <name>ReceiveCoinsDialog</name> <message> @@ -1219,6 +1218,10 @@ <translation>Slanje novca</translation> </message> <message> + <source>Insufficient funds!</source> + <translation>Nedovoljna sredstva</translation> + </message> + <message> <source>Quantity:</source> <translation>Količina:</translation> </message> @@ -1243,6 +1246,10 @@ <translation>Vraćeno:</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Naknada za transakciju:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Pošalji novce većem broju primatelja u jednoj transakciji</translation> </message> @@ -1372,6 +1379,10 @@ <translation>Potpis</translation> </message> <message> + <source>Sign &Message</source> + <translation>&Potpišite poruku</translation> + </message> + <message> <source>Clear &All</source> <translation>Obriši &sve</translation> </message> @@ -1380,6 +1391,10 @@ <translation>&Potvrdite poruku</translation> </message> <message> + <source>Verify &Message</source> + <translation>&Potvrdite poruku</translation> + </message> + <message> <source>Wallet unlock was cancelled.</source> <translation>Otključavanje novčanika je otkazano.</translation> </message> @@ -1769,14 +1784,6 @@ <translation>Izvršavaj u pozadini kao uslužnik i prihvaćaj komande</translation> </message> <message> - <source>Use the test network</source> - <translation>Koristi test mrežu</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>Upozorenje: -paytxfee je podešen na preveliki iznos. To je iznos koji ćete platiti za obradu transakcije.</translation> - </message> - <message> <source>Block creation options:</source> <translation>Opcije za kreiranje bloka:</translation> </message> @@ -1789,24 +1796,24 @@ <translation>Pogreška: Nema dovoljno prostora na disku!</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Uvozi blokove sa vanjske blk000??.dat datoteke</translation> - </message> - <message> <source>Information</source> <translation>Informacija</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> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Nevaljali iznos za opciju -maxtxfee=<iznos>: '%s'</translation> </message> <message> - <source>Start minimized</source> - <translation>Pokreni minimiziran</translation> + <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> + <translation>Nevaljali iznos za opciju -minrelaytxfee=<iznos>: '%s'</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> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>Nevaljali iznos za opciju -mintxfee=<iznos>: '%s'</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>Username for JSON-RPC connections</source> @@ -1825,18 +1832,6 @@ <translation>Izvršite naredbu kada se najbolji blok promjeni (%s u cmd je zamjenjen sa block hash)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Nadogradite novčanik u posljednji format.</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Koristi OpenSSL (https) za JSON-RPC povezivanje</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 fd476611ee..ab4517ccfa 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -1,4 +1,4 @@ -<TS language="hu" version="2.0"> +<TS language="hu" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -184,6 +184,10 @@ <translation>Add meg a tárca új jelszavát.<br/>Olyan jelszót válassz, ami <b>legalább tíz véletlenszerű karakterből</b> vagy <b>legalább 8 véletlenszerű szóból</b> áll.</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Add meg a tárcához a régi jelszavad és az új jelszavad.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>A tárca titkosítása sikertelen.</translation> </message> @@ -213,6 +217,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -391,6 +398,10 @@ <translation>&A Bitcoin Core-ról</translation> </message> <message> + <source>Modify configuration options for Bitcoin Core</source> + <translation>Konfigurációs opciók módosítása a Bitcoin Core-hoz</translation> + </message> + <message> <source>Show the list of used sending addresses and labels</source> <translation>A használt küldési címek és címkék megtekintése</translation> </message> @@ -410,18 +421,38 @@ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> <translation>A Bitcoin Core súgóüzenet megjelenítése a Bitcoin lehetséges parancssori kapcsolóival.</translation> </message> + <message numerus="yes"> + <source>%n active connection(s) to Bitcoin network</source> + <translation><numerusform>%n aktív kapcsolat a Bitcoin hálózathoz</numerusform><numerusform>%n aktív kapcsolat a Bitcoin hálózathoz</numerusform></translation> + </message> <message> <source>No block source available...</source> <translation>Blokk forrása ismeretlen...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>%n blokk feldolgozva a tranzakció előzményből.</numerusform><numerusform>%n blokk feldolgozva a tranzakció előzményből.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n óra</numerusform><numerusform>%n óra</numerusform></translation> </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n nap</numerusform><numerusform>%n nap</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n hét</numerusform><numerusform>%n hét</numerusform></translation> + </message> <message> <source>%1 and %2</source> <translation>%1 és %2</translation> </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n év</numerusform><numerusform>%n év</numerusform></translation> + </message> <message> <source>%1 behind</source> <translation>%1 lemaradás</translation> @@ -461,12 +492,30 @@ </translation> </message> <message> + <source>Amount: %1 +</source> + <translation>Összeg: %1 +</translation> + </message> + <message> <source>Type: %1 </source> <translation>Típus: %1 </translation> </message> <message> + <source>Label: %1 +</source> + <translation>Címke: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Cím: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Tranzakció elküldve.</translation> </message> @@ -493,6 +542,10 @@ <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>Érme Választás</translation> + </message> + <message> <source>Quantity:</source> <translation>Mennyiség:</translation> </message> @@ -510,7 +563,7 @@ </message> <message> <source>Fee:</source> - <translation>Díjak:</translation> + <translation>Díj:</translation> </message> <message> <source>Dust:</source> @@ -541,6 +594,14 @@ <translation>Összeg</translation> </message> <message> + <source>Received with label</source> + <translation>Címkével érkezett</translation> + </message> + <message> + <source>Received with address</source> + <translation>Címmel érkezett</translation> + </message> + <message> <source>Date</source> <translation>Dátum</translation> </message> @@ -653,6 +714,18 @@ <translation>semmi</translation> </message> <message> + <source>This label turns red if the transaction size is greater than 1000 bytes.</source> + <translation>Ez a címke pirosra változik, ha a tranzakció mérete nagyobb mint 1000 bájt.</translation> + </message> + <message> + <source>This label turns red if the priority is smaller than "medium".</source> + <translation>Ez a címke pirosra változik, ha a prioritás kisebb mint "közepes".</translation> + </message> + <message> + <source>This label turns red if any recipient receives an amount smaller than %1.</source> + <translation>Ez a címke pirosra változik, ha bármely fogadónak %1-nál kevesebb összeg érkezik.</translation> + </message> + <message> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation>Bemenetenként +/- %1 satoshi-val változhat</translation> </message> @@ -793,7 +866,7 @@ <source>command-line options</source> <translation>parancssoros opciók</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -828,6 +901,10 @@ <source>Error</source> <translation>Hiba</translation> </message> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n GB elérhető szabad hely</numerusform><numerusform>%n GB elérhető szabad hely</numerusform></translation> + </message> </context> <context> <name>OpenURIDialog</name> @@ -863,6 +940,10 @@ <translation>&Fő</translation> </message> <message> + <source>Size of &database cache</source> + <translation>A&datbázis gyorsítótár mérete</translation> + </message> + <message> <source>MB</source> <translation>MB</translation> </message> @@ -879,6 +960,10 @@ <translation>A proxy IP címe (pl.: IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source> + <translation>Itt beállíthatod a kezelőfelület nyelvét. A beállítás a Bitcoin újraindítása után lép érvénybe.</translation> + </message> + <message> <source>Reset all client options to default.</source> <translation>Minden kliensbeállítás alapértelmezettre állítása.</translation> </message> @@ -895,8 +980,12 @@ <translation>A Bitcoin elindítása bejelentkezéskor</translation> </message> <message> + <source>W&allet</source> + <translation>T&árca</translation> + </message> + <message> <source>Expert</source> - <translation>szakértő</translation> + <translation>Szakértő</translation> </message> <message> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> @@ -923,6 +1012,18 @@ <translation>Proxy portja (pl.: 9050)</translation> </message> <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> <source>&Window</source> <translation>&Ablak</translation> </message> @@ -994,6 +1095,10 @@ <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>Watch-only:</source> + <translation>Csak megfigyelés</translation> + </message> + <message> <source>Available:</source> <translation>Elérhető:</translation> </message> @@ -1018,6 +1123,10 @@ <translation>Bányászott egyenleg amely még nem érett be.</translation> </message> <message> + <source>Balances</source> + <translation>Egyenlegek</translation> + </message> + <message> <source>Total:</source> <translation>Összesen:</translation> </message> @@ -1044,6 +1153,14 @@ <source>Cannot start bitcoin: click-to-pay handler</source> <translation>A bitcoint nem lehet elindítani: click-to-pay handler</translation> </message> + <message> + <source>Payment request expired.</source> + <translation>A fizetési kérelem lejárt</translation> + </message> + <message> + <source>Invalid payment request.</source> + <translation>Érvénytelen fizetési kérelem</translation> + </message> </context> <context> <name>PeerTableModel</name> @@ -1063,6 +1180,10 @@ <translation>Összeg</translation> </message> <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>Ad meg egy Bitcoin címet (pl: %1)</translation> + </message> + <message> <source>%1 d</source> <translation>%1 n</translation> </message> @@ -1079,10 +1200,18 @@ <translation>%1 mp</translation> </message> <message> + <source>None</source> + <translation>Semmi</translation> + </message> + <message> <source>N/A</source> <translation>Nem elérhető</translation> </message> - </context> + <message> + <source>%1 ms</source> + <translation>%1 ms</translation> + </message> +</context> <context> <name>QRImageWidget</name> <message> @@ -1133,6 +1262,10 @@ <translation>Használt OpenSSL verzió</translation> </message> <message> + <source>Using BerkeleyDB version</source> + <translation>Használt BerkeleyDB verzió</translation> + </message> + <message> <source>Startup time</source> <translation>Bekapcsolás ideje</translation> </message> @@ -1157,6 +1290,10 @@ <translation>Aktuális blokkok száma</translation> </message> <message> + <source>Memory usage</source> + <translation>Memóriahasználat</translation> + </message> + <message> <source>Received</source> <translation>Fogadott</translation> </message> @@ -1169,6 +1306,10 @@ <translation>&Peerek</translation> </message> <message> + <source>Select a peer to view detailed information.</source> + <translation>Peer kijelölése a részletes információkért</translation> + </message> + <message> <source>Version</source> <translation>Verzió</translation> </message> @@ -1181,6 +1322,10 @@ <translation>Szolgáltatások</translation> </message> <message> + <source>Connection Time</source> + <translation>Csatlakozás ideje</translation> + </message> + <message> <source>Last Send</source> <translation>Legutóbbi küldés</translation> </message> @@ -1189,14 +1334,6 @@ <translation>Legutóbbi fogadás</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Küldött bájtok</translation> - </message> - <message> - <source>Bytes Received</source> - <translation>Fogadott bájtok</translation> - </message> - <message> <source>Ping Time</source> <translation>Ping idő</translation> </message> @@ -1217,6 +1354,10 @@ <translation>&Hálózati forgalom</translation> </message> <message> + <source>&Clear</source> + <translation>&Törlés</translation> + </message> + <message> <source>Totals</source> <translation>Összesen:</translation> </message> @@ -1241,6 +1382,22 @@ <translation>Konzol törlése</translation> </message> <message> + <source>1 &hour</source> + <translation>1 &óra</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &nap</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &hét</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &év</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Navigálhat a fel és le nyilakkal, és <b>Ctrl-L</b> -vel törölheti a képernyőt.</translation> </message> @@ -1265,17 +1422,41 @@ <translation>%1 GB</translation> </message> <message> + <source>via %1</source> + <translation>%1 által</translation> + </message> + <message> <source>never</source> <translation>soha</translation> </message> <message> + <source>Inbound</source> + <translation>Bejövő</translation> + </message> + <message> + <source>Outbound</source> + <translation>Kimenő</translation> + </message> + <message> + <source>Yes</source> + <translation>Igen</translation> + </message> + <message> + <source>No</source> + <translation>Nem</translation> + </message> + <message> <source>Unknown</source> <translation>Ismeretlen</translation> </message> - </context> +</context> <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>&Összeg:</translation> + </message> + <message> <source>&Label:</source> <translation>Címke:</translation> </message> @@ -1284,14 +1465,30 @@ <translation>&Üzenet:</translation> </message> <message> + <source>Clear all fields of the form.</source> + <translation>Minden mező törlése</translation> + </message> + <message> <source>Clear</source> <translation>Törlés</translation> </message> <message> + <source>Requested payments history</source> + <translation>A kért kifizetések története</translation> + </message> + <message> + <source>&Request payment</source> + <translation>&Fizetés kérése</translation> + </message> + <message> <source>Show</source> <translation>Mutat</translation> </message> <message> + <source>Remove the selected entries from the list</source> + <translation>A kijelölt elemek törlése a listáról</translation> + </message> + <message> <source>Remove</source> <translation>Eltávolítás</translation> </message> @@ -1327,6 +1524,14 @@ <translation>&Kép mentése</translation> </message> <message> + <source>Request payment to %1</source> + <translation>Fizetés kérése a %1-hez</translation> + </message> + <message> + <source>Payment information</source> + <translation>Kifizetés információ</translation> + </message> + <message> <source>URI</source> <translation>URI:</translation> </message> @@ -1377,7 +1582,15 @@ <source>(no label)</source> <translation>(nincs címke)</translation> </message> - </context> + <message> + <source>(no message)</source> + <translation>(nincs üzenet)</translation> + </message> + <message> + <source>(no amount)</source> + <translation>(nincs összeg)</translation> + </message> +</context> <context> <name>SendCoinsDialog</name> <message> @@ -1389,6 +1602,14 @@ <translation>Bemenetek...</translation> </message> <message> + <source>automatically selected</source> + <translation>automatikusan kiválasztva</translation> + </message> + <message> + <source>Insufficient funds!</source> + <translation>Fedezethiány!</translation> + </message> + <message> <source>Quantity:</source> <translation>Mennyiség:</translation> </message> @@ -1421,10 +1642,34 @@ <translation>Tranzakciós díj</translation> </message> <message> + <source>Choose...</source> + <translation>Válassz...</translation> + </message> + <message> + <source>per kilobyte</source> + <translation>kilobájtonként</translation> + </message> + <message> <source>Hide</source> <translation>Elrejtés</translation> </message> <message> + <source>Recommended:</source> + <translation>Ajánlott:</translation> + </message> + <message> + <source>Custom:</source> + <translation>Egyéni:</translation> + </message> + <message> + <source>normal</source> + <translation>normál</translation> + </message> + <message> + <source>fast</source> + <translation>gyors</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Küldés több címzettnek egyszerre</translation> </message> @@ -1433,6 +1678,10 @@ <translation>&Címzett hozzáadása</translation> </message> <message> + <source>Clear all fields of the form.</source> + <translation>Minden mező törlése</translation> + </message> + <message> <source>Dust:</source> <translation>Por-határ:</translation> </message> @@ -1501,6 +1750,14 @@ <translation>A küldeni kívánt összeg és a %1 tranzakciós díj együtt meghaladja az egyenlegeden rendelkezésedre álló összeget.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>A fizetési kérelem lejárt</translation> + </message> + <message> + <source>Warning: Invalid Bitcoin address</source> + <translation>Figyelmeztetés: Érvénytelen Bitcoin cím</translation> + </message> + <message> <source>(no label)</source> <translation>(nincs címke)</translation> </message> @@ -1508,6 +1765,10 @@ <source>Copy dust</source> <translation>Visszajáró másolása</translation> </message> + <message> + <source>Are you sure you want to send?</source> + <translation>Biztos, hogy el akarod küldeni?</translation> + </message> </context> <context> <name>SendCoinsEntry</name> @@ -1529,6 +1790,10 @@ <translation>Címke:</translation> </message> <message> + <source>Choose previously used address</source> + <translation>Válassz egy korábban már használt címet</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1541,10 +1806,18 @@ <translation>Alt+P</translation> </message> <message> + <source>Remove this entry</source> + <translation>Ez a bejegyzés eltávolítása</translation> + </message> + <message> <source>Message:</source> <translation>Üzenet:</translation> </message> <message> + <source>Pay To:</source> + <translation>Címzett:</translation> + </message> + <message> <source>Memo:</source> <translation>Jegyzet:</translation> </message> @@ -1555,7 +1828,11 @@ <source>Bitcoin Core is shutting down...</source> <translation>A Bitcoin Core leáll...</translation> </message> - </context> + <message> + <source>Do not shut down the computer until this window disappears.</source> + <translation>Ne állítsd le a számítógépet amíg ez az ablak el nem tűnik.</translation> + </message> +</context> <context> <name>SignVerifyMessageDialog</name> <message> @@ -1567,6 +1844,10 @@ <translation>Üzenet aláírása...</translation> </message> <message> + <source>Choose previously used address</source> + <translation>Válassz egy korábban már használt címet</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1607,6 +1888,10 @@ <translation>Üzenet ellenőrzése</translation> </message> <message> + <source>Verify &Message</source> + <translation>Üzenet ellenőrzése</translation> + </message> + <message> <source>The entered address is invalid.</source> <translation>A megadott cím nem érvényes.</translation> </message> @@ -1949,6 +2234,10 @@ <translation>Tranzakciós részletek megjelenítése</translation> </message> <message> + <source>Watch-only</source> + <translation>Csak megfigyelés</translation> + </message> + <message> <source>Exporting Failed</source> <translation>Az exportálás sikertelen volt</translation> </message> @@ -2064,11 +2353,6 @@ </translation> </message> <message> - <source>Use the test network</source> - <translation>Teszthálózat használata -</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Kívülről érkező kapcsolatok elfogadása (alapértelmezett: 1, ha nem használt a -proxy vagy a -connect)</translation> </message> @@ -2077,10 +2361,6 @@ <translation>Parancs, amit akkor hajt végre, amikor egy tárca-tranzakció megváltozik (%s a parancsban lecserélődik a blokk TxID-re)</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>Figyelem: a -paytxfee nagyon magas. Ennyi tranzakciós díjat fogsz fizetni, ha elküldöd a tranzakciót.</translation> - </message> - <message> <source>Connect only to the specified node(s)</source> <translation>Csatlakozás csak a megadott csomóponthoz</translation> </message> @@ -2145,8 +2425,8 @@ <translation>Az adatbázist újra kell építeni -reindex használatával (módosítás -tindex).</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Adatkönyvtár kiválasztása induláskor (alapbeállítás: 0)</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Külső cím (-whitebind address) feloldása nem sikerült: '%s'</translation> </message> <message> <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> @@ -2161,6 +2441,10 @@ <translation>Információ</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Érvénytelen -maxtxfee=<amount>: '%s' összeg</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Érvénytelen -minrelaytxfee=<amount>: '%s' összeg</translation> </message> @@ -2173,27 +2457,10 @@ <translation>trace/debug információ küldése a konzolra a debog.log fájl helyett</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>SLL gyökér-igazolások megadása fizetési kérelmekhez (alapértelmezett: -system-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Nyelvbeállítás, például "de_DE" (alapértelmezett: rendszer nyelve)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Indítóképernyő mutatása induláskor (alapértelmezett: 1)</translation> - </message> - <message> <source>Signing transaction failed</source> <translation>Tranzakció aláírása sikertelen</translation> </message> <message> - <source>Start minimized</source> - <translation>Indítás lekicsinyítve -</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Ez egy kísérleti szoftver.</translation> </message> @@ -2210,10 +2477,6 @@ <translation>Túl nagy tranzakció</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> - <message> <source>Username for JSON-RPC connections</source> <translation>Felhasználói név JSON-RPC csatlakozásokhoz </translation> @@ -2232,20 +2495,6 @@ <translation>Parancs, amit akkor hajt végre, amikor a legjobb blokk megváltozik (%s a cmd-ban lecserélődik a blokk hash-re)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>A Tárca frissítése a legfrissebb formátumra</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> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>OpenSSL (https) használata JSON-RPC csatalkozásokhoz -</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 6855d11c80..1b626fbf23 100644 --- a/src/qt/locale/bitcoin_id_ID.ts +++ b/src/qt/locale/bitcoin_id_ID.ts @@ -1,7 +1,11 @@ -<TS language="id_ID" version="2.0"> +<TS language="id_ID" version="2.1"> <context> <name>AddressBookPage</name> <message> + <source>Right-click to edit address or label</source> + <translation>Klik-kanan untuk mengubah alamat atau label</translation> + </message> + <message> <source>Create a new address</source> <translation>Buat alamat baru</translation> </message> @@ -197,6 +201,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -247,6 +254,10 @@ <translation>&Pilihan...</translation> </message> <message> + <source>&Encrypt Wallet...</source> + <translation>&Enkripsi Dompet...</translation> + </message> + <message> <source>&Backup Wallet...</source> <translation>&Cadangkan Dompet...</translation> </message> @@ -451,6 +462,36 @@ <translation>Menyusul...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>Tanggal: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Jumlah: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Tipe: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Label: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Alamat: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>Transaksi terkirim</translation> </message> @@ -477,6 +518,10 @@ <context> <name>CoinControlDialog</name> <message> + <source>Coin Selection</source> + <translation>Pemilihan Koin</translation> + </message> + <message> <source>Quantity:</source> <translation>Kuantitas:</translation> </message> @@ -754,6 +799,10 @@ <translation>Mengenai Bitcoin Core</translation> </message> <message> + <source>Command-line options</source> + <translation>pilihan Perintah-baris</translation> + </message> + <message> <source>Usage:</source> <translation>Penggunaan:</translation> </message> @@ -761,7 +810,7 @@ <source>command-line options</source> <translation>pilihan perintah-baris</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -895,6 +944,18 @@ <translation>Port proxy (cth. 9050)</translation> </message> <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> <source>&Window</source> <translation>&Jendela</translation> </message> @@ -955,6 +1016,10 @@ <translation>Restart klien diperlukan untuk mengaktifkan perubahan.</translation> </message> <message> + <source>Client will be shut down. Do you want to proceed?</source> + <translation>Klien akan dimatikan, apakah anda hendak melanjutkan?</translation> + </message> + <message> <source>This change would require a client restart.</source> <translation>Perubahan ini akan memerlukan restart klien</translation> </message> @@ -998,6 +1063,10 @@ <translation>Saldo ditambang yang masih terlalu muda</translation> </message> <message> + <source>Balances</source> + <translation>Saldo:</translation> + </message> + <message> <source>Total:</source> <translation>Jumlah:</translation> </message> @@ -1017,6 +1086,10 @@ <translation>Alamat pembayaran salah %1</translation> </message> <message> + <source>Payment request rejected</source> + <translation>Permintaan pembayaran ditolak</translation> + </message> + <message> <source>Requested payment amount of %1 is too small (considered dust).</source> <translation>Nilai pembayaran %1 yang diminta oleh Anda terlalu sedikit (dianggap debu).</translation> </message> @@ -1025,6 +1098,10 @@ <translation>Gagalan permintaan pembayaran</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Permintaan pembayaran telah kadaluarsa</translation> + </message> + <message> <source>Refund from %1</source> <translation>Pembayaran kembali dari %1</translation> </message> @@ -1047,6 +1124,10 @@ </context> <context> <name>PeerTableModel</name> + <message> + <source>User Agent</source> + <translation>Agen Pengguna</translation> + </message> </context> <context> <name>QObject</name> @@ -1055,6 +1136,10 @@ <translation>Nilai</translation> </message> <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>Masukkan alamat Bitcoin (contoh %1)</translation> + </message> + <message> <source>%1 h</source> <translation>%1 Jam</translation> </message> @@ -1141,6 +1226,24 @@ <translation>Jumlah blok terkini</translation> </message> <message> + <source>Sent</source> + <translation>Terkirim</translation> + </message> + <message> + <source>Version</source> + <translation>Versi</translation> + </message> + <message> + <source>User Agent</source> + <translation>Agen Pengguna + +</translation> + </message> + <message> + <source>Services</source> + <translation>Layanan</translation> + </message> + <message> <source>Last block time</source> <translation>Waktu blok terakhir</translation> </message> @@ -1185,6 +1288,26 @@ <translation>Bersihkan konsol</translation> </message> <message> + <source>1 &hour</source> + <translation>1 &jam</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &hari</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &minggu</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &tahun</translation> + </message> + <message> + <source>Welcome to the Bitcoin Core RPC console.</source> + <translation>Selamat datang di konsol RPC Bitcoin.</translation> + </message> + <message> <source>Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.</source> <translation>Gunakan panah keatas dan kebawah untuk menampilkan sejarah, dan <b>Ctrl-L</b> untuk bersihkan layar.</translation> </message> @@ -1208,7 +1331,19 @@ <source>%1 GB</source> <translation>%1 GB</translation> </message> - </context> + <message> + <source>Yes</source> + <translation>Ya</translation> + </message> + <message> + <source>No</source> + <translation>Tidak</translation> + </message> + <message> + <source>Unknown</source> + <translation>Tidak diketahui</translation> + </message> +</context> <context> <name>ReceiveCoinsDialog</name> <message> @@ -1429,6 +1564,26 @@ <translation>Alamat uang kembali yang kustom</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Biaya Transaksi:</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Disarankan</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Waktu konfirmasi:</translation> + </message> + <message> + <source>normal</source> + <translation>normal</translation> + </message> + <message> + <source>fast</source> + <translation>cepat</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Kirim ke beberapa penerima sekaligus</translation> </message> @@ -1441,6 +1596,10 @@ <translation>Hapus informasi dari form.</translation> </message> <message> + <source>Clear &All</source> + <translation>Hapus &Semua</translation> + </message> + <message> <source>Balance:</source> <translation>Saldo:</translation> </message> @@ -1489,8 +1648,8 @@ <translation>Salin uang kembali</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Jumlah Nilai %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Jumlah Total %1</translation> </message> <message> <source>or</source> @@ -1517,6 +1676,14 @@ <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> <message> + <source>A fee higher than %1 is considered an absurdly high fee.</source> + <translation>Biaya yang lebih tinggi dari %1 dianggap biaya tak masuk akal.</translation> + </message> + <message> + <source>Payment request expired.</source> + <translation>Permintaan pembayaran telah kadaluarsa</translation> + </message> + <message> <source>Warning: Invalid Bitcoin address</source> <translation>Awas: Alamat Bitcoin tidak sah</translation> </message> @@ -1654,6 +1821,10 @@ <translation>Hapus semua bidang penanda pesan</translation> </message> <message> + <source>Clear &All</source> + <translation>Hapus &Semua</translation> + </message> + <message> <source>&Verify Message</source> <translation>&Verifikasi Pesan</translation> </message> @@ -2191,10 +2362,6 @@ <translation>Berjalan dibelakang sebagai daemin dan menerima perintah</translation> </message> <message> - <source>Use the test network</source> - <translation>Gunakan jaringan uji</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Terima hubungan dari luar (standar: 1 kalau -proxy atau -connect tidak dipilih)</translation> </message> @@ -2207,10 +2374,6 @@ <translation>Tidak bisa mengikat dengan %s di computer ini. Kemungkinan Bitcoin Core sudah mulai.</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> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Peringatan: Jaringan tidak semua bersetuju! Beberapa penambang dapat persoalan.</translation> </message> @@ -2219,18 +2382,6 @@ <translation>Peringatan: Kami tidak bersetujuh dengan peer-peer kami! Kemungkinan Anda harus upgrade, atau node-node lain yang harus diupgrade.</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>Awas: wallet.dat tidak bisa dibaca! Berhasil periksakan kunci-kunci dalam arsipnya, tetapi ada kemungkinan informasi tentang transaksi atau isi-isi buku alamat salah atau terhilang.</translation> - </message> - <message> - <source>(default: 1)</source> - <translation>(pengaturan awal: 1)</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> - <message> <source>Block creation options:</source> <translation>Pilihan pembuatan blok:</translation> </message> @@ -2319,18 +2470,26 @@ <translation>Harus membangun ulang database menggunakan -reindex supaya mengubah -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Impor blok dari eksternal berkas blk000???.dat</translation> - </message> - <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Tidak bisa mengunci data directory %s. Kemungkinan Bitcoin Core sudah mulai.</translation> </message> <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Tidak dapat menyelesaikan alamat -whitebind: '%s'</translation> + </message> + <message> + <source>Connect through SOCKS5 proxy</source> + <translation>Hubungkan melalui proxy SOCKS5</translation> + </message> + <message> <source>Information</source> <translation>Informasi</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Nilai salah untuk -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Nilai yang salah untuk -minrelaytxfee=<amount>: '%s'</translation> </message> @@ -2347,14 +2506,6 @@ <translation>Kirim info jejak/debug ke konsol bukan berkas debug.log</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Atur bahasa, sebagai contoh "id_ID" (standar: system locale)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Tampilkan layar pembuka saat nyala (standar: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Mengecilkan berkas debug.log saat klien berjalan (Standar: 1 jika tidak -debug)</translation> </message> @@ -2363,10 +2514,6 @@ <translation>Tandatangani transaksi tergagal</translation> </message> <message> - <source>Start minimized</source> - <translation>Memulai terminimalisi</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Nilai transaksi terlalu kecil</translation> </message> @@ -2403,18 +2550,6 @@ <translation>Menjalankan perintah ketika perubahan blok terbaik (%s dalam cmd digantikan oleh hash blok)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Perbarui dompet ke format terbaru</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Gunakan OpenSSL (https) untuk hubungan JSON-RPC</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 d3cc576979..d510b1063b 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -1,4 +1,4 @@ -<TS language="it" version="2.0"> +<TS language="it" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/Netmask</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Bannato fino a</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -871,6 +882,34 @@ <source>command-line options</source> <translation>opzioni della riga di comando</translation> </message> + <message> + <source>UI Options:</source> + <translation>Opzioni interfaccia:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Seleziona la directory dei dati all'avvio (default: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Imposta la lingua, ad esempio "it_IT" (default: locale di sistema)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Avvia ridotto a icona</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Imposta un certificato SSL root per le richieste di pagamento (default: -system-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Mostra schermata iniziale all'avvio (default: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Reset di tutte le modifiche alle impostazioni eseguite da interfaccia grafica</translation> + </message> </context> <context> <name>Intro</name> @@ -910,7 +949,11 @@ <source>Error</source> <translation>Errore</translation> </message> - </context> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(di %nGB richiesti)</numerusform><numerusform>(%n GB richiesti)</numerusform></translation> + </message> +</context> <context> <name>OpenURIDialog</name> <message> @@ -1062,6 +1105,34 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Porta del proxy (ad es. 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Utilizzata per connettersi attraverso:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Mostra se la proxy SOCKS5 fornita viene utilizzata per raggiungere i peers attraverso questo tipo di rete.</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Connette alla rete Bitcoin attraverso un proxy SOCKS5 separato per Tor.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Usa un proxy SOCKS5 separato per connettersi ai peers attraverso Tor:</translation> + </message> + <message> <source>&Window</source> <translation>&Finestra</translation> </message> @@ -1280,10 +1351,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>La richiesta di pagamento %1 (%2 byte) supera la dimensione massima di %3 byte.</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Protezione DoS per la richiesta di pagamento</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Errore di comunicazione con %1: %2</translation> </message> @@ -1436,6 +1503,18 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Numero attuale di blocchi</translation> </message> <message> + <source>Memory Pool</source> + <translation>Memory Pool</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>Numero attuale di transazioni</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Utilizzo memoria</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>Apre il file log di debug di Bitcoin Core dalla cartella dati attuale. Questa azione può richiedere alcuni secondi per file log di grandi dimensioni.</translation> </message> @@ -1452,10 +1531,18 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>&Peer</translation> </message> <message> + <source>Banned peers</source> + <translation>Peers bannati</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>Whitelisted</source> + <translation>Whitelisted/sicuri</translation> + </message> + <message> <source>Direction</source> <translation>Direzione</translation> </message> @@ -1464,20 +1551,24 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Versione</translation> </message> <message> - <source>User Agent</source> - <translation>User Agent</translation> + <source>Starting Block</source> + <translation>Blocco di partenza</translation> </message> <message> - <source>Services</source> - <translation>Servizi</translation> + <source>Synced Headers</source> + <translation>Headers sincronizzati</translation> </message> <message> - <source>Starting Height</source> - <translation>Nr. Blocco Iniziale</translation> + <source>Synced Blocks</source> + <translation>Blocchi sincronizzati</translation> </message> <message> - <source>Sync Height</source> - <translation>Nr. Blocco Sincronizzato</translation> + <source>User Agent</source> + <translation>User Agent</translation> + </message> + <message> + <source>Services</source> + <translation>Servizi</translation> </message> <message> <source>Ban Score</source> @@ -1496,16 +1587,16 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Ultima Ricezione</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Byte Inviati</translation> + <source>Ping Time</source> + <translation>Tempo di Ping</translation> </message> <message> - <source>Bytes Received</source> - <translation>Byte Ricevuti</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>La durata di un ping attualmente in corso.</translation> </message> <message> - <source>Ping Time</source> - <translation>Tempo di Ping</translation> + <source>Ping Wait</source> + <translation>Attesa ping</translation> </message> <message> <source>Time Offset</source> @@ -1556,6 +1647,34 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Cancella console</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>&Nodo Disconnesso</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Nodo Bannato perché</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &ora</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &giorno</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &settimana</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &anno</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>&Elimina Ban Nodo</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Benvenuto nella console RPC di Bitcoin Core.</translation> </message> @@ -1584,6 +1703,10 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(id nodo: %1)</translation> + </message> + <message> <source>via %1</source> <translation>via %1</translation> </message> @@ -1600,12 +1723,16 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>In uscita</translation> </message> <message> - <source>Unknown</source> - <translation>Sconosciuto</translation> + <source>Yes</source> + <translation>Si</translation> </message> <message> - <source>Fetching...</source> - <translation>Recuperando...</translation> + <source>No</source> + <translation>No</translation> + </message> + <message> + <source>Unknown</source> + <translation>Sconosciuto</translation> </message> </context> <context> @@ -1972,8 +2099,8 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Copia resto</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Importo Totale %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Ammontare Totale %1</translation> </message> <message> <source>or</source> @@ -2008,8 +2135,12 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Richiesta di pagamento scaduta.</translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Paga solamente la commissione minima di %1</translation> + <source>Pay only the required fee of %1</source> + <translation>Paga solamente la commissione richiesta di %1</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Inizio delle conferme stimato entro %n blocco.</numerusform><numerusform>Inizio delle conferme stimato entro %n blocchi.</numerusform></translation> </message> <message> <source>The recipient address is not valid. Please recheck.</source> @@ -2643,6 +2774,10 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Copia l'ID transazione</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>Copia la transazione raw</translation> + </message> + <message> <source>Edit label</source> <translation>Modifica l'etichetta</translation> </message> @@ -2790,12 +2925,52 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Accetta comandi da riga di comando e JSON-RPC</translation> </message> <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>Se <category> non è specificato oppure se <category> = 1, mostra tutte le informazioni di debug.</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Totale massimo di commissioni (in %s) da usare in una singola transazione del wallet; valori troppo bassi possono abortire grandi transazioni (default: %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Per favore controllate che la data del computer e l'ora siano corrette. Se il vostro orologio è sbagliato Bitcoin non funzionerà correttamente.</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>La modalità prune è configurata al di sotto del minimo di %d MB. Si prega di utilizzare un valore più elevato.</translation> + </message> + <message> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation>Prune: l'ultima sincronizzazione del wallet risulta essere oltre la riduzione dei dati. È necessario eseguire un -reindex (scaricare nuovamente la blockchain in caso di nodo pruned)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Riduce i requisiti di spazio di archiviazione attraverso la rimozione dei vecchi blocchi (pruning). Questa modalità è incompatibile con l'opzione -txindex e -rescan. Attenzione: ripristinando questa opzione l'intera blockchain dovrà essere riscaricata. (default: 0 = disabilita il pruning, >%u = dimensione desiderata in MiB per i file dei blocchi)</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>Non è possibile un Rescan in modalità pruned. Sarà necessario utilizzare -reindex che farà scaricare nuovamente tutta la blockchain.</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Errore: si è presentato un errore interno fatale, consulta il file debug.log per maggiori dettagli</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Commissione (in %s/kB) da aggiungere alle transazioni inviate (default: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Pruning del blockstore...</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>Esegui in background come demone ed accetta i comandi</translation> </message> <message> - <source>Use the test network</source> - <translation>Utilizza la rete di prova</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>Impossibile avviare il server HTTP. Dettagli nel log di debug.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2818,18 +2993,14 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Esegue un comando quando lo stato di una transazione del portamonete cambia (%s in cmd è sostituito da TxID)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Commissioni massime totali da includere in una singola transazione dal portamonete. Un'impostazione troppo bassa potrebbe provocare l'annullamento di transazioni di grosse dimensioni (predefinito: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Riduce i requisiti di spazio di archiviazione attraverso la rimozione dei vecchi blocchi (pruning). Questa modalità disabilita le funzionalità di portamonete ed è incompatibile con l'opzione -txindex. Attenzione: il ripristinando questa opzione l'intera blockchain dovrà essere riscaricata. (predefinito: 0 = disabilita il pruning, >%u = dimensione desiderata in MiB per i file dei blocchi)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <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>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>Il database dei blocchi contiene un blocco che sembra provenire dal futuro. Questo può essere dovuto alla data e ora del tuo computer impostate in modo scorretto. Ricostruisci il database dei blocchi se sei certo che la data e l'ora sul tuo computer siano corrette</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> @@ -2838,6 +3009,10 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Impossibile associarsi a %s su questo computer. Probabilmente Bitcoin Core è già in esecuzione.</translation> </message> <message> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>Utilizza UPnP per mappare la porta in ascolto (default: 1 quando in ascolto e -proxy non è specificato)</translation> + </message> + <message> <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> <translation>ATTENZIONE, il numero di blocchi generati è insolitamente elevato: %d blocchi ricevuti nelle ultime %d ore (%d previsti)</translation> </message> @@ -2846,10 +3021,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>ATTENZIONE, si consiglia di verificare la connessione di rete: %d blocchi ricevuti nelle ultime %d ore (%d previsti)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Attenzione: -paytxfee è impostato su un valore molto elevato. Questa è la commissione che si paga quando si invia una transazione.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Attenzione: La rete non sembra trovarsi in pieno consenso! Alcuni minatori sembrano riscontrare problemi.</translation> </message> @@ -2858,10 +3029,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Attenzione: Sembra che non vi sia pieno consenso con i nostri peer! Un aggiornamento da parte tua o degli altri nodi potrebbe essere necessario.</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>Attenzione: errore di lettura di wallet.dat! Tutte le chiavi sono state lette correttamente, ma i dati delle transazioni o della rubrica potrebbero essere mancanti o non corretti.</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>Attenzione: wallet.dat corrotto, dati recuperati! Il wallet.dat originale è stato salvato come wallet.{timestamp}.bak in %s. Se i dati relativi a saldo o transazioni non dovessero risultare corretti si consiglia di procedere al ripristino da un backup.</translation> </message> @@ -2870,18 +3037,14 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Inserisce in whitelist i peer che si connettono da un dato indirizzo IP o netmask. Può essere specificato più volte.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(predefinito: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool deve essere almeno %d MB</translation> </message> <message> <source><category> can be:</source> <translation>Valori possibili per <category>:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Tenta di recuperare le chiavi private da un wallet.dat corrotto</translation> - </message> - <message> <source>Block creation options:</source> <translation>Opzioni creazione blocco:</translation> </message> @@ -2910,6 +3073,22 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Vuoi ricostruire ora il database dei blocchi?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation>Abilita pubblicazione hash blocco in <address></translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>Abilità pubblicazione hash transazione in <address></translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>Abilita pubblicazione blocchi raw in <address></translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation>Abilita pubblicazione transazione raw in <address></translation> + </message> + <message> <source>Error initializing block database</source> <translation>Errore durante l'inizializzazione del database dei blocchi</translation> </message> @@ -2926,10 +3105,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Errore durante l'apertura del database blocchi</translation> </message> <message> - <source>Error: A fatal internal error occured, see debug.log for details</source> - <translation>Errore: si è verificato un errore interno 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> @@ -2938,10 +3113,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Nessuna porta disponibile per l'ascolto. Usa -listen=0 se vuoi procedere comunque.</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> - <message> <source>Importing...</source> <translation>Importazione...</translation> </message> @@ -2954,6 +3125,10 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Indirizzo -onion non valido: '%s'</translation> </message> <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>Mantieni la memory pool delle transazioni al di sotto di <n> megabytes (default: %u)</translation> + </message> + <message> <source>Not enough file descriptors available.</source> <translation>Non ci sono abbastanza descrittori di file disponibili.</translation> </message> @@ -2982,10 +3157,26 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Specifica il file del portamonete (all'interno della cartella dati)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Ignorata opzione -benchmark non supportata, utilizzare -debug=bench.</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Argomento -debugnet ignorato in quanto non supportato, usare -debug=net.</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>Rilevato argomento -tor non supportato, utilizzare -onion.</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Usa UPnP per mappare la porta di ascolto (predefinito: %u)</translation> </message> <message> + <source>User Agent comment (%s) contains unsafe characters.</source> + <translation>Il commento del User Agent (%s) contiene caratteri non sicuri.</translation> + </message> + <message> <source>Verifying blocks...</source> <translation>Verifica blocchi...</translation> </message> @@ -3010,10 +3201,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>È necessario ricostruire il database usando -reindex per cambiare -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importa blocchi da un file blk000??.dat esterno</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>Permette connessioni JSON-RPC dall'origine specificata. I valori validi per <ip> sono un singolo IP (ad es. 1.2.3.4), una network/netmask (ad es. 1.2.3.4/255.255.255.0) oppure una network/CIDR (ad es. 1.2.3.4/24). Questa opzione può essere specificata più volte.</translation> </message> @@ -3042,16 +3229,12 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Errore: attesa per connessioni in arrivo fallita (errore riportato %s)</translation> </message> <message> - <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> - <translation>Errore: individuato argomento -socks non supportato. Non è più possibile impostare la versione SOCKS, solamente i proxy SOCKS5 sono supportati.</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 in caso di ricezione di un allarme pertinente o se si rileva un fork molto lungo (%s in cmd è sostituito dal messaggio)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Le commissioni (in BTC/kB) inferiori a questo valore sono considerate pari a zero relativamente alla trasmissione (predefinito: %s)</translation> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>Le commissioni (in %s/kB) inferiori a questo valore sono considerate pari a zero per trasmissione, mining e creazione della transazione (default: %s)</translation> </message> <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> @@ -3066,10 +3249,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Dimensione massima dei dati in transazioni di trasporto dati che saranno trasmesse ed incluse nei blocchi (predefinito: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>La modalità prune è configurata al di sotto del minimo di %d MB. Si prega di utilizzare un valore più elevato.</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Ottiene gli indirizzi dei peer attraverso interrogazioni DNS, in caso di scarsa disponibilità (predefinito: 1 a meno che -connect non sia specificato)</translation> </message> @@ -3094,37 +3273,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation> <translation>Questo prodotto include software sviluppato dal progetto OpenSSL per l'uso del Toolkit OpenSSL <https://www.openssl.org/>, software crittografico scritto da Eric Young e software UPnP scritto da Thomas Bernard.</translation> </message> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>Per utilizzare bitcoind o l'opzione -server in Bitcoin Core è necessario specificare una rpcpassword nel file di configurazione: -%s -Si raccomanda di utilizzare la seguente password casuale: -rpcuser=bitcoinrpc -rpcpassword=%s -(non è necessario ricordare questa password) -Il nome utente e la password NON DEVONO corrispondere. -Se il file non esiste si raccomanda di crearlo con permessi di lettura per il solo proprietario. -Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche di eventuali problemi, ad es. alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Attenzione: -maxtxfee è impostato su un valore molto elevato. Tali commissioni potrebbero essere pagate anche in una singola transazione.</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>Attenzione: Si prega di verificare che data ed ora del computer siano corrette! Una configurazione errata dell'orologio di sistema potrebbe impedire a Bitcoin Core di funzionare regolarmente.</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>I peer inclusi in whitelist non possono subire ban per DoS e le loro transazioni saranno sempre trasmesse, anche nel caso in cui si trovino già nel mempool. Ciò è utile ad es. per i gateway</translation> </message> @@ -3145,16 +3293,20 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Attivazione della blockchain migliore...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>Impossibile operare con un portamonete in modalità prune.</translation> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>Trasmetti sempre le transazioni ricevute da peers whitelisted (default: %d)</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>Impossibile risolvere indirizzo -whitebind: '%s'</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Prova a recuperare le chiavi private da un wallet corrotto all'avvio</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Seleziona la cartella dati all'avvio (predefinito: 0)</translation> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Crea automaticamente il servizio Tor (default: %d)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Impossibile risolvere indirizzo -whitebind: '%s'</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3165,10 +3317,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Copyright (C) 2009-%i Gli sviluppatori di Bitcoin Core</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Non è stato possibile riconoscere il valore %s di -rpcbind come indirizzo di rete</translation> - </message> - <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Errore durante il caricamento del file wallet.dat: il portamonete richiede una versione di Bitcoin Core più recente</translation> </message> @@ -3177,12 +3325,8 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Errore durante lalettura del database. Arresto in corso.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Errore: Rilevato argomento -tor non supportato, utilizzare -onion.</translation> - </message> - <message> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation>Commissione (in BTC/kB) da aggiungere alle transazioni che invii (predefinito: %s)</translation> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Importa blocchi da un file blk000??.dat esterno all'avvio</translation> </message> <message> <source>Information</source> @@ -3225,18 +3369,10 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Opzioni trasmissione nodo:</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> - <message> <source>RPC server options:</source> <translation>Opzioni server RPC:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>Supporto RPC per le connessioni HTTP persistenti (predefinito: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Ricostruzione dell'indice della block chain dai file blk000??.dat correnti all'avvio</translation> </message> @@ -3245,30 +3381,26 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Ricevi e visualizza gli alerts della rete P2P (default: %u)</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Invia le informazioni di trace/debug alla console invece che al file debug.log</translation> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> + <translation>Riduzione -maxconnections da %d a %d a causa di limitazioni di sistema.</translation> </message> <message> - <source>Send transactions as zero-fee transactions if possible (default: %u)</source> - <translation>Invia transazioni a zero commissioni se possibile (predefinito: %u)</translation> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Ripete la scansione della block chain per individuare le transazioni che mancano dal wallet all'avvio</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Imposta i certificati radice SSL per le richieste di pagamento (predefinito: -system-)</translation> + <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 language, for example "de_DE" (default: system locale)</source> - <translation>Imposta lingua, ad esempio "it_IT" (predefinito: lingua di sistema)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Invia transazioni a zero commissioni se possibile (predefinito: %u)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Mostra tutte le opzioni di debug (utilizzo: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostra finestra di presentazione all'avvio (predefinito: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Riduce il file debug.log all'avvio del client (predefinito: 1 se -debug non è impostato)</translation> </message> @@ -3277,10 +3409,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Firma transazione fallita</translation> </message> <message> - <source>Start minimized</source> - <translation>Avvia ridotto a icona</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>L'importo della transazione è troppo basso per pagare la commissione</translation> </message> @@ -3289,6 +3417,14 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Questo è un software sperimentale.</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>Password porta controllo Tor (default: empty)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>Porta di controllo Tor da usare se in ascolto su onion (default: %s)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Importo transazione troppo piccolo</translation> </message> @@ -3305,16 +3441,12 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Transazione troppo grande</translation> </message> <message> - <source>UI Options:</source> - <translation>Opzioni Interfaccia Utente:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Impossibile associarsi a %s su questo computer (l'associazione ha restituito l'errore %s)</translation> </message> <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 quando in ascolto)</translation> + <source>Upgrade wallet to latest format on startup</source> + <translation>Aggiorna il wallet all'ultimo formato all'avvio</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3329,20 +3461,16 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Attenzione</translation> </message> <message> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation>Attenzione: Argomento -benchmark ignorato in quanto non supportato, usare -debug=bench.</translation> - </message> - <message> - <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> - <translation>Attenzione: Argomento -debugnet ignorato in quanto non supportato, usare -debug=net.</translation> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>Imposta se operare in modalità solo blocchi (default: %u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> <translation>Eliminazione dal portamonete di tutte le transazioni...</translation> </message> <message> - <source>on startup</source> - <translation>all'avvio</translation> + <source>ZeroMQ notification options:</source> + <translation>Opzioni di notifica ZeroMQ</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3357,18 +3485,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Esegue un comando quando il miglior blocco cambia (%s nel cmd è sostituito dall'hash del blocco)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Aggiorna il wallet all'ultimo formato</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Ripete la scansione della block chain per individuare le transazioni che mancano dal portamonete</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Utilizza OpenSSL (https) per le connessioni JSON-RPC</translation> - </message> - <message> <source>This help message</source> <translation>Questo messaggio di aiuto</translation> </message> @@ -3389,6 +3505,26 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>(1 = mantiene metadati tx, ad es. proprietario account ed informazioni di richiesta di pagamento, 2 = scarta metadati tx)</translation> </message> <message> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>-maxtxfee è impostato molto alto! Commissioni così alte possono venir pagate anche su una singola transazione.</translation> + </message> + <message> + <source>-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> + <translation>-paytxfee è impostato su un valore molto elevato. Questa è la commissione che si paga quando si invia una transazione.</translation> + </message> + <message> + <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>Non mantenere le transazioni nella mempool più a lungo di <n> ore (default: %u)</translation> + </message> + <message> + <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> + <translation>Errore di lettura di wallet.dat! Tutte le chiavi sono state lette correttamente, ma i dati delle transazioni o della rubrica potrebbero essere mancanti o non corretti.</translation> + </message> + <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>Le commissioni (in %s/kB) inferiori a questo valore sono considerate pari a zero per la creazione della transazione (default: %s)</translation> + </message> + <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Determina quanto sarà approfondita la verifica da parte di -checkblocks (0-4, predefinito: %u)</translation> </message> @@ -3405,16 +3541,32 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Emette informazioni di debug (predefinito: %u, fornire <category> è opzionale)</translation> </message> <message> + <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> + <translation>Supporta filtraggio di blocchi e transazioni con filtri bloom (default: %u)</translation> + </message> + <message> + <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> + <translation>La lunghezza totale della stringa di network version (%i) eccede la lunghezza massima (%i). Ridurre il numero o la dimensione di uacomments.</translation> + </message> + <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>Cerca di mantenere il traffico in uscita al di sotto della soglia scelta (in MiB ogni 24h), 0 = nessun limite (default: %d)</translation> + </message> + <message> + <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Argomento -socks non supportato. Non è più possibile impostare la versione SOCKS, solamente i proxy SOCKS5 sono supportati.</translation> + </message> + <message> <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> <translation>Usa un proxy SOCKS5 a parte per raggiungere i peer attraverso gli hidden services di Tor (predefinito: %s)</translation> </message> <message> - <source>(default: %s)</source> - <translation>(predefinito: %s)</translation> + <source>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source> + <translation>Username e hash password per connessioni JSON-RPC. Il campo <userpw> utilizza il formato: <USERNAME>:<SALT>$<HASH>. Uno script python standard è incluso in share/rpcuser. Questa opzione può essere specificata più volte</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Cifrari accettabili (predefinito: %s)</translation> + <source>(default: %s)</source> + <translation>(predefinito: %s)</translation> </message> <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> @@ -3477,14 +3629,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d <translation>Trasmette transazioni non-P2SH multisig (predefinito: %u)</translation> </message> <message> - <source>Server certificate file (default: %s)</source> - <translation>File del certificato del server (predefinito: %s)</translation> - </message> - <message> - <source>Server private key (default: %s)</source> - <translation>Chiave privata del server (predefinito: %s)</translation> - </message> - <message> <source>Set key pool size to <n> (default: %u)</source> <translation>Imposta la dimensione del pool di chiavi a <n> (predefinito: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index e2c22f7f6d..4344fd0436 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -1,4 +1,4 @@ -<TS language="ja" version="2.0"> +<TS language="ja" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IPアドレス/ネットマスク</translation> + </message> + <message> + <source>Banned Until</source> + <translation>以下の時間までbanする:</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -340,11 +351,11 @@ </message> <message> <source>&Send</source> - <translation>送る (&S)</translation> + <translation>送金 (&S)</translation> </message> <message> <source>&Receive</source> - <translation>受信 (&R)</translation> + <translation>入金 (&R)</translation> </message> <message> <source>Show information about Bitcoin Core</source> @@ -787,7 +798,7 @@ </message> <message> <source>New receiving address</source> - <translation>新しい受信アドレス</translation> + <translation>新しい入金アドレス</translation> </message> <message> <source>New sending address</source> @@ -795,7 +806,7 @@ </message> <message> <source>Edit receiving address</source> - <translation>受信アドレスを編集</translation> + <translation>入金アドレスを編集</translation> </message> <message> <source>Edit sending address</source> @@ -871,6 +882,34 @@ <source>command-line options</source> <translation>コマンドライン オプション</translation> </message> + <message> + <source>UI Options:</source> + <translation>UIオプション:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>起動時にデータ ディレクトリを選ぶ (初期値: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>言語設定 例: "de_DE" (初期値: システムの言語)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>最小化された状態で起動する</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>支払いリクエスト用にSSLルート証明書を設定する (デフォルト:-system-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>起動時にスプラッシュ画面を表示する (初期値: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>GUI 経由で行われた設定の変更を全てリセット</translation> + </message> </context> <context> <name>Intro</name> @@ -1069,6 +1108,34 @@ <translation>プロキシのポート番号 (例 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>ピアへ到達するために使われた方法:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>このネットワークタイプ経由で、与えられたデフォルトのSOCKS5プロキシを使用してピアに到達した場合に表示する。</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Tor秘匿サービスを利用するため、独立なSOCKS5プロキシ経由でBitcoinネットワークに接続する</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Tor秘匿サービス経由でピアに到達するため、独立なSOCKS5プロキシを利用する:</translation> + </message> + <message> <source>&Window</source> <translation>ウインドウ (&W)</translation> </message> @@ -1287,10 +1354,6 @@ <translation>支払リクエスト %1 は大きすぎます(%2バイトですが、%3バイトまでが許されています)。</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>支払リクエストDoS保護</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>%1: %2とコミュニケーション・エラーです</translation> </message> @@ -1443,6 +1506,18 @@ <translation>現在のブロック数</translation> </message> <message> + <source>Memory Pool</source> + <translation>メモリ・プール</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>現在のトランザクション数</translation> + </message> + <message> + <source>Memory usage</source> + <translation>メモリ使用量</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>現在のデータディレクトリからBitcoin Coreのデバッグ用ログファイルを開きます。ログファイルが巨大な場合、数秒かかることがあります。</translation> </message> @@ -1459,10 +1534,18 @@ <translation>ピア (&P)</translation> </message> <message> + <source>Banned peers</source> + <translation>Banされたピア</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>詳しい情報を見たいピアを選択してください。</translation> </message> <message> + <source>Whitelisted</source> + <translation>ホワイトリスト</translation> + </message> + <message> <source>Direction</source> <translation>方向</translation> </message> @@ -1471,20 +1554,24 @@ <translation>バージョン</translation> </message> <message> - <source>User Agent</source> - <translation>ユーザエージェント</translation> + <source>Starting Block</source> + <translation>開始ブロック</translation> </message> <message> - <source>Services</source> - <translation>サービス</translation> + <source>Synced Headers</source> + <translation>同期済みヘッダ</translation> </message> <message> - <source>Starting Height</source> - <translation>開始時のブロック高</translation> + <source>Synced Blocks</source> + <translation>同期済みブロック</translation> + </message> + <message> + <source>User Agent</source> + <translation>ユーザエージェント</translation> </message> <message> - <source>Sync Height</source> - <translation>同期済みブロック高</translation> + <source>Services</source> + <translation>サービス</translation> </message> <message> <source>Ban Score</source> @@ -1503,16 +1590,16 @@ <translation>最終受信</translation> </message> <message> - <source>Bytes Sent</source> - <translation>送信済バイト数</translation> + <source>Ping Time</source> + <translation>Ping時間</translation> </message> <message> - <source>Bytes Received</source> - <translation>受信済バイト数</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>現在実行中のpingにかかっている時間。</translation> </message> <message> - <source>Ping Time</source> - <translation>Ping時間</translation> + <source>Ping Wait</source> + <translation>Ping待ち</translation> </message> <message> <source>Time Offset</source> @@ -1563,6 +1650,34 @@ <translation>コンソールをクリア</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>ノードを切断する (&D)</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>ノードをbanする:</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1時間 (&H)</translation> + </message> + <message> + <source>1 &day</source> + <translation>1日 (&D)</translation> + </message> + <message> + <source>1 &week</source> + <translation>1週間 (&W)</translation> + </message> + <message> + <source>1 &year</source> + <translation>1年 (&Y)</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>ノードのbanを解除する (&U)</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Bitcoin CoreのRPCコンソールへようこそ。</translation> </message> @@ -1591,6 +1706,10 @@ <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(ノードID: %1)</translation> + </message> + <message> <source>via %1</source> <translation>%1経由</translation> </message> @@ -1607,12 +1726,16 @@ <translation>外向き</translation> </message> <message> - <source>Unknown</source> - <translation>未知</translation> + <source>Yes</source> + <translation>はい</translation> </message> <message> - <source>Fetching...</source> - <translation>取得中……</translation> + <source>No</source> + <translation>いいえ</translation> + </message> + <message> + <source>Unknown</source> + <translation>未知</translation> </message> </context> <context> @@ -1940,7 +2063,7 @@ </message> <message> <source>S&end</source> - <translation>送る (&e)</translation> + <translation>送金 (&E)</translation> </message> <message> <source>Confirm send coins</source> @@ -1979,8 +2102,8 @@ <translation>釣り銭をコピー</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>総送金額 %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>合計: %1</translation> </message> <message> <source>or</source> @@ -2014,15 +2137,15 @@ <source>Payment request expired.</source> <translation>支払いリクエストの期限が切れました。</translation> </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>要求手数料 %1 のみを支払う</translation> + </message> <message numerus="yes"> <source>Estimated to begin confirmation within %n block(s).</source> <translation><numerusform>%n ブロック以内に検証が開始されると予想されます。</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>最小手数料 %1 のみを支払う</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>受取アドレスが不正です。再チェックしてください。</translation> </message> @@ -2528,7 +2651,7 @@ </message> <message> <source>Received with</source> - <translation>受信元</translation> + <translation>受け取り</translation> </message> <message> <source>Received from</source> @@ -2654,6 +2777,10 @@ <translation>取引 ID をコピー</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>生トランザクションをコピー</translation> + </message> + <message> <source>Edit label</source> <translation>ラベルの編集</translation> </message> @@ -2801,12 +2928,52 @@ <translation>コマンドラインと JSON-RPC コマンドを許可</translation> </message> <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation><category> が与えられなかった場合や <category> = 1 の場合には、すべてのデバッグ情報が出力されます。</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>ひとつのウォレットトランザクションで使用する合計手数料 (%s 単位) の最大値。低すぎる値を指定すると巨大なトランザクションの作成ができなくなります (規定値: %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>あなたのPCの日付と時刻が正しいことを確認して下さい! もしあなたの時計が正しくなければBitcoin Coreが正確に動作しません。</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>剪定が最小値の %d MiB以下に設定されています。もっと大きな値を使用してください。</translation> + </message> + <message> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation>剪定: 最後のウォレット同期ポイントは、選定されたデータよりも過去のものとなっています。-reindexをする必要があります (剪定されたノードの場合、ブロックチェイン全体をダウンロードします)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>古いブロックを剪定する (削除する) ことで記憶容量の必要量を削減する。このモードを有効にすると-txindexや-rescanと互換性がなくなります。警告: この設定の再有効化には全ブロックチェインの再ダウンロードが必要となります。(規定値: 0 = ブロックの剪定無効、>%u = ブロックファイルに使用するMiB単位の目標サイズ)</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>剪定モードでは再スキャンを行うことはできません。-reindexを指定し、ブロックチェイン全体を再ダウンロードする必要があります。</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>エラー:致命的な内部エラーが発生しました。詳細はdebug.logを参照してください</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>送信するトランザクションに付加する手数料 (%s/kB単位) (初期値: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>ブロックデータを剪定しています……</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>デーモンとしてバックグランドで実行しコマンドを許可</translation> </message> <message> - <source>Use the test network</source> - <translation>テストのためのネットワークを使用</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>HTTPサーバを開始できませんでした。詳細はデバッグログをご確認ください。</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2829,18 +2996,14 @@ <translation>ウォレットの取引を変更する際にコマンドを実行 (cmd の %s は TxID に置換される)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>ひとつのウォレットトランザクションで使用する合計手数料の最大値。低すぎる値を指定すると巨大なトランザクションの作成ができなくなります (規定値: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>古いブロックを剪定する(削除する)ことで記憶容量の必要量を削減する。このモードを有効にするとウォレット機能のサポートは無効になり、-txindexとも互換性がなくなります。警告: この設定の再有効化には全ブロックチェインの再ダウンロードが必要となります。(規定値: 0 = ブロックの剪定無効、>%u = ブロックファイルに使用するMiB単位の目標サイズ)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>スクリプト検証スレッドを設定 (%uから%dの間, 0 = 自動, <0 = たくさんのコアを自由にしておく, 初期値: %d)</translation> </message> <message> + <source>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>ブロックのデータベースに未来の時刻のブロックが含まれています。これはおそらくお使いのコンピュータに設定されている日時が間違っていることを示しています。お使いのコンピュータの日時が本当に正しい場合にのみ、ブロックのデータベースの再構築を行ってください。</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> @@ -2849,6 +3012,10 @@ <translation>このコンピュータの %s にバインドすることができません。おそらく Bitcoin Core は既に実行されています。</translation> </message> <message> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>リスン ポートの割当に UPnP を使用 (初期値: リスン中および-proxyが指定されていない場合は1)</translation> + </message> + <message> <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> <translation>警告:異常に多くの数のブロックが生成されています。%d ブロックが最近 %d 時間以内に受け取られました。(期待値: %d)</translation> </message> @@ -2857,10 +3024,6 @@ <translation>警告:ネットワーク接続を確認してください。%d ブロックが最近 %d 時間以内にに受け取られました。(期待値: %d)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>警告: -paytxfee が非常に高く設定されています! これは取引を送信する場合に支払う取引手数料です。</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>警告: ネットワークは完全に同意しないみたいです。マイナーは何かの問題を経験してるみたいなんです。</translation> </message> @@ -2869,10 +3032,6 @@ <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> - <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> </message> @@ -2881,18 +3040,14 @@ <translation>与えられたネットマスクやIPアドレスから接続を行う、ホワイトリストのピア。複数回指定できます。</translation> </message> <message> - <source>(default: 1)</source> - <translation>(デフォルト: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempoolは最低でも %d MB必要です</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> - <message> <source>Block creation options:</source> <translation>ブロック作成オプション:</translation> </message> @@ -2922,6 +3077,22 @@ <translation>ブロック データベースを今すぐ再構築しますか?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation><address>に対し、ハッシュブロックの公開を有効にする</translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation><address> に対し、ハッシュトランザクションの公開を有効にする</translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation><address> に対し、生ブロックの公開を有効にする</translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation><address> に対し、生トランザクションの公開を有効にする</translation> + </message> + <message> <source>Error initializing block database</source> <translation>ブロック データベースの初期化中にエラー</translation> </message> @@ -2938,10 +3109,6 @@ <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> @@ -2950,10 +3117,6 @@ <translation>ポートのリスンに失敗しました。必要であれば -listen=0 を使用してください。</translation> </message> <message> - <source>If <category> is not supplied, output all debugging information.</source> - <translation><category> が与えられなかった場合には、すべてのデバッグ情報が出力されます。</translation> - </message> - <message> <source>Importing...</source> <translation>インポートしています……</translation> </message> @@ -2966,6 +3129,10 @@ <translation>無効な -onion アドレス:'%s'</translation> </message> <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>トランザクションのメモリ・プールの総量を <n> メガバイト以下に維持する (初期値: %u)</translation> + </message> + <message> <source>Not enough file descriptors available.</source> <translation>使用可能なファイルディスクリプタが不足しています。</translation> </message> @@ -2994,10 +3161,26 @@ <translation>ウォレットのファイルを指定 (データ・ディレクトリの中に)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>サポートされていない引数 -benchmark は無視されました。-debug=bench を使用してください。</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>サポートされていない引数 -debugnet は無視されました。-debug=net を使用してください。</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>サポートされていない引数 -tor が見つかりました。-onion を使用してください。</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>リッスンポートの割当に UPnP を使用 (初期値: %u)</translation> </message> <message> + <source>User Agent comment (%s) contains unsafe characters.</source> + <translation>ユーザエージェントのコメント (%s) には安全でない文字が含まれています。</translation> + </message> + <message> <source>Verifying blocks...</source> <translation>ブロックの検証中...</translation> </message> @@ -3022,18 +3205,10 @@ <translation>-txindex を変更するには -reindex を使用してデータベースを再構築する必要があります</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)、ネットワーク/ネットマスク (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の場合には [host]:port 表記を使用してください</translation> </message> @@ -3058,16 +3233,12 @@ <translation>エラー: 内向きの接続をリッスンするのに失敗しました (エラー %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/Kb単位) はゼロであるとみなす (デフォルト: %s)</translation> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>トランザクションの中継、採掘および作成の際には、この値未満の手数料 (%s/kB単位) はゼロであるとみなす (デフォルト: %s)</translation> </message> <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> @@ -3082,10 +3253,6 @@ <translation>中継および採掘を行う際の、データ運送トランザクションの中のデータの最大サイズ (初期値: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>剪定が最小値の %d MB以下に設定されています。もっと大きな値を使用してください。</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>保有するピアアドレスが少ない場合、DNS ルックアップによりピアアドレスを問い合わせる (-connect を使っていない場合の初期値: 1)</translation> </message> @@ -3110,38 +3277,6 @@ <translation>この製品はOpenSSLプロジェクトにより開発されたソフトウェアをOpenSSLツールキットとして利用しています <https://www.openssl.org/>。また、Eric Young氏により開発された暗号ソフトウェア、Thomas Bernard氏により書かれたUPnPソフトウェアを用いています。</translation> </message> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>bitcoindを用いる場合や、-server オプションをbitcoin-qtに指定する場合には、設定ファイルにrpcpasswordを設定しなければなりません: -%s -以下のランダムなパスワードを用いることが推奨されます: -rpcuser=bitcoinrpc -rpcpassword=%s -(このパスワードを暗記する必要はありません) -ユーザ名とパスワードは一致してはいけません。 -ファイルが存在しない場合には、所有者のみ読み込み可能なファイルパーミッションでファイルを作成してください。 -またalertnotifyを設定し、問題発生時に通知が行くようにすることをおすすめします; -例: alertnotify=echo %%s | mail -s "Bitcoinアラート" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>警告: -maxtxfee が非常に高く設定されています!ひとつのトランザクションでこの量の手数料が支払われてしまうことがあります。</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>警告: あなたのPCの日付と時刻が正しいことを確認して下さい! もしあなたの時計が正しくなければ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によるアクセス禁止処理が無効化され、トランザクションは例えmempool内に既に存在していたとしても常にリレーされます。これは例えばゲートウェイに対して有用です</translation> </message> @@ -3162,16 +3297,20 @@ rpcpassword=%s <translation>最優良のチェインを有効化しています...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>剪定モードではウォレット機能付きで起動できません。</translation> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>ホワイトリストにあるピアから受け取ったトランザクションを常にリレーする (初期値: %d)</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>-whitebind アドレス '%s' を解決できません</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>起動時に壊れた wallet.dat から秘密鍵を復旧することを試す</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>起動時にデータ ディレクトリを選ぶ (初期値: 0)</translation> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Tor秘匿サービスを自動的に作成する (初期値: %d)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>-whitebind アドレス '%s' を解決できません</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3182,10 +3321,6 @@ rpcpassword=%s <translation>Copyright (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> @@ -3194,12 +3329,8 @@ rpcpassword=%s <translation>データベースの読み込みエラー。シャットダウンします。</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/kB単位) (初期値: %s)</translation> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>起動時に外部の blk000??.dat ファイルからブロックをインポート</translation> </message> <message> <source>Information</source> @@ -3242,18 +3373,10 @@ rpcpassword=%s <translation>ノード中継オプション:</translation> </message> <message> - <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> - <translation>RPC SSL オプション: (SSLのセットアップ手順はビットコインWikiを参照してください)</translation> - </message> - <message> <source>RPC server options:</source> <translation>RPCサーバのオプション:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>RPCにおけるHTTPの持続的接続のサポート (初期値: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>起動時に現在の blk000??.dat ファイルからブロック チェーンのインデックスを再構築</translation> </message> @@ -3262,30 +3385,26 @@ rpcpassword=%s <translation>P2Pネットワークのアラートの受け取りと表示を行う (デフォルト: %u)</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>トレース/デバッグ情報を debug.log ファイルの代わりにコンソールへ送る</translation> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> + <translation>システム上の制約から、-maxconnections を %d から %d に削減しました。</translation> </message> <message> - <source>Send transactions as zero-fee transactions if possible (default: %u)</source> - <translation>可能な場合には手数料ゼロのトランザクションとしてトランザクションを送信する (初期値: %u)</translation> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>起動時に失ったウォレットの取引のブロック チェーンを再スキャン</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>支払いリクエスト用にSSLルート証明書を設定する(デフォルト:-system-)</translation> + <source>Send trace/debug info to console instead of debug.log file</source> + <translation>トレース/デバッグ情報を debug.log ファイルの代わりにコンソールへ送る</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>言語設定 例: "de_DE" (初期値: システムの言語)</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> <translation>すべてのデバッグオプションを表示する (使い方: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>起動時にスプラッシュ画面を表示する (初期値: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>クライアント起動時に debug.log ファイルを縮小 (初期値: -debug オプションを指定しない場合は1)</translation> </message> @@ -3294,10 +3413,6 @@ rpcpassword=%s <translation>取引の署名に失敗しました</translation> </message> <message> - <source>Start minimized</source> - <translation>最小化された状態で起動する</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>トランザクションの金額が小さすぎて手数料を支払えません</translation> </message> @@ -3306,6 +3421,14 @@ rpcpassword=%s <translation>これは実験的なソフトウェアです。</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>Tor管理ポートのパスワード (初期値: 空文字)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>Onion のリッスンが有効になっている場合に使用するTor管理ポート (初期値: %s)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>取引の額が小さ過ぎます</translation> </message> @@ -3322,16 +3445,12 @@ rpcpassword=%s <translation>取引が大き過ぎます</translation> </message> <message> - <source>UI Options:</source> - <translation>UIオプション:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>このコンピュータの %s にバインドすることができません (バインドが返したエラーは %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>リスン ポートの割当に UPnP を使用 (初期値: リスン中は1)</translation> + <source>Upgrade wallet to latest format on startup</source> + <translation>起動時にウォレットを最新のフォーマットにアップグレード</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3346,20 +3465,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> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>ブロック限定モードにおいて動作を行うかどうか (初期値: %u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> <translation>ウォレットからすべてのトランザクションを消去しています...</translation> </message> <message> - <source>on startup</source> - <translation>起動時</translation> + <source>ZeroMQ notification options:</source> + <translation>ZeroMQ通知オプション:</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3374,18 +3489,6 @@ rpcpassword=%s <translation>最良のブロックに変更する際にコマンドを実行 (cmd の %s はブロック ハッシュに置換される)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>ウォレットを最新のフォーマットにアップグレード</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>失ったウォレットの取引のブロック チェーンを再スキャン</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>JSON-RPC 接続に OpenSSL (https) を使用</translation> - </message> - <message> <source>This help message</source> <translation>このヘルプ メッセージ</translation> </message> @@ -3406,6 +3509,26 @@ rpcpassword=%s <translation>(1 = トランザクションのメタデータ、例えばアカウントの所有者や支払リクエストの内容を保持する, 2 = トランザクションのメタデータを破棄する)</translation> </message> <message> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>-maxtxfee が非常に高く設定されています!ひとつのトランザクションでこの量の手数料が支払われてしまうことがあります。</translation> + </message> + <message> + <source>-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>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>mempool内でトランザクションを <n> 時間以上保持しない (初期値: %u)</translation> + </message> + <message> + <source>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> + <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>トランザクション作成の際、この値未満の手数料 (%s/kB単位) はゼロであるとみなす (デフォルト: %s)</translation> + </message> + <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>-checkblocks のブロックの検証レベル (0-4, 初期値: %u)</translation> </message> @@ -3422,16 +3545,32 @@ rpcpassword=%s <translation>デバッグ情報を出力する (初期値: %u, <category> の指定は任意です)</translation> </message> <message> + <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> + <translation>Bloomフィルタによる、ブロックおよびトランザクションのフィルタリングを有効化する (初期値: %u)</translation> + </message> + <message> + <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> + <translation>ネットワークバージョン文字 (%i) の長さが最大の長さ (%i) を超えています。UAコメントの数や長さを削減してください。</translation> + </message> + <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>送信転送量を与えられた目標値以下に維持するようにする (24時間あたり何MiBかで指定)。0 の場合は無制限 (初期値: %d)</translation> + </message> + <message> + <source>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>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> <translation>Tor 秘匿サービスを通し、別々の SOCKS5 プロキシを用いることでピアに到達する (初期値: %s)</translation> </message> <message> - <source>(default: %s)</source> - <translation>(デフォルト: %s)</translation> + <source>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source> + <translation>JSON-RPC接続時のユーザ名とハッシュ化されたパスワード。<userpw> フィールドのフォーマットは <USERNAME>:<SALT>$<HASH>。標準的な Python スクリプトが share/rpcuser 内に含まれています。このオプションは複数回指定できます。</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>受付可能な暗号化方式 (初期値: %s)</translation> + <source>(default: %s)</source> + <translation>(デフォルト: %s)</translation> </message> <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> @@ -3494,14 +3633,6 @@ rpcpassword=%s <translation>P2SHでないマルチシグトランザクションをリレーする (初期値: %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>key pool のサイズを <n> (初期値: %u) にセット</translation> </message> diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts index 4c6ce13eff..11c73ec767 100644 --- a/src/qt/locale/bitcoin_ka.ts +++ b/src/qt/locale/bitcoin_ka.ts @@ -1,4 +1,4 @@ -<TS language="ka" version="2.0"> +<TS language="ka" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -201,6 +201,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -745,7 +748,7 @@ <source>command-line options</source> <translation>კომანდების ზოლის ოპციები</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -761,6 +764,10 @@ <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-ის ბლოკთა ჯაჭვს. მითითებულ კატალოგში დაგროვდება სულ ცოტა %1 გბ მონაცემები, და მომავალში უფრო გაიზრდება. საფულეც ამავე კატალოგში შეინახება.</translation> + </message> + <message> <source>Use the default data directory</source> <translation>ნაგულისხმევი კატალოგის გამოყენება</translation> </message> @@ -1429,6 +1436,10 @@ <translation>ხურდის მისამართი</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>ტრანსაქციის საფასური - საკომისიო:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>გაგზავნა რამდენიმე რეციპიენტთან ერთდროულად</translation> </message> @@ -1493,10 +1504,6 @@ <translation>ხურდის კოპირება</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>ჯამური თანხა %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>ან</translation> </message> @@ -1509,6 +1516,10 @@ <translation>თანხა აღემატება თქვენს ბალანსს</translation> </message> <message> + <source>The total exceeds your balance when the %1 transaction fee is included.</source> + <translation>საკომისიო %1-ის დამატების შემდეგ თანხა აჭარბებს თქვენს ბალანსს</translation> + </message> + <message> <source>Transaction creation failed!</source> <translation>შეცდომა ტრანსაქციის შექმნისას!</translation> </message> @@ -2203,10 +2214,6 @@ <translation>რეზიდენტულად გაშვება და კომანდების მიღება</translation> </message> <message> - <source>Use the test network</source> - <translation>სატესტო ქსელის გამოყენება</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>გარედან შეერთებების დაშვება (ნაგულისხმევი: 1 თუ არ გამოიყენება -proxy ან -connect)</translation> </message> @@ -2223,10 +2230,6 @@ <translation>ეს არის წინასწარი სატესტო ვერსია - გამოიყენეთ საკუთარი რისკით - არ გამოიყენოთ მოპოვებისა ან კომერციული მიზნებისათვის</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> @@ -2235,10 +2238,6 @@ <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> - <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> </message> @@ -2247,10 +2246,6 @@ <translation><category> შეიძლება იყოს:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>პირადი გასაღებების აღდგენის მცდელობა wallet.dat-იდან</translation> - </message> - <message> <source>Block creation options:</source> <translation>ბლოკის შექმნის ოპციები:</translation> </message> @@ -2295,10 +2290,6 @@ <translation>ვერ ხერხდება პორტების მიყურადება. თუ გსურთ, გამოიყენეთ -listen=0.</translation> </message> <message> - <source>If <category> is not supplied, output all debugging information.</source> - <translation>თუ <category> არ არის მითითებული, ნაჩვენები იქნება სრული დახვეწის ინფორმაცია.</translation> - </message> - <message> <source>Incorrect or no genesis block found. Wrong datadir for network?</source> <translation>საწყისი ბლოკი არ არსებობს ან არასწორია. ქსელის მონაცემთა კატალოგი datadir ხომ არის არასწორი?</translation> </message> @@ -2339,10 +2330,6 @@ <translation>საჭიროა ბაზის ხელახალი აგება, გამოიყენეთ -reindex რათა შეცვალოთ -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>ბლოკების იმპორტი გარე blk000??.dat ფაილიდან</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>ბრძანების შესრულება შესაბამისი უწყების მიღებისას ან როცა შეინიშნება საგრძნობი გახლეჩა (cmd-ში %s შეიცვლება მესიჯით)</translation> </message> @@ -2351,14 +2338,18 @@ <translation>მაღალპრიორიტეტული/დაბალსაკომისიოიანი ტრანსაქციების მაქსიმალური ზომა ბაიტებში (ნაგულისხმევი: %d)</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>მონაცემთა კატალოგის მითითება ყოველი გაშვებისას (ნაგულისხმევი: 0)</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>ვერ ხერხდება -whitebind მისამართის გარკვევა: '%s'</translation> </message> <message> <source>Information</source> <translation>ინფორმაცია</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>დაუშვებელი მნიშვნელობა -pmaxtxfee<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>დაუშვებელი მნიშვნელობა -minrelaytxfee=<amount>: '%s'</translation> </message> @@ -2371,14 +2362,6 @@ <translation>ტრასირების/დახვეწის ინფოს გაგზავნა კონსოლზე debug.log ფაილის ნაცვლად</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>აირჩიეთ ენა, მაგალითად "de_DE" (ნაგულისხმევია სისტემური ლოკალი)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>მისალმების ეკრანის ჩვენება გაშვებისას (ნაგულისხმევი:1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>debug.log ფაილის შეკუმშვა გაშვებისას (ნაგულისხმევია: 1 როცა არ აყენია -debug)</translation> </message> @@ -2387,10 +2370,6 @@ <translation>ტრანსაქციების ხელმოწერა ვერ მოხერხდა</translation> </message> <message> - <source>Start minimized</source> - <translation>გაშვება მინიმიზებული ეკრანით</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>ტრანსაქციების რაოდენობა ძალიან ცოტაა</translation> </message> @@ -2403,10 +2382,6 @@ <translation>ტრანსაქცია ძალიან დიდია</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>გამოიყენეთ UPnP მისაყურადებელი პორტის გადასამისამართებლად (ნაგულისხმევი: 1 როცა ჩართულია მიყურადება)</translation> - </message> - <message> <source>Username for JSON-RPC connections</source> <translation>მომხმარებლის სახელი JSON-RPC-შეერთებისათვის</translation> </message> @@ -2431,18 +2406,6 @@ <translation>კომანდის შესრულება უკეთესი ბლოკის გამოჩენისას (%s კომანდაში ჩანაცვლდება ბლოკის ჰეშით)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>საფულის ფორმატის განახლება</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>ბლოკების ჯაჭვის გადამოწმება საფულეში გამორჩენილ ტრანსაქციებზე</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>OpenSSL-ის (https) გამოყენება JSON-RPC-შეერთებებისათვის</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 5ee9040633..cfa19d13f0 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.0"> +<TS language="kk_KZ" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -85,6 +85,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>&Transactions</source> @@ -228,6 +231,10 @@ <context> <name>EditAddressDialog</name> <message> + <source>&Label</source> + <translation>таңба</translation> + </message> + <message> <source>&Address</source> <translation>Адрес</translation> </message> @@ -250,6 +257,10 @@ </context> <context> <name>OptionsDialog</name> + <message> + <source>W&allet</source> + <translation>Әмиян</translation> + </message> </context> <context> <name>OverviewPage</name> @@ -272,9 +283,17 @@ </context> <context> <name>RPCConsole</name> + <message> + <source>&Information</source> + <translation>Информация</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> + <message> + <source>&Amount:</source> + <translation>Саны</translation> + </message> </context> <context> <name>ReceiveRequestDialog</name> @@ -339,6 +358,10 @@ </context> <context> <name>SendCoinsEntry</name> + <message> + <source>A&mount:</source> + <translation>Саны</translation> + </message> </context> <context> <name>ShutdownWindow</name> diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 5126e53f8e..ce48ce249f 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -1,9 +1,9 @@ -<TS language="ko_KR" version="2.0"> +<TS language="ko_KR" version="2.1"> <context> <name>AddressBookPage</name> <message> <source>Right-click to edit address or label</source> - <translation>지갑 주소나 이름을 수정하려면 우클릭하세요.</translation> + <translation>지갑 주소나 라벨을 수정하려면 우클릭하세요.</translation> </message> <message> <source>Create a new address</source> @@ -27,7 +27,7 @@ </message> <message> <source>&Copy Address</source> - <translation>계좌 복사(&C)</translation> + <translation>주소 복사(&C)</translation> </message> <message> <source>Delete the currently selected address from the list</source> @@ -59,11 +59,11 @@ </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> @@ -75,7 +75,7 @@ </message> <message> <source>Copy &Label</source> - <translation>표 복사</translation> + <translation>라벨 복사</translation> </message> <message> <source>&Edit</source> @@ -87,7 +87,7 @@ </message> <message> <source>Comma separated file (*.csv)</source> - <translation>각각의 파일에 쉼표하기(*.csv)</translation> + <translation>쉼표로 구분된 파일(*.csv)</translation> </message> <message> <source>Exporting Failed</source> @@ -95,14 +95,14 @@ </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> <name>AddressTableModel</name> <message> <source>Label</source> - <translation>표</translation> + <translation>라벨</translation> </message> <message> <source>Address</source> @@ -110,7 +110,7 @@ </message> <message> <source>(no label)</source> - <translation>(표 없음)</translation> + <translation>(라벨 없음)</translation> </message> </context> <context> @@ -129,7 +129,7 @@ </message> <message> <source>Repeat new passphrase</source> - <translation>새 암호 반복</translation> + <translation>새로운 암호 재확인</translation> </message> <message> <source>Encrypt wallet</source> @@ -141,7 +141,7 @@ </message> <message> <source>Unlock wallet</source> - <translation>지갑 열기</translation> + <translation>지갑 잠금해제</translation> </message> <message> <source>This operation needs your wallet passphrase to decrypt the wallet.</source> @@ -157,11 +157,11 @@ </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>경고: 만약 암호화된 지갑의 비밀번호를 잃어버릴 경우, 모든 비트코인들을 잃어버릴 수 있습니다!</translation> + <translation>경고: 만약 암호화 된 지갑의 비밀번호를 잃어버릴 경우, <b>모든 비트코인들을 잃어버릴 수 있습니다</b>!</translation> </message> <message> <source>Are you sure you wish to encrypt your wallet?</source> @@ -169,17 +169,21 @@ </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>경고: 캡스록 키가 켜져있습니다!</translation> + <translation>경고: Caps Lock키가 켜져있습니다!</translation> </message> <message> <source>Wallet encrypted</source> <translation>지갑 암호화 완료</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>지갑의 기존 암호와 새로운 암호를 입력해주세요.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>지갑 암호화 실패</translation> </message> @@ -209,6 +213,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -344,11 +351,11 @@ </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> @@ -396,7 +403,7 @@ </message> <message> <source>Open a bitcoin: URI or payment request</source> - <translation>비트코인: URI 또는 지불요청 열기</translation> + <translation>bitcoin: URI 또는 지불요청 열기</translation> </message> <message> <source>&Command-line options</source> @@ -426,6 +433,10 @@ <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> @@ -459,6 +470,36 @@ <translation>블록 따라잡기...</translation> </message> <message> + <source>Date: %1 +</source> + <translation>날짜: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>금액: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>종류: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>라벨: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>주소: %1 +</translation> + </message> + <message> <source>Sent transaction</source> <translation>거래 보내기</translation> </message> @@ -498,7 +539,7 @@ </message> <message> <source>Amount:</source> - <translation>거래량:</translation> + <translation>금액:</translation> </message> <message> <source>Priority:</source> @@ -769,7 +810,7 @@ <source>command-line options</source> <translation>명령줄 옵션</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -927,6 +968,18 @@ <translation>프록시의 포트번호입니다(예: 9050)</translation> </message> <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> <source>&Window</source> <translation>창(&W)</translation> </message> @@ -1034,6 +1087,10 @@ <translation>아직 사용 가능하지 않은 채굴된 잔액</translation> </message> <message> + <source>Balances</source> + <translation>잔액</translation> + </message> + <message> <source>Total:</source> <translation>총액:</translation> </message> @@ -1045,6 +1102,10 @@ <source>Your current balance in watch-only addresses</source> <translation>모니터링 지갑의 현재 잔액</translation> </message> + <message> + <source>Recent transactions</source> + <translation>최근 거래</translation> + </message> </context> <context> <name>PaymentServer</name> @@ -1115,10 +1176,26 @@ <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>N/A</source> <translation>없음</translation> </message> - </context> + <message> + <source>%1 ms</source> + <translation>%1 ms</translation> + </message> +</context> <context> <name>QRImageWidget</name> <message> @@ -1166,7 +1243,11 @@ </message> <message> <source>Using OpenSSL version</source> - <translation>오픈SSL 버전을 사용합니다</translation> + <translation>사용중인 OpenSSL 버전</translation> + </message> + <message> + <source>Using BerkeleyDB version</source> + <translation>사용중인 BerkeleyDB 버전</translation> </message> <message> <source>Startup time</source> @@ -1193,6 +1274,22 @@ <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>Version</source> + <translation>버전</translation> + </message> + <message> <source>Last block time</source> <translation>최종 블럭 시각</translation> </message> @@ -1244,6 +1341,22 @@ <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> </context> <context> <name>ReceiveCoinsDialog</name> @@ -1253,7 +1366,7 @@ </message> <message> <source>&Label:</source> - <translation>표:</translation> + <translation>라벨:</translation> </message> <message> <source>&Message:</source> @@ -1395,7 +1508,7 @@ </message> <message> <source>(no label)</source> - <translation>(표 없음)</translation> + <translation>(라벨 없음)</translation> </message> <message> <source>(no message)</source> @@ -1461,6 +1574,14 @@ <translation>주소변경</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>거래 수수료:</translation> + </message> + <message> + <source>Recommended:</source> + <translation>권장:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>다수의 수령인들에게 한번에 보내기</translation> </message> @@ -1525,10 +1646,6 @@ <translation>우선도 복사</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>총 액수 %1(=%2)</translation> - </message> - <message> <source>or</source> <translation>또는</translation> </message> @@ -2108,6 +2225,10 @@ <translation>거래 기록 내보내기</translation> </message> <message> + <source>Watch-only</source> + <translation>모니터링 지갑</translation> + </message> + <message> <source>Exporting Failed</source> <translation>내보내기 실패</translation> </message> @@ -2239,10 +2360,6 @@ <translation>데몬으로 백그라운드에서 실행하고 명령을 허용</translation> </message> <message> - <source>Use the test network</source> - <translation>테스트 네트워크 사용</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>외부 접속을 승인합니다</translation> </message> @@ -2259,10 +2376,6 @@ <translation>이 빌드 버전은 정식 출시 전 테스트의 목적이며, 예기치 않은 위험과 오류가 발생할 수 있습니다. 채굴과 상점용 소프트웨어로 사용하는 것을 권하지 않습니다.</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> @@ -2271,22 +2384,10 @@ <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> - <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 파일은 %s 후에 wallet.{timestamp}.bak 이름으로 저장됩니다. 잔액과 거래 내역이 정확하지 않다면 백업 파일로 부터 복원해야 합니다. </translation> </message> <message> - <source>(default: 1)</source> - <translation>(기본값: 1)</translation> - </message> - <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>손상된 wallet.dat에서 개인키 복원을 시도합니다</translation> - </message> - <message> <source>Block creation options:</source> <translation>블록 생성 옵션:</translation> </message> @@ -2319,6 +2420,10 @@ <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> @@ -2335,10 +2440,6 @@ <translation>어떤 포트도 반응하지 않습니다. 사용자 반응=0 만약 원한다면</translation> </message> <message> - <source>If <category> is not supplied, output all debugging information.</source> - <translation><카테고리>가 제공되지 않을 경우, 모든 디버깅 정보를 출력</translation> - </message> - <message> <source>Importing...</source> <translation>들여오기 중...</translation> </message> @@ -2387,10 +2488,6 @@ <translation>-txindex를 바꾸기 위해서는 -reindex를 사용해서 데이터베이스를 재구성해야 합니다. </translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>외부 blk000??.dat 파일에서 블록을 가져옵니다.</translation> - </message> - <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>데이터 디렉토리 %s에 락을 걸 수 없었습니다. 비트코인 코어가 이미 실행 중인 것으로 보입니다.</translation> </message> @@ -2403,14 +2500,18 @@ <translation>최대 크기를 최우선으로 설정 / 바이트당 최소 수수료로 거래(기본값: %d)</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>파일목록을 선택하여 시작하시오(기본값: 0)</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>-whitebind 주소를 확인할 수 없습니다: '%s'</translation> </message> <message> <source>Information</source> <translation>정보</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>-maxtxfee=<amount>에 대한 양이 잘못되었습니다: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>노드로 전달하기 위한 최저 거래 수수료가 부족합니다. - minrelaytxfee=<amount>: '%s' -</translation> </message> @@ -2419,10 +2520,6 @@ <translation>최저 거래 수수료가 부족합니다. -mintxfee=<amount>: '%s'</translation> </message> <message> - <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> @@ -2431,22 +2528,10 @@ <translation>추적오류 정보를 degug.log 자료로 보내는 대신 콘솔로 보내기</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>지불 요청을 위해 SSL 최상위 인증을 설정합니다. (기본값: -system-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>"de_DE"와 같이 언어를 설정하십시오 (기본값: 시스템 로캘)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>모든 디버그 설정 보기(설정: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>시작시 시작 화면 표시 (기본값: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>클라이언트 시작시 debug.log 파일 비우기(기본값: 디버그 안할때 1)</translation> </message> @@ -2455,10 +2540,6 @@ <translation>거래를 서명하는것을 실패하였습니다.</translation> </message> <message> - <source>Start minimized</source> - <translation>최소화 상태에서 시작</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>거래량이 너무 적습니다</translation> </message> @@ -2471,10 +2552,6 @@ <translation>너무 큰 거래</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>UPnP사용하여 지도에서 포트 반응기다리는 중 (기본값: 1 반응이 생기면)</translation> - </message> - <message> <source>Username for JSON-RPC connections</source> <translation>JSON-RPC 연결에 사용할 사용자 이름</translation> </message> @@ -2487,10 +2564,6 @@ <translation>지갑의 모든거래내역 건너뛰기...</translation> </message> <message> - <source>on startup</source> - <translation>구동 중</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat 파일이 손상되었고 복구가 실패하였습니다.</translation> </message> @@ -2503,18 +2576,6 @@ <translation>최고의 블럭이 변하면 명령을 실행(cmd 에 있는 %s 는 블럭 해시에 의해 대체되어 짐)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>지갑을 최근 형식으로 개선하시오</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>누락된 지갑 송금에 대한 블록 체인 다시 검색</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>JSON-RPC 연결에 OpenSSL(https) 사용</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 442d7c5d52..51efd519c3 100644 --- a/src/qt/locale/bitcoin_ky.ts +++ b/src/qt/locale/bitcoin_ky.ts @@ -1,4 +1,4 @@ -<TS language="ky" version="2.0"> +<TS language="ky" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -25,6 +25,9 @@ <name>AskPassphraseDialog</name> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>&Transactions</source> @@ -123,6 +126,10 @@ <translation>&Тармак</translation> </message> <message> + <source>W&allet</source> + <translation>Капчык</translation> + </message> + <message> <source>&Port:</source> <translation>&Порт:</translation> </message> @@ -173,6 +180,10 @@ <translation>Жалпы</translation> </message> <message> + <source>Network</source> + <translation>&Тармак</translation> + </message> + <message> <source>Name</source> <translation>Аты</translation> </message> @@ -191,6 +202,10 @@ </context> <context> <name>ReceiveCoinsDialog</name> + <message> + <source>&Message:</source> + <translation>Билдирүү:</translation> + </message> </context> <context> <name>ReceiveRequestDialog</name> diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts index b1a69c9a9e..e3dcd505fe 100644 --- a/src/qt/locale/bitcoin_la.ts +++ b/src/qt/locale/bitcoin_la.ts @@ -1,4 +1,4 @@ -<TS language="la" version="2.0"> +<TS language="la" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -157,6 +157,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -303,6 +306,10 @@ <translation>Bitcoin Nucleus</translation> </message> <message> + <source>&Command-line options</source> + <translation>Optiones mandati initiantis</translation> + </message> + <message> <source>No block source available...</source> <translation>Nulla fons frustorum absens...</translation> </message> @@ -473,7 +480,7 @@ <source>command-line options</source> <translation>Optiones mandati intiantis</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -511,6 +518,10 @@ <translation>&Rete</translation> </message> <message> + <source>W&allet</source> + <translation>Cassidile</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>Aperi per se portam clientis Bitcoin in itineratore. Hoc tantum effectivum est si itineratrum tuum supportat UPnP et id activum est.</translation> </message> @@ -653,6 +664,10 @@ <translation>&Informatio</translation> </message> <message> + <source>Debug window</source> + <translation>Fenestra Debug</translation> + </message> + <message> <source>Using OpenSSL version</source> <translation>Utens OpenSSL versione</translation> </message> @@ -712,10 +727,18 @@ <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>Quantitas:</translation> + </message> + <message> <source>&Label:</source> <translation>&Titulus:</translation> </message> <message> + <source>&Message:</source> + <translation>Nuntius:</translation> + </message> + <message> <source>Copy label</source> <translation>Copia titulum</translation> </message> @@ -727,6 +750,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>&Copia Inscriptionem</translation> + </message> + <message> <source>Address</source> <translation>Inscriptio</translation> </message> @@ -781,10 +808,18 @@ <translation>Mitte Nummos</translation> </message> <message> + <source>Insufficient funds!</source> + <translation>Inopia nummorum</translation> + </message> + <message> <source>Amount:</source> <translation>Quantitas:</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Transactionis merces:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Mitte pluribus accipientibus simul</translation> </message> @@ -867,6 +902,10 @@ <source>Message:</source> <translation>Nuntius:</translation> </message> + <message> + <source>Pay To:</source> + <translation>Pensa Ad:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -1387,10 +1426,6 @@ <translation>Operare infere sicut daemon et mandata accipe</translation> </message> <message> - <source>Use the test network</source> - <translation>Utere rete experimentale</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Accipe conexiones externas (praedefinitum: 1 nisi -proxy neque -connect)</translation> </message> @@ -1407,22 +1442,10 @@ <translation>Hoc est prae-dimittum experimentala aedes - utere eo periculo tuo proprio - nolite utere fodendo vel applicationibus mercatoriis</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>Monitio: -paytxfee constitutum valde magnum! Hoc est merces transactionis solves si mittis transactionem.</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>Monitio: error legendo wallet.dat! Omnes claves recte lectae, sed data transactionum vel libri inscriptionum fortasse desint vel prava sint.</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>Monitio: wallet.data corrupta, data salvata! Originalis wallet.dat salvata ut wallet.{timestamp}.bak in %s; si pendendum tuum vel transactiones pravae sunt, oportet ab conservato restituere.</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Conare recipere claves privatas de corrupto wallet.dat</translation> - </message> - <message> <source>Block creation options:</source> <translation>Optiones creandi frustorum:</translation> </message> @@ -1475,14 +1498,18 @@ <translation>Verificante cassidilem...</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importat frusta ab externa plica blk000??.dat</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Non posse resolvere -whitebind inscriptionem: '%s'</translation> </message> <message> <source>Information</source> <translation>Informatio</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Quantitas non valida pro -maxtxfee=<amount>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Quantitas non valida pro -minrelaytxfee=<amount>: '%s'</translation> </message> @@ -1495,14 +1522,6 @@ <translation>Mitte informationem vestigii/debug ad terminale potius quam plicam debug.log</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Constitue linguam, exempli gratia "de_DE" (praedefinitum: lingua systematis)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Monstra principem imaginem ad initium (praedefinitum: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Diminue plicam debug.log ad initium clientis (praedefinitum: 1 nisi -debug)</translation> </message> @@ -1511,10 +1530,6 @@ <translation>Signandum transactionis abortum est</translation> </message> <message> - <source>Start minimized</source> - <translation>Incipe minifactum ut icon</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Magnitudo transactionis nimis parva</translation> </message> @@ -1527,10 +1542,6 @@ <translation>Transactio nimis magna</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> - <message> <source>Username for JSON-RPC connections</source> <translation>Nomen utentis pro conexionibus JSON-RPC</translation> </message> @@ -1551,18 +1562,6 @@ <translation>Pelle mandatum quando optissimum frustum mutat (%s in mandato substituitur ab hash frusti)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Progredere cassidile ad formam recentissimam</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Iterum perlege catenam frustorum propter absentes cassidilis transactiones</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Utere OpenSSL (https) pro conexionibus JSON-RPC</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 4e468911dc..b98976dfea 100644 --- a/src/qt/locale/bitcoin_lt.ts +++ b/src/qt/locale/bitcoin_lt.ts @@ -1,4 +1,4 @@ -<TS language="lt" version="2.0"> +<TS language="lt" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -189,6 +189,13 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>Banned Until</source> + <translation>Užblokuotas iki</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -355,6 +362,10 @@ <translation>&Apie Bitcoin Core</translation> </message> <message> + <source>&Command-line options</source> + <translation>Komandinės eilutės parametrai</translation> + </message> + <message> <source>Error</source> <translation>Klaida</translation> </message> @@ -548,7 +559,11 @@ <source>(no label)</source> <translation>(nėra žymės)</translation> </message> - </context> + <message> + <source>(change)</source> + <translation>(Graža)</translation> + </message> +</context> <context> <name>EditAddressDialog</name> <message> @@ -629,7 +644,7 @@ <source>command-line options</source> <translation>komandinės eilutės parametrai</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -663,10 +678,26 @@ <translation>&Pagrindinės</translation> </message> <message> + <source>MB</source> + <translation>MB</translation> + </message> + <message> + <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> + <translation>Proxy IP adresas (Pvz. IPv4: 127.0.0.1 / IPv6: ::1)</translation> + </message> + <message> + <source>&Reset Options</source> + <translation>&Atstatyti Parinktis</translation> + </message> + <message> <source>&Network</source> <translation>&Tinklas</translation> </message> <message> + <source>W&allet</source> + <translation>Piniginė</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>Automatiškai atidaryti Bitcoin kliento prievadą maršrutizatoriuje. Tai veikia tik tada, kai jūsų maršrutizatorius palaiko UPnP ir ji įjungta.</translation> </message> @@ -687,6 +718,18 @@ <translation>Tarpinio serverio preivadas (pvz, 9050)</translation> </message> <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> <source>&Window</source> <translation>&Langas</translation> </message> @@ -739,6 +782,14 @@ <translation>Patvirtinti nustatymų atstatymą</translation> </message> <message> + <source>Client restart required to activate changes.</source> + <translation>Kliento perkrovimas reikalingas nustatymų aktyvavimui</translation> + </message> + <message> + <source>This change would require a client restart.</source> + <translation>Šis pakeitimas reikalautų kliento perkrovimo</translation> + </message> + <message> <source>The supplied proxy address is invalid.</source> <translation>Nurodytas tarpinio serverio adresas negalioja.</translation> </message> @@ -754,6 +805,10 @@ <translation>Galimi:</translation> </message> <message> + <source>Your current spendable balance</source> + <translation>Jūsų dabartinis išleidžiamas balansas</translation> + </message> + <message> <source>Pending:</source> <translation>Laukiantys:</translation> </message> @@ -777,10 +832,18 @@ <translation>URI apdorojimas</translation> </message> <message> + <source>Invalid payment address %1</source> + <translation>Neteisingas mokėjimo adresas %1</translation> + </message> + <message> <source>Payment request rejected</source> <translation>Mokėjimo siuntimas atmestas</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Mokėjimo siuntimas pasibaigė</translation> + </message> + <message> <source>Network request error</source> <translation>Tinklo užklausos klaida</translation> </message> @@ -810,10 +873,18 @@ <context> <name>QRImageWidget</name> <message> + <source>&Copy Image</source> + <translation>Kopijuoti nuotrauką</translation> + </message> + <message> <source>Save QR Code</source> <translation>Įrašyti QR kodą</translation> </message> - </context> + <message> + <source>PNG Image (*.png)</source> + <translation>PNG paveikslėlis (*.png)</translation> + </message> +</context> <context> <name>RPCConsole</name> <message> @@ -833,6 +904,10 @@ <translation>&Informacija</translation> </message> <message> + <source>Debug window</source> + <translation>Derinimo langas</translation> + </message> + <message> <source>Using OpenSSL version</source> <translation>Naudojama OpenSSL versija</translation> </message> @@ -845,6 +920,10 @@ <translation>Tinklas</translation> </message> <message> + <source>Name</source> + <translation>Pavadinimas</translation> + </message> + <message> <source>Number of connections</source> <translation>Prisijungimų kiekis</translation> </message> @@ -869,14 +948,6 @@ <translation>Versija</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Nusiųsti baitai</translation> - </message> - <message> - <source>Bytes Received</source> - <translation>Gauti baitai</translation> - </message> - <message> <source>Last block time</source> <translation>Paskutinio bloko laikas</translation> </message> @@ -889,6 +960,10 @@ <translation>&Konsolė</translation> </message> <message> + <source>&Clear</source> + <translation>Išvalyti</translation> + </message> + <message> <source>Totals</source> <translation>Viso:</translation> </message> @@ -924,14 +999,30 @@ <source>never</source> <translation>Niekada</translation> </message> + <message> + <source>Yes</source> + <translation>Taip</translation> + </message> + <message> + <source>No</source> + <translation>Ne</translation> + </message> </context> <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>Suma:</translation> + </message> + <message> <source>&Label:</source> <translation>Ž&ymė:</translation> </message> <message> + <source>&Message:</source> + <translation>Žinutė:</translation> + </message> + <message> <source>Clear</source> <translation>Išvalyti</translation> </message> @@ -951,6 +1042,10 @@ <translation>QR kodas</translation> </message> <message> + <source>Copy &Address</source> + <translation>&Kopijuoti adresą</translation> + </message> + <message> <source>Payment information</source> <translation>Mokėjimo informacija</translation> </message> @@ -1005,6 +1100,10 @@ <translation>Siųsti monetas</translation> </message> <message> + <source>Insufficient funds!</source> + <translation>Nepakanka lėšų</translation> + </message> + <message> <source>Quantity:</source> <translation>Kiekis:</translation> </message> @@ -1033,6 +1132,10 @@ <translation>Graža:</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Sandorio mokestis:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Siųsti keliems gavėjams vienu metu</translation> </message> @@ -1097,6 +1200,10 @@ <translation>Jei pridedame sandorio mokestį %1 bendra suma viršija jūsų balansą.</translation> </message> <message> + <source>Payment request expired.</source> + <translation>Mokėjimo siuntimas pasibaigė</translation> + </message> + <message> <source>(no label)</source> <translation>(nėra žymės)</translation> </message> @@ -1135,6 +1242,10 @@ <source>Message:</source> <translation>Žinutė:</translation> </message> + <message> + <source>Pay To:</source> + <translation>Mokėti gavėjui:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -1182,6 +1293,10 @@ <translation>Patikrinkite žinutę, jog įsitikintumėte, kad ją pasirašė nurodytas Bitcoin adresas</translation> </message> <message> + <source>Verify &Message</source> + <translation>&Patikrinti žinutę</translation> + </message> + <message> <source>Click "Sign Message" to generate signature</source> <translation>Spragtelėkite "Registruotis žinutę" tam, kad gauti parašą</translation> </message> @@ -1615,14 +1730,6 @@ <translation>Dirbti fone kaip šešėlyje ir priimti komandas</translation> </message> <message> - <source>Use the test network</source> - <translation>Naudoti testavimo tinklą</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>Įspėjimas: -paytxfee yra nustatytas per didelis. Tai sandorio mokestis, kurį turėsite mokėti, jei siųsite sandorį.</translation> - </message> - <message> <source>Connect only to the specified node(s)</source> <translation>Prisijungti tik prie nurodyto mazgo</translation> </message> @@ -1643,20 +1750,20 @@ <translation>Informacija</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> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Neteisinga suma -maxtxfee=<amount>: '%s'</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Nustatyti kalbą, pavyzdžiui "lt_LT" (numatyta: sistemos kalba)</translation> + <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> + <translation>Neteisinga suma -minrelaytxfee=<amount>: '%s'</translation> </message> <message> - <source>Start minimized</source> - <translation>Paleisti sumažintą</translation> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>Neteisinga suma -mintxfee=<amount>: '%s'</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> + <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>Username for JSON-RPC connections</source> @@ -1671,18 +1778,6 @@ <translation>Slaptažodis JSON-RPC sujungimams</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Atnaujinti piniginę į naujausią formatą</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Naudoti OpenSSL (https) jungimuisi JSON-RPC </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 23b846bd49..e01d4c812c 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.0"> +<TS language="lv_LV" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -62,6 +62,14 @@ <translation>Saņemšanas adreses</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>Šīs ir jūsu Bitcoin adreses maksājumu sūtīšanai. Vienmēr pārbaudiet summu un saņēmēja adresi pirms monētu sūtīšanas.</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>Šīs ir jūsu Bitcoin adreses maksājumu saņemšanai. Ir ieteicams katram darījumam izmantot jaunu saņemšanas adresi.</translation> + </message> + <message> <source>Copy &Label</source> <translation>Kopēt &Nosaukumu</translation> </message> @@ -81,7 +89,11 @@ <source>Exporting Failed</source> <translation>Eksportēšana Neizdevās</translation> </message> - </context> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Radās kļūda, saglabājot adrešu sarakstu %1. Lūdzu, mēģiniet vēlreiz!</translation> + </message> +</context> <context> <name>AddressTableModel</name> <message> @@ -152,6 +164,14 @@ <translation>Vai tu tiešām vēlies šifrēt savu maciņu?</translation> </message> <message> + <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Bitcoin Core tiks aizvērts, lai pabeigtu šifrēšansa procesu. Atcerieties, ka jūsu maka šifrēšana nevar pilnībā pasargāt jūsu monētas no to nozagašanas, inficējot datoru ar ļaunprātīgām programmām.</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>SVARĪGI: Iepriekšējie maka faila dublējumi ir jāaizvieto ar jauno, šifrēto maka failu. Drošības apsvērumu dēļ iepriekšējie nešifrētā maka dublējumi vairs nebūs derīgi, tiklīdz sāksiet izmantot jauno, šifrēto maku.</translation> + </message> + <message> <source>Warning: The Caps Lock key is on!</source> <translation>Brīdinājums: Caps Lock ir ieslēgts!</translation> </message> @@ -160,6 +180,10 @@ <translation>Maciņš nošifrēts</translation> </message> <message> + <source>Enter the old passphrase and new passphrase to the wallet.</source> + <translation>Ievadiet veco un jauno maka paroli.</translation> + </message> + <message> <source>Wallet encryption failed</source> <translation>Maciņa šifrēšana neizdevās</translation> </message> @@ -189,6 +213,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -694,6 +721,10 @@ <translation>Par Bitcoin Core</translation> </message> <message> + <source>Command-line options</source> + <translation>Komandrindas iespējas</translation> + </message> + <message> <source>Usage:</source> <translation>Lietojums:</translation> </message> @@ -701,7 +732,7 @@ <source>command-line options</source> <translation>komandrindas izvēles</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -775,10 +806,18 @@ <translation>Skriptu &pārbaudes pavedienu skaits</translation> </message> <message> + <source>Allow incoming connections</source> + <translation>Atļaut ienākošos savienojumus</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> <message> + <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> + <translation>Minimizēt nevis aizvērt aplikāciju, kad logs tiek aizvērts. Kad šī iespēja ir ieslēgta, aplikācija tiks aizvērta, izvēloties Aizvērt izvēlnē.</translation> + </message> + <message> <source>Third party transaction URLs</source> <translation>Trešo personu transakciju URLs</translation> </message> @@ -945,6 +984,14 @@ <translation>Nederīga maksājuma adrese %1</translation> </message> <message> + <source>Payment request rejected</source> + <translation>Maksājuma pieprasījums noraidīts</translation> + </message> + <message> + <source>Payment request network doesn't match client network.</source> + <translation>Maksājuma pieprasījuma tīkls neatbilst klienta tīklam.</translation> + </message> + <message> <source>Payment request error</source> <translation>Maksājumu pieprasījuma kļūda</translation> </message> @@ -1333,6 +1380,10 @@ <translation>Pielāgota atlikuma adrese</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Transakcijas maksa:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Sūtīt vairākiem saņēmējiem uzreiz</translation> </message> @@ -1397,10 +1448,6 @@ <translation>Kopēt atlikumu</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Kopējā Summa %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>vai</translation> </message> @@ -2075,22 +2122,10 @@ <translation>Darbināt fonā kā servisu un pieņemt komandas</translation> </message> <message> - <source>Use the test network</source> - <translation>Izmantot testa tīklu</translation> - </message> - <message> - <source>(default: 1)</source> - <translation>(noklusējums: 1)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> var būt:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Mēģināt atgūt privātās atslēgas no bojāta wallet.dat</translation> - </message> - <message> <source>Block creation options:</source> <translation>Bloka izveidošanas iestatījumi:</translation> </message> @@ -2115,10 +2150,6 @@ <translation>Kļūda: Zema diska vieta!</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> - <message> <source>Importing...</source> <translation>Importē...</translation> </message> @@ -2135,38 +2166,38 @@ <translation>Maciņa iespējas:</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importēt blokus no ārējās blk000??.dat datnes</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Nevar atrisināt -whitebind adresi: '%s'</translation> </message> <message> <source>Information</source> <translation>Informācija</translation> </message> <message> - <source>RPC server options:</source> - <translation>RPC servera iestatījumi:</translation> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Nederīgs daudzums priekš -maxtxfee=<amount>: '%s'</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Debug/trace informāciju izvadīt konsolē, nevis debug.log failā</translation> + <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> + <translation>Nederīgs daudzums priekš -minrelaytxfee=<amount>: '%s'</translation> + </message> + <message> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>Nederīgs daudzums priekš -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Uzstādiet valodu, piemēram "de_DE" (pēc noklusēšanas: sistēmas lokāle)</translation> + <source>RPC server options:</source> + <translation>RPC servera iestatījumi:</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Uzsākot, parādīt programmas informācijas logu (pēc noklusēšanas: 1)</translation> + <source>Send trace/debug info to console instead of debug.log file</source> + <translation>Debug/trace informāciju izvadīt konsolē, nevis debug.log failā</translation> </message> <message> <source>Signing transaction failed</source> <translation>Transakcijas parakstīšana neizdevās</translation> </message> <message> - <source>Start minimized</source> - <translation>Sākt minimizētu</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Transakcijas summa ir pārāk maza</translation> </message> @@ -2187,10 +2218,6 @@ <translation>Brīdinājums</translation> </message> <message> - <source>on startup</source> - <translation>startēšanas laikā</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat ir bojāts, glābšana neizdevās</translation> </message> @@ -2203,18 +2230,6 @@ <translation>Izpildīt komandu, kad labāk atbilstošais bloks izmainās (%s cmd aizvieto ar bloka hešu)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Atjaunot maciņa formātu uz jaunāko</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>JSON-RPC savienojumiem izmantot OpenSSL (https)</translation> - </message> - <message> <source>This help message</source> <translation>Šis palīdzības paziņojums</translation> </message> diff --git a/src/qt/locale/bitcoin_mk_MK.ts b/src/qt/locale/bitcoin_mk_MK.ts new file mode 100644 index 0000000000..b7797063b2 --- /dev/null +++ b/src/qt/locale/bitcoin_mk_MK.ts @@ -0,0 +1,1039 @@ +<TS language="mk_MK" version="2.1"> +<context> + <name>AddressBookPage</name> + <message> + <source>Right-click to edit address or label</source> + <translation>Десен клик за уредување на адреса или етикета</translation> + </message> + <message> + <source>Create a new address</source> + <translation>Креирај нова адреса</translation> + </message> + <message> + <source>&New</source> + <translation>&Нова</translation> + </message> + <message> + <source>Copy the currently selected address to the system clipboard</source> + <translation>Копирај ја избраната адреса на системскиот клипборд</translation> + </message> + <message> + <source>&Copy</source> + <translation>&Копирај</translation> + </message> + <message> + <source>C&lose</source> + <translation>З&атвори</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>&Копирај Адреса</translation> + </message> + <message> + <source>Delete the currently selected address from the list</source> + <translation>Избриши ја избраната адреса од листата</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Експортирај ги податоците од активното јазиче во датотека</translation> + </message> + <message> + <source>&Export</source> + <translation>&Експорт</translation> + </message> + <message> + <source>&Delete</source> + <translation>&Избриши</translation> + </message> + <message> + <source>Choose the address to send coins to</source> + <translation>Изберете адресата за да пратите биткоини</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>Изберете адресата за да примите биткоини</translation> + </message> + <message> + <source>C&hoose</source> + <translation>И&збери</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Адреси за праќање</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Адреси за примање</translation> + </message> + <message> + <source>Copy &Label</source> + <translation>Копирај &Етикета</translation> + </message> + <message> + <source>&Edit</source> + <translation>&Уреди</translation> + </message> + <message> + <source>Export Address List</source> + <translation>Експортирај Листа со Адреси</translation> + </message> + <message> + <source>Exporting Failed</source> + <translation>Експортирањето не Успеа</translation> + </message> + </context> +<context> + <name>AddressTableModel</name> + <message> + <source>Label</source> + <translation>Етикета</translation> + </message> + <message> + <source>Address</source> + <translation>Адреса</translation> + </message> + <message> + <source>(no label)</source> + <translation>(без етикета)</translation> + </message> +</context> +<context> + <name>AskPassphraseDialog</name> + <message> + <source>Enter passphrase</source> + <translation>Внеси тајна фраза</translation> + </message> + <message> + <source>New passphrase</source> + <translation>Нова тајна фраза</translation> + </message> + <message> + <source>Repeat new passphrase</source> + <translation>Повторете ја новата тајна фраза</translation> + </message> + <message> + <source>Encrypt wallet</source> + <translation>Криптирање на паричник</translation> + </message> + <message> + <source>Unlock wallet</source> + <translation>Отклучи паричник</translation> + </message> + <message> + <source>Decrypt wallet</source> + <translation>Декриптирање на паричник</translation> + </message> + <message> + <source>Change passphrase</source> + <translation>Измени тајна фраза</translation> + </message> + <message> + <source>Confirm wallet encryption</source> + <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> + <message> + <source>Wallet encryption failed</source> + <translation>Криптирањето на паричникот е неуспешно</translation> + </message> + <message> + <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source> + <translation>Криптирањето на паричникот не успеа поради интерна грешка. Вашиот паричник не е криптиран.</translation> + </message> + <message> + <source>The supplied passphrases do not match.</source> + <translation>Приложените тајни фрази не се поклопуваат</translation> + </message> + <message> + <source>Wallet unlock failed</source> + <translation>Отклучувањето на паричникот е неуспешно</translation> + </message> + <message> + <source>The passphrase entered for the wallet decryption was incorrect.</source> + <translation>Тајната фраза која што ја внесовте за декриптирање на паричникот е неточна.</translation> + </message> + <message> + <source>Wallet decryption failed</source> + <translation>Декриптирањето на паричникот е неуспешно</translation> + </message> + <message> + <source>Wallet passphrase was successfully changed.</source> + <translation>Тајната фраза е успешно променета.</translation> + </message> +</context> +<context> + <name>BanTableModel</name> + </context> +<context> + <name>BitcoinGUI</name> + <message> + <source>Sign &message...</source> + <translation>Потпиши &порака...</translation> + </message> + <message> + <source>Synchronizing with network...</source> + <translation>Синхронизација со мрежата...</translation> + </message> + <message> + <source>&Overview</source> + <translation>&Преглед</translation> + </message> + <message> + <source>Node</source> + <translation>Јазол</translation> + </message> + <message> + <source>&Transactions</source> + <translation>&Трансакции</translation> + </message> + <message> + <source>Browse transaction history</source> + <translation>Преглед на историјата на трансакции</translation> + </message> + <message> + <source>E&xit</source> + <translation>И&злез</translation> + </message> + <message> + <source>Quit application</source> + <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> + <message> + <source>&Receiving addresses...</source> + <translation>&Адреси за Примање...</translation> + </message> + <message> + <source>Open &URI...</source> + <translation>Отвори &URI...</translation> + </message> + <message> + <source>Bitcoin Core client</source> + <translation>Биткоин Core софтверот</translation> + </message> + <message> + <source>Importing blocks from disk...</source> + <translation>Внесување на блокови од дискот...</translation> + </message> + <message> + <source>Reindexing blocks on disk...</source> + <translation>Повторно индексирање на блокови од дискот...</translation> + </message> + <message> + <source>Send coins to a Bitcoin address</source> + <translation>Испрати биткоини на Биткоин адреса</translation> + </message> + <message> + <source>&Verify message...</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>Show information about Bitcoin Core</source> + <translation>Прикажи информации за Биткоин Core</translation> + </message> + <message> + <source>&Show / Hide</source> + <translation>&Прикажи / Сокриј</translation> + </message> + <message> + <source>Encrypt the private keys that belong to your wallet</source> + <translation>Криптирај ги приватните клучеви кои припаѓаат на твојот паричник</translation> + </message> + <message> + <source>&Settings</source> + <translation>&Подесувања</translation> + </message> + <message> + <source>&Help</source> + <translation>&Помош</translation> + </message> + <message> + <source>Bitcoin Core</source> + <translation>Биткоин Core</translation> + </message> + <message> + <source>&About Bitcoin Core</source> + <translation>&За Биткоин Core</translation> + </message> + <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>Обработен %n блок од историјата на трансакции.</numerusform><numerusform>Обработени %n блокови од историјата на трансакции.</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n час</numerusform><numerusform>%n часови</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n ден</numerusform><numerusform>%n денови</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n недела</numerusform><numerusform>%n недели</numerusform></translation> + </message> + <message> + <source>%1 and %2</source> + <translation>%1 и %2</translation> + </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n година</numerusform><numerusform>%n години</numerusform></translation> + </message> + <message> + <source>%1 behind</source> + <translation>%1 позади</translation> + </message> + <message> + <source>Error</source> + <translation>Грешка</translation> + </message> + <message> + <source>Warning</source> + <translation>Предупредување</translation> + </message> + <message> + <source>Up to date</source> + <translation>Во тек</translation> + </message> + <message> + <source>Date: %1 +</source> + <translation>Дата: %1 +</translation> + </message> + <message> + <source>Amount: %1 +</source> + <translation>Сума: %1 +</translation> + </message> + <message> + <source>Type: %1 +</source> + <translation>Тип: %1 +</translation> + </message> + <message> + <source>Label: %1 +</source> + <translation>Етикета: %1 +</translation> + </message> + <message> + <source>Address: %1 +</source> + <translation>Адреса: %1 +</translation> + </message> + </context> +<context> + <name>ClientModel</name> + </context> +<context> + <name>CoinControlDialog</name> + <message> + <source>Bytes:</source> + <translation>Бајти:</translation> + </message> + <message> + <source>Amount:</source> + <translation>Сума:</translation> + </message> + <message> + <source>Priority:</source> + <translation>Приоритет:</translation> + </message> + <message> + <source>Fee:</source> + <translation>Провизија:</translation> + </message> + <message> + <source>Dust:</source> + <translation>Прашина:</translation> + </message> + <message> + <source>After Fee:</source> + <translation>После Провизија:</translation> + </message> + <message> + <source>Change:</source> + <translation>Кусур:</translation> + </message> + <message> + <source>Amount</source> + <translation>Сума</translation> + </message> + <message> + <source>Date</source> + <translation>Дата</translation> + </message> + <message> + <source>Priority</source> + <translation>Приоритет</translation> + </message> + <message> + <source>Copy address</source> + <translation>Копирај адреса</translation> + </message> + <message> + <source>Copy label</source> + <translation>Копирај етикета</translation> + </message> + <message> + <source>Copy amount</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>none</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 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>yes</source> + <translation>да</translation> + </message> + <message> + <source>no</source> + <translation>не</translation> + </message> + <message> + <source>Transactions with higher priority are more likely to get included into a block.</source> + <translation>Трансакциите со повисок приоритет имаат поголеми шанси да бидат вклучени во блок.</translation> + </message> + <message> + <source>(no label)</source> + <translation>(без етикета)</translation> + </message> + <message> + <source>(change)</source> + <translation>(кусур)</translation> + </message> +</context> +<context> + <name>EditAddressDialog</name> + <message> + <source>Edit Address</source> + <translation>Измени Адреса</translation> + </message> + <message> + <source>&Label</source> + <translation>&Етикета</translation> + </message> + <message> + <source>&Address</source> + <translation>&Адреса</translation> + </message> + </context> +<context> + <name>FreespaceChecker</name> + <message> + <source>name</source> + <translation>име</translation> + </message> + </context> +<context> + <name>HelpMessageDialog</name> + <message> + <source>Bitcoin Core</source> + <translation>Биткоин Core</translation> + </message> + <message> + <source>version</source> + <translation>верзија</translation> + </message> + <message> + <source>(%1-bit)</source> + <translation>(%1-бит)</translation> + </message> + <message> + <source>About Bitcoin Core</source> + <translation>За Биткоин Core</translation> + </message> + </context> +<context> + <name>Intro</name> + <message> + <source>Bitcoin Core</source> + <translation>Биткоин Core</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>URI:</source> + <translation>URI:</translation> + </message> + </context> +<context> + <name>OptionsDialog</name> + <message> + <source>Options</source> + <translation>Опции</translation> + </message> + <message> + <source>MB</source> + <translation>МБ</translation> + </message> + <message> + <source>&Network</source> + <translation>&Мрежа</translation> + </message> + <message> + <source>W&allet</source> + <translation>П&аричник</translation> + </message> + <message> + <source>&Window</source> + <translation>&Прозорец</translation> + </message> + <message> + <source>&OK</source> + <translation>&ОК</translation> + </message> + <message> + <source>&Cancel</source> + <translation>&Откажи</translation> + </message> + <message> + <source>none</source> + <translation>нема</translation> + </message> + </context> +<context> + <name>OverviewPage</name> + <message> + <source>Total:</source> + <translation>Вкупно:</translation> + </message> + </context> +<context> + <name>PaymentServer</name> + </context> +<context> + <name>PeerTableModel</name> + </context> +<context> + <name>QObject</name> + <message> + <source>Amount</source> + <translation>Сума</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>%1 ms</source> + <translation>%1 мс</translation> + </message> +</context> +<context> + <name>QRImageWidget</name> + <message> + <source>&Save 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>Network</source> + <translation>Мрежа</translation> + </message> + <message> + <source>Name</source> + <translation>Име</translation> + </message> + <message> + <source>Number of connections</source> + <translation>Број на конекции</translation> + </message> + <message> + <source>Block chain</source> + <translation>Block chain</translation> + </message> + <message> + <source>Sent</source> + <translation>Испратени</translation> + </message> + <message> + <source>Version</source> + <translation>Верзија</translation> + </message> + <message> + <source>&Console</source> + <translation>&Конзола</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> + </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>Show</source> + <translation>Прикажи</translation> + </message> + <message> + <source>Copy label</source> + <translation>Копирај етикета</translation> + </message> + <message> + <source>Copy message</source> + <translation>Копирај порака</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Копирај сума</translation> + </message> +</context> +<context> + <name>ReceiveRequestDialog</name> + <message> + <source>QR Code</source> + <translation>QR Код</translation> + </message> + <message> + <source>Copy &URI</source> + <translation>Копирај &URI</translation> + </message> + <message> + <source>Copy &Address</source> + <translation>Копирај &Адреса</translation> + </message> + <message> + <source>&Save Image...</source> + <translation>&Сними Слика...</translation> + </message> + <message> + <source>URI</source> + <translation>URI</translation> + </message> + <message> + <source>Address</source> + <translation>Адреса</translation> + </message> + <message> + <source>Amount</source> + <translation>Сума</translation> + </message> + <message> + <source>Label</source> + <translation>Етикета</translation> + </message> + <message> + <source>Message</source> + <translation>Порака</translation> + </message> + </context> +<context> + <name>RecentRequestsTableModel</name> + <message> + <source>Date</source> + <translation>Дата</translation> + </message> + <message> + <source>Label</source> + <translation>Етикета</translation> + </message> + <message> + <source>Message</source> + <translation>Порака</translation> + </message> + <message> + <source>Amount</source> + <translation>Сума</translation> + </message> + <message> + <source>(no label)</source> + <translation>(без етикета)</translation> + </message> + </context> +<context> + <name>SendCoinsDialog</name> + <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>Dust:</source> + <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>(no label)</source> + <translation>(без етикета)</translation> + </message> + <message> + <source>Copy dust</source> + <translation>Копирај прашина</translation> + </message> + </context> +<context> + <name>SendCoinsEntry</name> + <message> + <source>A&mount:</source> + <translation>Сума:</translation> + </message> + <message> + <source>&Label:</source> + <translation>&Етикета:</translation> + </message> + <message> + <source>Message:</source> + <translation>Порака:</translation> + </message> + </context> +<context> + <name>ShutdownWindow</name> + </context> +<context> + <name>SignVerifyMessageDialog</name> + </context> +<context> + <name>SplashScreen</name> + <message> + <source>Bitcoin Core</source> + <translation>Биткоин Core</translation> + </message> + </context> +<context> + <name>TrafficGraphWidget</name> + </context> +<context> + <name>TransactionDesc</name> + <message> + <source>Date</source> + <translation>Дата</translation> + </message> + <message> + <source>Message</source> + <translation>Порака</translation> + </message> + <message> + <source>Amount</source> + <translation>Сума</translation> + </message> + </context> +<context> + <name>TransactionDescDialog</name> + </context> +<context> + <name>TransactionTableModel</name> + <message> + <source>Date</source> + <translation>Дата</translation> + </message> + <message> + <source>Label</source> + <translation>Етикета</translation> + </message> + </context> +<context> + <name>TransactionView</name> + <message> + <source>Copy address</source> + <translation>Копирај Адреса</translation> + </message> + <message> + <source>Copy label</source> + <translation>Копирај етикета</translation> + </message> + <message> + <source>Copy amount</source> + <translation>Копирај сума</translation> + </message> + <message> + <source>Exporting Failed</source> + <translation>Експортирањето не Успеа</translation> + </message> + <message> + <source>Date</source> + <translation>Дата</translation> + </message> + <message> + <source>Label</source> + <translation>Етикета</translation> + </message> + <message> + <source>Address</source> + <translation>Адреса</translation> + </message> + </context> +<context> + <name>UnitDisplayStatusBarControl</name> + </context> +<context> + <name>WalletFrame</name> + </context> +<context> + <name>WalletModel</name> + </context> +<context> + <name>WalletView</name> + <message> + <source>&Export</source> + <translation>&Експорт</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Експортирај ги податоците од активното јазиче во датотека</translation> + </message> + </context> +<context> + <name>bitcoin-core</name> + <message> + <source>Options:</source> + <translation>Опции:</translation> + </message> + <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_mn.ts b/src/qt/locale/bitcoin_mn.ts index 73793482d6..b790010066 100644 --- a/src/qt/locale/bitcoin_mn.ts +++ b/src/qt/locale/bitcoin_mn.ts @@ -1,4 +1,4 @@ -<TS language="mn" version="2.0"> +<TS language="mn" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -50,6 +50,10 @@ <translation>Зооснуудыг хүлээн авах хаягийг сонгоно уу</translation> </message> <message> + <source>C&hoose</source> + <translation>С&онго</translation> + </message> + <message> <source>Sending addresses</source> <translation>Илгээх хаягууд</translation> </message> @@ -173,6 +177,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -227,6 +234,10 @@ <translation>&Нууц Үгийг Солих...</translation> </message> <message> + <source>&Receiving addresses...</source> + <translation>Хүлээн авах хаяг</translation> + </message> + <message> <source>Change the passphrase used for wallet encryption</source> <translation>Түрүйвчийг цоожлох нууц үгийг солих</translation> </message> @@ -263,6 +274,10 @@ <translation>Алдаа</translation> </message> <message> + <source>Information</source> + <translation>Мэдээллэл</translation> + </message> + <message> <source>Up to date</source> <translation>Шинэчлэгдсэн</translation> </message> @@ -415,6 +430,14 @@ <translation>проксигийн IP хаяг (жишээ нь: IPv4: 127.0.0.1 / IPv6: ::1)</translation> </message> <message> + <source>&Network</source> + <translation>Сүлжээ</translation> + </message> + <message> + <source>W&allet</source> + <translation>Түрүйвч</translation> + </message> + <message> <source>Client restart required to activate changes.</source> <translation>Ѳѳрчлѳлтүүдийг идэвхижүүлхийн тулд клиентийг ахин эхлүүлэх шаардлагтай</translation> </message> @@ -516,10 +539,18 @@ <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>Show</source> <translation>Харуул</translation> </message> @@ -547,6 +578,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>Хаягийг &Хуулбарлах</translation> + </message> + <message> <source>Address</source> <translation>Хаяг</translation> </message> @@ -649,10 +684,6 @@ <translation>Ѳѳрчлѳлтийг санах</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Нийт дүн %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>эсвэл</translation> </message> @@ -711,6 +742,10 @@ <source>Message:</source> <translation>Зурвас:</translation> </message> + <message> + <source>Pay To:</source> + <translation>Тѳлѳх хаяг:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -1031,8 +1066,8 @@ <translation>Түрүйвчийн сонголтууд:</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Түрүйвчийг хамгийн сүүлийн үеийн форматруу шинэчлэх</translation> + <source>Information</source> + <translation>Мэдээллэл</translation> </message> <message> <source>Loading addresses...</source> diff --git a/src/qt/locale/bitcoin_ms_MY.ts b/src/qt/locale/bitcoin_ms_MY.ts index 5e10c80aff..df98dd8396 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.0"> +<TS language="ms_MY" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -57,6 +57,9 @@ <name>AskPassphraseDialog</name> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>&Options...</source> @@ -119,6 +122,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>&Salin Alamat</translation> + </message> + <message> <source>Address</source> <translation>Alamat</translation> </message> diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 385f038d46..9236ac86fe 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -1,4 +1,4 @@ -<TS language="nb" version="2.0"> +<TS language="nb" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/Nettmaske</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Utestengt til</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -871,6 +882,34 @@ <source>command-line options</source> <translation>kommandolinjevalg</translation> </message> + <message> + <source>UI Options:</source> + <translation>Grensesnittvalg:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Velg datakatalog for oppstart (default: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Sett språk, for eksempel "nb_NO" (default: system-«locale»)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Begynn minimert</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Sett SSL-rootsertifikat for betalingshenvendelser (default: -system-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Vis velkomstbilde ved oppstart (default: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Nullstill alle oppsettendringer gjort via det grafiske grensesnittet</translation> + </message> </context> <context> <name>Intro</name> @@ -1069,6 +1108,34 @@ <translation>Proxyens port (f.eks. 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Brukt for å nå noder via:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Viser om angitt SOCKS5 mellomtjener blir brukt for å nå noder via denne nettverkstypen.</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Koble til Bitcoin-nettverket gjennom en separat SOCKS5 mellomtjener for Tor skjulte tjenester.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Bruk separat SOCKS5 mellomtjener for å nå noder via Tor skjulte tjenester:</translation> + </message> + <message> <source>&Window</source> <translation>&Vindu</translation> </message> @@ -1287,10 +1354,6 @@ <translation>Betalingsforespørsel %1 er for stor (%2 bytes, tillatt %3 bytes).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Betalingsforespørsel DoS-beskyttelse</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Feil i kommunikasjonen med %1: %2</translation> </message> @@ -1443,6 +1506,18 @@ <translation>Nåværende antall blokker</translation> </message> <message> + <source>Memory Pool</source> + <translation>Minnepool</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>Nåværende antall transaksjoner</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Minnebruk</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>Åpne Bitcoin Core sin loggfil for feilsøk fra gjeldende datamappe. Dette kan ta noen sekunder for store loggfiler.</translation> </message> @@ -1459,10 +1534,18 @@ <translation>&Noder</translation> </message> <message> + <source>Banned peers</source> + <translation>Utestengte noder</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Velg en node for å vise detaljert informasjon.</translation> </message> <message> + <source>Whitelisted</source> + <translation>Hvitelistet</translation> + </message> + <message> <source>Direction</source> <translation>Retning</translation> </message> @@ -1471,20 +1554,24 @@ <translation>Versjon</translation> </message> <message> - <source>User Agent</source> - <translation>Brukeragent</translation> + <source>Starting Block</source> + <translation>Startblokk</translation> </message> <message> - <source>Services</source> - <translation>Tjenester</translation> + <source>Synced Headers</source> + <translation>Synkroniserte Blokkhoder</translation> </message> <message> - <source>Starting Height</source> - <translation>Starthøyde</translation> + <source>Synced Blocks</source> + <translation>Synkroniserte Blokker</translation> </message> <message> - <source>Sync Height</source> - <translation>Synkroniseringshøyde</translation> + <source>User Agent</source> + <translation>Brukeragent</translation> + </message> + <message> + <source>Services</source> + <translation>Tjenester</translation> </message> <message> <source>Ban Score</source> @@ -1503,16 +1590,16 @@ <translation>Siste Mottatte</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Byte Sendt</translation> + <source>Ping Time</source> + <translation>Ping-tid</translation> </message> <message> - <source>Bytes Received</source> - <translation>Byte Mottatt</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>Tidsforløp for utestående ping.</translation> </message> <message> - <source>Ping Time</source> - <translation>Ping-tid</translation> + <source>Ping Wait</source> + <translation>Ping Tid</translation> </message> <message> <source>Time Offset</source> @@ -1563,6 +1650,34 @@ <translation>Tøm konsoll</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>&Koble fra node</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Steng node ute for</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &time</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &dag</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &uke</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &år</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>Fjern &Utestengning av Node</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Velkommen til Bitcoin Core sin RPC-konsoll.</translation> </message> @@ -1591,6 +1706,10 @@ <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(node id: %1)</translation> + </message> + <message> <source>via %1</source> <translation>via %1</translation> </message> @@ -1607,12 +1726,16 @@ <translation>Utgående</translation> </message> <message> - <source>Unknown</source> - <translation>Ukjent</translation> + <source>Yes</source> + <translation>Ja</translation> </message> <message> - <source>Fetching...</source> - <translation>Henter …</translation> + <source>No</source> + <translation>Nei</translation> + </message> + <message> + <source>Unknown</source> + <translation>Ukjent</translation> </message> </context> <context> @@ -1979,8 +2102,8 @@ <translation>Kopier veksel</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Totalt Beløp %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Totalt Beløp %1</translation> </message> <message> <source>or</source> @@ -2014,15 +2137,15 @@ <source>Payment request expired.</source> <translation>Betalingsetterspørringen har utløpt.</translation> </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>Betal kun påkrevd gebyr på %1</translation> + </message> <message numerus="yes"> <source>Estimated to begin confirmation within %n block(s).</source> <translation><numerusform>Anslått til å begynne bekreftelse innen %n blokk.</numerusform><numerusform>Anslått til å begynne bekreftelse innen %n blokker.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Betal kun minimumsgebyret på %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>Mottakeradressen er ikke gyldig. Vennligst kontroller på nytt.</translation> </message> @@ -2654,6 +2777,10 @@ <translation>Kopier transaksjons-ID</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>Kopier råtransaksjon</translation> + </message> + <message> <source>Edit label</source> <translation>Rediger merkelapp</translation> </message> @@ -2801,12 +2928,52 @@ <translation>Ta imot kommandolinje- og JSON-RPC-kommandoer</translation> </message> <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>Hvis <category> ikke er oppgitt eller hvis <category> = 1, ta ut all informasjon for feilsøking.</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Maksimalt samlede gebyrer (i %s) til å bruke i en enkelt lommeboktransaksjon; settes dette for lavt kan store transaksjoner kanskje avbrytes (standardverdi: %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>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>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>Beskjæringsmodus er konfigurert under minimum på %d MiB. Vennligst bruk et høyere nummer.</translation> + </message> + <message> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation>Beskjæring: siste lommeboksynkronisering går utenfor beskjærte data. Du må bruke -reindex (laster ned hele blokkjeden igjen for beskjærte noder)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Reduser lagringsbehovet ved beskjæring (sletting) av gamle blokker. Denne modusen er ikke kompatibel med -txindex og -rescan. Advarsel: Tilbakestilling av denne innstillingen krever at hele blokkjeden må lastes ned på nytt. (Standardverdi: 0 = deaktiver beskjæring av blokker, >%u = mål for størrelse i MiB å bruke for blokkfiler)</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>Omsøk er ikke mulig i beskjært modus. Du vil måtte bruke -reindex som vil laste nede hele blokkjeden på nytt.</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Feil: En fatal intern feil oppstod, se debug.log for detaljer</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Gebyr (i %s/kB) for å legge til i transaksjoner du sender (standardverdi: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Beskjærer blokklageret...</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>Kjør i bakgrunnen som daemon og ta imot kommandoer</translation> </message> <message> - <source>Use the test network</source> - <translation>Bruk testnettverket</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>Kunne ikke starte HTTP server. Se debug logg for detaljer.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2829,18 +2996,14 @@ <translation>Kjør kommando når en lommeboktransaksjon endres (%s i kommando er erstattet med TxID)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Maksimalt samlede gebyrer til å bruke i en enkelt lommeboktransaksjon; settes dette for lavt kan store transaksjoner kanskje avbrytes (standardverdi: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Reduser lagringsbehovet ved beskjæring (slette) gamle blokker. Denne modusen deaktiverer støtte for lommebok og er ikke kompatibel med -txindex. Advarsel: Tilbakestilling av denne innstillingen krever at hele blokkjeden må lastes ned på nytt. (Standardverdi: 0 = deaktiver beskjæringsblokker, >%u = mål for størrelse i MiB å bruke for blokkfiler)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <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>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>Blokkdatabasen inneholder en blokk som ser ut til å være fra fremtiden. Dette kan være fordi dato og tid på din datamaskin er satt feil. Gjenopprett kun blokkdatabasen når du er sikker på at dato og tid er satt riktig.</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> @@ -2849,6 +3012,10 @@ <translation>Ute av stand til å binde til %s på denne datamaskinen. Bitcoin Core kjører sannsynligvis allerede.</translation> </message> <message> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>Bruk UPnP for lytteport (standardverdi: 1 ved lytting og uten -proxy)</translation> + </message> + <message> <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> <translation>ADVARSEL: unormalt høyt antall blokker generert, %d blokker mottatt de siste %d timene (%d forventet)</translation> </message> @@ -2857,10 +3024,6 @@ <translation>ADVARSEL: kontroller nettverkstilkoblingen, mottok %d blokker i de siste %d timene (%d forventet)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Advarsel: -paytxfee er satt veldig høyt! Dette er transaksjonsgebyret du betaler når du sender transaksjoner.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Advarsel: Nettverket ser ikke ut til å være enig! Noen minere ser ut til å ha problemer.</translation> </message> @@ -2869,10 +3032,6 @@ <translation>Advarsel: Vi ser ikke ut til å være enige med våre noder! Du må oppgradere, eller andre noder må oppgradere.</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>Advarsel: Feil ved lesing av wallet.dat! Alle nøkler lest riktig, men transaksjonsdataene eller oppføringer i adresseboken mangler kanskje eller er feil.</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>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> @@ -2881,18 +3040,14 @@ <translation>Hvitelist noder som kobler til fra den oppgitte nettmasken eller IP-adressen. Kan oppgis flere ganger.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(standardverdi: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool må være minst %d MB</translation> </message> <message> <source><category> can be:</source> <translation><category> kan være:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Forsøk å berge private nøkler fra en korrupt wallet.dat</translation> - </message> - <message> <source>Block creation options:</source> <translation>Valg for opprettelse av blokker:</translation> </message> @@ -2921,6 +3076,22 @@ <translation>Ønsker du å gjenopprette blokkdatabasen nå?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation>Slå på publish hash block i <address></translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>Slå på publish hash transaction i <address></translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>Slå på publisering av råblokk i <address></translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation>Slå på publisering av råtransaksjon i <address></translation> + </message> + <message> <source>Error initializing block database</source> <translation>Feil under initialisering av blokkdatabase</translation> </message> @@ -2937,10 +3108,6 @@ <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> @@ -2949,10 +3116,6 @@ <translation>Kunne ikke lytte på noen port. Bruk -listen=0 hvis det er dette du vil.</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> - <message> <source>Importing...</source> <translation>Importerer...</translation> </message> @@ -2965,6 +3128,10 @@ <translation>Ugyldig -onion adresse: '%s'</translation> </message> <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>Hold transaksjonsminnet under <n> megabytes (standard: %u)</translation> + </message> + <message> <source>Not enough file descriptors available.</source> <translation>For få fildeskriptorer tilgjengelig.</translation> </message> @@ -2993,10 +3160,26 @@ <translation>Angi lommebokfil (inne i datamappe)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Ustøttet argument -benchmark ble ignorert, bruk -debug=bench.</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Advarsel: Argumentet -debugnet er ikke støttet og ble ignorert, bruk -debug=net.</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>Feil: Argumentet -tor er ikke støttet, bruk -onion.</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>User Agent comment (%s) contains unsafe characters.</source> + <translation>User Agent kommentar (%s) inneholder utrygge tegn.</translation> + </message> + <message> <source>Verifying blocks...</source> <translation>Verifiserer blokker...</translation> </message> @@ -3021,18 +3204,10 @@ <translation>Du må gjenoppbygge databasen med å bruke -reindex for å endre -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importerer blokker fra ekstern fil 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>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> <message> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation>En feil oppstod under oppsett av RPC-adressen %s port %u for lytting: %s</translation> - </message> - <message> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> <translation>Bind til gitt adresse og hvitlist peers som kobler seg til den. Bruk [host]:port notasjon for IPv6</translation> </message> @@ -3057,16 +3232,12 @@ <translation>Feil: Lytting etter innkommende tilkoblinger feilet (lytting returnerte feil %s)</translation> </message> <message> - <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> - <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 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> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Gebyrer (i BTC/Kb) mindre enn dette anses som null gebyr for videresending (standardverdi: %s)</translation> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>Gebyrer (i %s/kB) mindre enn dette anses som null gebyr for videresending, graving og laging av transaksjoner (standardverdi: %s)</translation> </message> <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> @@ -3081,10 +3252,6 @@ <translation>Maksimal størrelse på data i databærende transaksjoner vi videresender og ufører graving på (standardverdi: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>Beskjæringsmodus er konfigurert under minimum på %d MB. Vennligst bruk et høyere nummer.</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Søk etter nodeadresser via DNS-oppslag, hvis vi har få adresser å koble til (standard: 1 med mindre -connect)</translation> </message> @@ -3109,38 +3276,6 @@ <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> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>For å bruke bitcoind, eller -server valget til bitcoin-qt, må du angi et rpcpassord i konfigurasjonsfilen: -%s -Det anbefales at du bruker det følgende tilfeldige passordet: -rpcuser=bitcoinrpc -rpcpassword=%s -(du behøver ikke å huske passordet) -Brukernavnet og passordet MÅ IKKE være like. -Om filen ikke eksisterer, opprett den med eier-kun-les filrettigheter. -Det er også anbefalt at å sette varselsmelding slik du får melding om problemer; -for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Advarsel: -paytxfee er satt veldig høyt! Så stort gebyr kan bli betalt ved en enkelt transaksjon.</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>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>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> @@ -3161,16 +3296,20 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aktiverer beste kjede...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>Kan ikke kjøre med en lommebok i beskjæringsmodus.</translation> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>Alltid videresend transaksjoner mottatt fra hvitlistede noder (standardverdi: %d)</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>Kan ikke løse -whitebind-adresse: '%s'</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Forsøk å berge private nøkler fra en korrupt wallet.dat ved oppstart</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Velg datamappe ved oppstart (standard: 0)</translation> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Automatisk opprette Tor skjult tjeneste (standardverdi: %d)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Kan ikke løse -whitebind-adresse: '%s'</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3181,10 +3320,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Copyright (C) 2009-%i utviklerne av Bitcoin Core</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Kunne ikke tolke -rpcbind-verdi %s som en nettverksadresse</translation> - </message> - <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Feil ved lasting av wallet.dat: Lommeboken krever en nyere versjon av Bitcoin Core</translation> </message> @@ -3193,12 +3328,8 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Feil ved lesing fra database, stenger ned.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Feil: Argumentet -tor er ikke støttet, bruk -onion.</translation> - </message> - <message> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation>Gebyr (i BTC/kB) for å legge til i transaksjoner du sender (standardverdi: %s)</translation> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Importerer blokker fra ekstern fil blk000??.dat ved oppstart</translation> </message> <message> <source>Information</source> @@ -3241,18 +3372,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Node alternativer for videresending:</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> - <message> <source>RPC server options:</source> <translation>Innstillinger for RPC-server:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>RPC-støtte for persistente HTTP-forbindelser (standardverdi: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Gjenopprett blokkjedeindeks fra gjeldende blk000??.dat filer ved oppstart</translation> </message> @@ -3261,30 +3384,26 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Motta og vis P2P nettverksvarsler (standardvalg: %u)</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> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> + <translation>Reduserer -maxconnections fra %d til %d, pga. systembegrensninger.</translation> </message> <message> - <source>Send transactions as zero-fee transactions if possible (default: %u)</source> - <translation>Send transaksjoner uten transaksjonsgebyr hvis mulig (standardverdi: %u)</translation> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Se gjennom blokkjeden etter manglende lommeboktransaksjoner ved oppstart</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Sett SSL-rotsertifikat for betalingsetterspørring (standard: -system-)</translation> + <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 language, for example "de_DE" (default: system locale)</source> - <translation>Sett språk, for eksempel "nb_NO" (standardverdi: fra operativsystem)</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> <translation>Vis alle feilsøkingsvalg (bruk: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Vis splashskjerm ved oppstart (standardverdi: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Krymp filen debug.log når klienten starter (standardverdi: 1 hvis uten -debug)</translation> </message> @@ -3293,10 +3412,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Signering av transaksjon feilet</translation> </message> <message> - <source>Start minimized</source> - <translation>Start minimert</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>Transaksjonsbeløpet er for lite til å betale gebyr</translation> </message> @@ -3305,6 +3420,14 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Dette er eksperimentell programvare.</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>Passord for Tor-kontrollport (standardverdi: tom)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>Tor-kontrollport å bruke hvis onion-lytting er aktivert (standardverdi: %s)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Transaksjonen er for liten</translation> </message> @@ -3321,16 +3444,12 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transaksjonen er for stor</translation> </message> <message> - <source>UI Options:</source> - <translation>Innstillinger for Brukergrensesnitt:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Kan ikke binde til %s på denne datamaskinen (binding returnerte feilen %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Bruk UPnP for lytteport (standardverdi: 1 ved lytting)</translation> + <source>Upgrade wallet to latest format on startup</source> + <translation>Oppgrader lommebok til nyeste format ved oppstart</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3345,20 +3464,16 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Advarsel</translation> </message> <message> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation>Advarsel: Argumentet -benchmark er ikke støttet og ble ignorert, bruk -debug=bench.</translation> - </message> - <message> - <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> - <translation>Advarsel: Argumentet -debugnet er ikke støttet og ble ignorert, bruk -debug=net.</translation> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>Hvorvidt å operere i modus med kun blokker (standardverdi: %u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> <translation>Zapper alle transaksjoner fra lommeboken...</translation> </message> <message> - <source>on startup</source> - <translation>ved oppstart</translation> + <source>ZeroMQ notification options:</source> + <translation>Valg for ZeroMQ-meldinger:</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3373,18 +3488,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Utfør kommando når beste blokk endrer seg (%s i kommandoen erstattes med blokkens hash)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Oppgrader lommebok til nyeste format</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Se gjennom blokkjeden etter manglende lommeboktransaksjoner</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Bruk OpenSSL (https) for JSON-RPC forbindelser</translation> - </message> - <message> <source>This help message</source> <translation>Denne hjelpemeldingen</translation> </message> @@ -3405,6 +3508,26 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = behold metadata for transaksjon som f. eks. kontoeier og informasjon om betalingsanmodning, 2 = dropp metadata for transaksjon)</translation> </message> <message> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>-maxtxfee er satt veldig høyt! Så stort gebyr kan bli betalt ved en enkelt transaksjon.</translation> + </message> + <message> + <source>-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> + <translation>-paytxfee er satt veldig høyt! Dette er transaksjonsgebyret du betaler når du sender transaksjoner.</translation> + </message> + <message> + <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>Ikke hold transaksjoner i minnet lenger enn <n> timer (standard: %u)</translation> + </message> + <message> + <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> + <translation>Feil ved lesing av wallet.dat! Alle nøkler lest riktig, men transaksjonsdataene eller oppføringer i adresseboken mangler kanskje eller er feil.</translation> + </message> + <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>Gebyrer (i %s/Kb) mindre enn dette anses som null gebyr for laging av transaksjoner (standardverdi: %s)</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> @@ -3421,16 +3544,32 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Ta ut feilsøkingsinformasjon (standardverdi: %u, bruk av <category> er valgfritt)</translation> </message> <message> + <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> + <translation>Støtte filtrering av blokker og transaksjoner med bloomfiltre (standardverdi: %u)</translation> + </message> + <message> + <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> + <translation>Total lengde av nettverks-versionstreng (%i) er over maks lengde (%i). Reduser tallet eller størrelsen av uacomments.</translation> + </message> + <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>Prøv å holde utgående trafikk under angitt mål (i MB per 24t), 0 = ingen grense (standard: %d)</translation> + </message> + <message> + <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Argumentet -socks er ikke støttet. Det er ikke lenger mulig å sette SOCKS-versjon; bare SOCKS5-proxyer er støttet.</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> + <source>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source> + <translation>Brukernavn og hashet passord for JSON-RPC tilkoblinger. Feltet <userpw> kommer i formatet: <USERNAME>:<SALT>$<HASH>. Et Python-skript er inkludert i share/rpcuser. Dette alternativet kan angis flere ganger</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Akseptable sifre (standardverdi: %s)</translation> + <source>(default: %s)</source> + <translation>(standardverdi: %s)</translation> </message> <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> @@ -3493,14 +3632,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Videresend ikke-P2SH multisig (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> diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 7999e263e4..8457a9ab50 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -1,4 +1,4 @@ -<TS language="nl" version="2.0"> +<TS language="nl" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -59,7 +59,7 @@ </message> <message> <source>Sending addresses</source> - <translation>Verstuur adressen</translation> + <translation>Verstuuradressen</translation> </message> <message> <source>Receiving addresses</source> @@ -67,11 +67,11 @@ </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>Dit zijn uw Bitcoinadressen om betalingen mee te verzenden. Controleer altijd het bedrag en het ontvang adres voordat u uw bitcoins verzendt.</translation> + <translation>Dit zijn uw Bitcoinadressen om betalingen mee te doen. Controleer altijd het bedrag en het ontvang adres voordat u uw bitcoins verstuurt.</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>Dit zijn uw Bitcoin-adressen waarmee u kunt betalen. We raden u aan om een nieuw ontvangstadres voor elke transactie te gebruiken.</translation> + <translation>Dit zijn uw Bitcoinadressen waarmee u kunt betalen. We raden u aan om een nieuw ontvangstadres voor elke transactie te gebruiken.</translation> </message> <message> <source>Copy &Label</source> @@ -157,7 +157,7 @@ </message> <message> <source>Confirm wallet encryption</source> - <translation>Bevestig versleuteling van de portemonnee</translation> + <translation>Bevestig versleuteling van uw portemonnee</translation> </message> <message> <source>Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!</source> @@ -177,7 +177,7 @@ </message> <message> <source>Warning: The Caps Lock key is on!</source> - <translation>Waarschuwing: De Caps-Lock-toets staat aan!</translation> + <translation>Waarschuwing: De Caps Locktoets staat aan!</translation> </message> <message> <source>Wallet encrypted</source> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/Netmasker</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Geband tot</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -248,11 +259,11 @@ </message> <message> <source>Browse transaction history</source> - <translation>Blader door transactieverleden</translation> + <translation>Blader door transactiegescheidenis</translation> </message> <message> <source>E&xit</source> - <translation>&Afsluiten</translation> + <translation>A&fsluiten</translation> </message> <message> <source>Quit application</source> @@ -268,7 +279,7 @@ </message> <message> <source>&Options...</source> - <translation>O&pties...</translation> + <translation>&Opties...</translation> </message> <message> <source>&Encrypt Wallet...</source> @@ -284,11 +295,11 @@ </message> <message> <source>&Sending addresses...</source> - <translation>V&erstuur adressen...</translation> + <translation>&Verstuuradressen...</translation> </message> <message> <source>&Receiving addresses...</source> - <translation>O&ntvang adressen...</translation> + <translation>&Ontvang adressen...</translation> </message> <message> <source>Open &URI...</source> @@ -296,7 +307,7 @@ </message> <message> <source>Bitcoin Core client</source> - <translation>Bitcoin Kern applicatie</translation> + <translation>Bitcoin Coreapplicatie</translation> </message> <message> <source>Importing blocks from disk...</source> @@ -340,7 +351,7 @@ </message> <message> <source>&Send</source> - <translation>&Versturen</translation> + <translation>&Verstuur</translation> </message> <message> <source>&Receive</source> @@ -348,7 +359,7 @@ </message> <message> <source>Show information about Bitcoin Core</source> - <translation>Toon informatie over bitcoin kern</translation> + <translation>Toon informatie over Bitcoin Core</translation> </message> <message> <source>&Show / Hide</source> @@ -388,11 +399,11 @@ </message> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Kern</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>Request payments (generates QR codes and bitcoin: URIs)</source> - <translation>Vraag betaling aan (genereert QR codes en bitcoin: URIs)</translation> + <translation>Vraag betaling aan (genereert QR-codes en bitcoin: URI's)</translation> </message> <message> <source>&About Bitcoin Core</source> @@ -404,7 +415,7 @@ </message> <message> <source>Show the list of used sending addresses and labels</source> - <translation>Toon de lijst met gebruikt verzend adressen en labels</translation> + <translation>Toon de lijst met gebruikte verstuuradressen en -labels</translation> </message> <message> <source>Show the list of used receiving addresses and labels</source> @@ -416,15 +427,15 @@ </message> <message> <source>&Command-line options</source> - <translation>&Commandoregel-opties</translation> + <translation>&Opdrachytregelopties</translation> </message> <message> <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source> - <translation>Toon het Bitcoin Core hulpbericht om een lijst te krijgen met mogelijke Bitcoin commandoregelopties</translation> + <translation>Toon het Bitcoin Core hulpbericht om een lijst te krijgen met mogelijke Bitcoinopdrachtregelopties</translation> </message> <message numerus="yes"> <source>%n active connection(s) to Bitcoin network</source> - <translation><numerusform>%n actieve connectie naar Bitcoin netwerk</numerusform><numerusform>%n actieve connecties naar Bitcoin netwerk</numerusform></translation> + <translation><numerusform>%n actieve verbinding met Bitcoinnetwerk</numerusform><numerusform>%n actieve verbindingen met Bitcoinnetwerk</numerusform></translation> </message> <message> <source>No block source available...</source> @@ -432,11 +443,11 @@ </message> <message numerus="yes"> <source>Processed %n block(s) of transaction history.</source> - <translation><numerusform>%n blok aan transactie geschiedenis verwerkt.</numerusform><numerusform>%n blokken aan transactie geschiedenis verwerkt.</numerusform></translation> + <translation><numerusform>%n blok aan transactiegeschiedenis verwerkt.</numerusform><numerusform>%n blokken aan transactiegeschiedenis verwerkt.</numerusform></translation> </message> <message numerus="yes"> <source>%n hour(s)</source> - <translation><numerusform>%n uur</numerusform><numerusform>%n uur</numerusform></translation> + <translation><numerusform>%n uur</numerusform><numerusform>%n uren</numerusform></translation> </message> <message numerus="yes"> <source>%n day(s)</source> @@ -452,7 +463,7 @@ </message> <message numerus="yes"> <source>%n year(s)</source> - <translation><numerusform>%n jaar</numerusform><numerusform>%n jaar</numerusform></translation> + <translation><numerusform>%n jaar</numerusform><numerusform>%n jaren</numerusform></translation> </message> <message> <source>%1 behind</source> @@ -518,7 +529,7 @@ </message> <message> <source>Sent transaction</source> - <translation>Verzonden transactie</translation> + <translation>Verstuurde transactie</translation> </message> <message> <source>Incoming transaction</source> @@ -564,7 +575,7 @@ </message> <message> <source>Fee:</source> - <translation>Vergoeding:</translation> + <translation>Transactiekosten:</translation> </message> <message> <source>Dust:</source> @@ -572,7 +583,7 @@ </message> <message> <source>After Fee:</source> - <translation>Na vergoeding:</translation> + <translation>Naheffing:</translation> </message> <message> <source>Change:</source> @@ -648,11 +659,11 @@ </message> <message> <source>Copy fee</source> - <translation>Kopieer vergoeding</translation> + <translation>Kopieerkosten</translation> </message> <message> <source>Copy after fee</source> - <translation>Kopieer na vergoeding</translation> + <translation>Kopieernaheffing</translation> </message> <message> <source>Copy bytes</source> @@ -740,15 +751,15 @@ </message> <message> <source>This means a fee of at least %1 per kB is required.</source> - <translation>Dit betekent dat een vergoeding van minimaal %1 per kB nodig is.</translation> + <translation>Dit betekent dat kosten van minimaal %1 per kB aan verbonden zijn.</translation> </message> <message> <source>Can vary +/- 1 byte per input.</source> - <translation>Kan +/- byte per invoer variëren.</translation> + <translation>Kan +/- 1 byte per invoer variëren.</translation> </message> <message> <source>Transactions with higher priority are more likely to get included into a block.</source> - <translation>Transacties met een hogere prioriteit zullen eerder in een block gezet worden.</translation> + <translation>Transacties met een hogere prioriteit zullen eerder in een blok gezet worden.</translation> </message> <message> <source>(no label)</source> @@ -779,7 +790,7 @@ </message> <message> <source>The address associated with this address list entry. This can only be modified for sending addresses.</source> - <translation>Het adres dat bij dit adres item hoort. Dit kan alleen bewerkt worden voor verstuur adressen.</translation> + <translation>Het adres dat bij dit adresitem hoort. Dit kan alleen bewerkt worden voor verstuuradressen.</translation> </message> <message> <source>&Address</source> @@ -791,7 +802,7 @@ </message> <message> <source>New sending address</source> - <translation>Nieuw adres om naar te verzenden</translation> + <translation>Nieuw adres om naar te versturen</translation> </message> <message> <source>Edit receiving address</source> @@ -799,7 +810,7 @@ </message> <message> <source>Edit sending address</source> - <translation>Bewerk adres om naar te verzenden</translation> + <translation>Bewerk adres om naar te versturen</translation> </message> <message> <source>The entered address "%1" is already in the address book.</source> @@ -834,7 +845,7 @@ </message> <message> <source>Path already exists, and is not a directory.</source> - <translation>Communicatiepad bestaat al, en is geen folder.</translation> + <translation>Communicatiepad bestaat al, en is geen map.</translation> </message> <message> <source>Cannot create data directory here.</source> @@ -845,7 +856,7 @@ <name>HelpMessageDialog</name> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Kern</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>version</source> @@ -861,7 +872,7 @@ </message> <message> <source>Command-line options</source> - <translation>Commandoregel-opties</translation> + <translation>Opdrachtregelopties</translation> </message> <message> <source>Usage:</source> @@ -869,7 +880,35 @@ </message> <message> <source>command-line options</source> - <translation>commandoregel-opties</translation> + <translation>opdrachtregelopties</translation> + </message> + <message> + <source>UI Options:</source> + <translation>UI-opties:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Kies gegevensmap bij opstarten (standaard: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Stel taal in, bijvoorbeeld "nl_NL" (standaard: systeemlocale)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Geminimaliseerd starten</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Zet SSL-rootcertificaat voor betalingsverzoeken (standaard: -systeem-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Toon opstartscherm bij opstarten (standaard: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Reset alle wijzigingen aan instellingen gedaan met de GUI</translation> </message> </context> <context> @@ -888,7 +927,7 @@ </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 zal een kopie van de Bitcoin blokketen downloaden en opslaan. Tenminste %1 GB aan data wordt opgeslagen in deze map en het zal groeien in de tijd. De portemonnee wordt ook in deze map opgeslagen.</translation> + <translation>Bitcoin Core zal een kopie van de Bitcoinblokketen downloaden en opslaan. Tenminste %1 GB aan data wordt opgeslagen in deze map en het zal groeien in de tijd. De portemonnee wordt ook in deze map opgeslagen.</translation> </message> <message> <source>Use the default data directory</source> @@ -900,7 +939,7 @@ </message> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Kern</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>Error: Specified data directory "%1" cannot be created.</source> @@ -912,7 +951,7 @@ </message> <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> + <translation><numerusform>%n GB aan vrije opslagruimte beschikbaar</numerusform><numerusform>%n GB aan vrije opslagruimte beschikbaar</numerusform></translation> </message> <message numerus="yes"> <source>(of %n GB needed)</source> @@ -954,7 +993,7 @@ </message> <message> <source>Size of &database cache</source> - <translation>Grootte van de &database cache</translation> + <translation>Grootte van de &databasecache</translation> </message> <message> <source>MB</source> @@ -986,7 +1025,7 @@ </message> <message> <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> - <translation>Derde partijen URL's (bijvoorbeeld block explorer) dat in de transacties tab verschijnen als contextmenu elementen. %s in de URL is vervangen door transactie hash. Verscheidene URL's zijn gescheiden door een verticale streep |. </translation> + <translation>URL's van derden (bijvoorbeeld block explorer) die in de transacties tab verschijnen als contextmenuelementen. %s in de URL is vervangen door transactiehash. Verscheidene URL's zijn gescheiden door een verticale streep |. </translation> </message> <message> <source>Third party transaction URLs</source> @@ -994,7 +1033,7 @@ </message> <message> <source>Active command-line options that override above options:</source> - <translation>Actieve commandoregelopties die bovenstaande opties overschrijven:</translation> + <translation>Actieve opdrachtregelopties die bovenstaande opties overschrijven:</translation> </message> <message> <source>Reset all client options to default.</source> @@ -1010,11 +1049,11 @@ </message> <message> <source>Automatically start Bitcoin Core after logging in to the system.</source> - <translation>Bitcoin Kern automatisch starten bij inloggen.</translation> + <translation>Bitcoin Core automatisch starten bij inloggen.</translation> </message> <message> <source>&Start Bitcoin Core on system login</source> - <translation>&Start Bitcoin Kern tijdens login.</translation> + <translation>&Start Bitcoin Core tijdens login.</translation> </message> <message> <source>(0 = auto, <0 = leave that many cores free)</source> @@ -1042,7 +1081,7 @@ </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>Open de Bitcoin-poort automatisch op de router. Dit werkt alleen als de router UPnP ondersteunt en het aanstaat.</translation> + <translation>Open de Bitcoinpoort automatisch op de router. Dit werkt alleen als de router UPnP ondersteunt en het aanstaat.</translation> </message> <message> <source>Map port using &UPnP</source> @@ -1050,7 +1089,7 @@ </message> <message> <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> - <translation>Verbind met het Bitcoin netwerk via een SOCKS5 proxy.</translation> + <translation>Verbind met het Bitcoinnetwerk via een SOCKS5 proxy.</translation> </message> <message> <source>&Connect through SOCKS5 proxy (default proxy):</source> @@ -1069,12 +1108,40 @@ <translation>Poort van de proxy (bijv. 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Gebruikt om peers te bereiken via:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Vertoningen, als de opgegeven standaard SOCKS5-proxy is gebruikt om peers te benaderen via dit type netwerk.</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Maak verbinding met Bitcoinnetwerk door een aparte SOCKS5-proxy voor verborgen diensten van Tor.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Gebruikt aparte SOCKS5-proxy om peers te bereiken via verborgen diensten van Tor:</translation> + </message> + <message> <source>&Window</source> <translation>&Scherm</translation> </message> <message> <source>Show only a tray icon after minimizing the window.</source> - <translation>Laat alleen een systeemvak-icoon zien wanneer het venster geminimaliseerd is</translation> + <translation>Laat alleen een systeemvakicoon zien wanneer het venster geminimaliseerd is</translation> </message> <message> <source>&Minimize to the tray instead of the taskbar</source> @@ -1082,7 +1149,7 @@ </message> <message> <source>M&inimize on close</source> - <translation>Minimaliseer bij sluiten van het &venster</translation> + <translation>M&inimaliseer bij sluiten van het venster</translation> </message> <message> <source>&Display</source> @@ -1098,7 +1165,7 @@ </message> <message> <source>Choose the default subdivision unit to show in the interface and when sending coins.</source> - <translation>Kies de standaard onderverdelingseenheid om weer te geven in uw programma, en voor het versturen van munten</translation> + <translation>Kies de standaardonderverdelingseenheid om weer te geven in uw programma, en voor het versturen van munten</translation> </message> <message> <source>Whether to show coin control features or not.</source> @@ -1110,7 +1177,7 @@ </message> <message> <source>&Cancel</source> - <translation>Ann&uleren</translation> + <translation>&Annuleren</translation> </message> <message> <source>default</source> @@ -1256,7 +1323,7 @@ </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> + <translation>URI kan niet verwerkt worden! Dit kan het gevolg zijn van een ongeldig Bitcoinadres of misvormde URI-parameters.</translation> </message> <message> <source>Payment request file handling</source> @@ -1264,7 +1331,7 @@ </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> + <translation>Betalingsverzoekbestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoek-bestand.</translation> </message> <message> <source>Payment request expired.</source> @@ -1287,10 +1354,6 @@ <translation>Betalingsverzoek %1 is te groot (%2 bytes, toegestaan %3 bytes).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Betalingsaanvraag DoS bescherming</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Fout bij communiceren met %1: %2</translation> </message> @@ -1318,6 +1381,10 @@ <translation>User Agent</translation> </message> <message> + <source>Node/Service</source> + <translation>Node/Dienst</translation> + </message> + <message> <source>Ping Time</source> <translation>Ping tijd</translation> </message> @@ -1330,11 +1397,11 @@ </message> <message> <source>Enter a Bitcoin address (e.g. %1)</source> - <translation>Voer een Bitcoin-adres in (bijv. %1)</translation> + <translation>Voer een Bitcoinadres in (bijv. %1)</translation> </message> <message> <source>%1 d</source> - <translation>%1d</translation> + <translation>%1 d</translation> </message> <message> <source>%1 h</source> @@ -1346,7 +1413,7 @@ </message> <message> <source>%1 s</source> - <translation>%1s</translation> + <translation>%1 s</translation> </message> <message> <source>None</source> @@ -1439,8 +1506,20 @@ <translation>Huidig aantal blokken</translation> </message> <message> + <source>Memory Pool</source> + <translation>Geheugenpoel</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>Huidig aantal transacties</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Geheugengebruik</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> - <translation>Open het Bitcoin Core debug logbestand van de huidige gegevens directory. Dit kan enkele seconden duren voor grote logbestanden.</translation> + <translation>Open het Bitcoin Core debuglogbestand van de huidige gegevensmap. Dit kan enkele seconden duren voor grote logbestanden.</translation> </message> <message> <source>Received</source> @@ -1455,10 +1534,18 @@ <translation>&Peers</translation> </message> <message> + <source>Banned peers</source> + <translation>Gebande 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>Whitelisted</source> + <translation>Toegestaan</translation> + </message> + <message> <source>Direction</source> <translation>Directie</translation> </message> @@ -1467,20 +1554,24 @@ <translation>Versie</translation> </message> <message> - <source>User Agent</source> - <translation>User Agent</translation> + <source>Starting Block</source> + <translation>Start Blok</translation> </message> <message> - <source>Services</source> - <translation>Services</translation> + <source>Synced Headers</source> + <translation>Gesynchroniseerde headers</translation> </message> <message> - <source>Starting Height</source> - <translation>Aanvangshoogte</translation> + <source>Synced Blocks</source> + <translation>Gesynchroniseerde blokken</translation> + </message> + <message> + <source>User Agent</source> + <translation>User Agent</translation> </message> <message> - <source>Sync Height</source> - <translation>Synchronisatiehoogte</translation> + <source>Services</source> + <translation>Diensten</translation> </message> <message> <source>Ban Score</source> @@ -1499,16 +1590,20 @@ <translation>Laatst ontvangen</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Bytes Verzonden</translation> + <source>Ping Time</source> + <translation>Ping Tijd</translation> </message> <message> - <source>Bytes Received</source> - <translation>Bytes Ontvangen</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>De tijdsduur van een op het moment openstaande ping.</translation> </message> <message> - <source>Ping Time</source> - <translation>Ping Tijd</translation> + <source>Ping Wait</source> + <translation>Pingwachttijd</translation> + </message> + <message> + <source>Time Offset</source> + <translation>Tijdcompensatie</translation> </message> <message> <source>Last block time</source> @@ -1548,13 +1643,41 @@ </message> <message> <source>Debug log file</source> - <translation>Debug-logbestand</translation> + <translation>Debuglogbestand</translation> </message> <message> <source>Clear console</source> <translation>Maak console leeg</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>&Verbreek Verbinding Node</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Ban Node voor</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &uur</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &dag</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &week</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &jaar</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>&Maak Ban Ongedaan voor Node</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Welkom op de Bitcoin Core RPC console.</translation> </message> @@ -1564,7 +1687,7 @@ </message> <message> <source>Type <b>help</b> for an overview of available commands.</source> - <translation>Typ <b>help</b> voor een overzicht van de beschikbare commando's.</translation> + <translation>Typ <b>help</b> voor een overzicht van de beschikbare opdrachten.</translation> </message> <message> <source>%1 B</source> @@ -1583,6 +1706,10 @@ <translation>%1 Gb</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(node id: %1)</translation> + </message> + <message> <source>via %1</source> <translation>via %1</translation> </message> @@ -1599,12 +1726,16 @@ <translation>Uitgaand</translation> </message> <message> - <source>Unknown</source> - <translation>Onbekend</translation> + <source>Yes</source> + <translation>Ja</translation> </message> <message> - <source>Fetching...</source> - <translation>Ophalen...</translation> + <source>No</source> + <translation>Nee</translation> + </message> + <message> + <source>Unknown</source> + <translation>Onbekend</translation> </message> </context> <context> @@ -1631,7 +1762,7 @@ </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>Een optioneel bericht om bij te voegen aan het betalingsverzoek, dewelke zal getoond worden wanneer het verzoek is geopend. Opermerking: Het bericht zal niet worden verzonden met de betaling over het Bitcoin netwerk.</translation> + <translation>Een optioneel bericht om bij te voegen aan het betalingsverzoek, welke zal getoond worden wanneer het verzoek is geopend. Opmerking: Het bericht zal niet worden verzonden met de betaling over het Bitcoinnetwerk.</translation> </message> <message> <source>An optional label to associate with the new receiving address.</source> @@ -1780,7 +1911,7 @@ <name>SendCoinsDialog</name> <message> <source>Send Coins</source> - <translation>Verstuur munten</translation> + <translation>Verstuurde munten</translation> </message> <message> <source>Coin Control Features</source> @@ -1816,11 +1947,11 @@ </message> <message> <source>Fee:</source> - <translation>Vergoeding:</translation> + <translation>Kosten:</translation> </message> <message> <source>After Fee:</source> - <translation>Na vergoeding:</translation> + <translation>Naheffing:</translation> </message> <message> <source>Change:</source> @@ -1828,7 +1959,7 @@ </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>Als dit is geactiveerd, maar het wisselgeldadres is leeg of ongeldig, dan wordt het wisselgeld verzonden naar een nieuw gegenereerd adres.</translation> + <translation>Als dit is geactiveerd, maar het wisselgeldadres is leeg of ongeldig, dan wordt het wisselgeld verstuurd naar een nieuw gegenereerd adres.</translation> </message> <message> <source>Custom change address</source> @@ -1844,7 +1975,7 @@ </message> <message> <source>collapse fee-settings</source> - <translation>Transactiekosteninstellingen verbergen</translation> + <translation>verberg kosteninstellingen</translation> </message> <message> <source>per kilobyte</source> @@ -1880,7 +2011,7 @@ </message> <message> <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> - <translation>(Slimme vergoeding is nog niet geïnitialiseerd. Dit duurt meestal een paar blokken...)</translation> + <translation>(Slimme transactiekosten is nog niet geïnitialiseerd. Dit duurt meestal een paar blokken...)</translation> </message> <message> <source>Confirmation time:</source> @@ -1896,7 +2027,7 @@ </message> <message> <source>Send as zero-fee transaction if possible</source> - <translation>Verstuur als transactie zonder verzendkosten indien mogelijk</translation> + <translation>Indien mogelijk, verstuur zonder transactiekosten</translation> </message> <message> <source>(confirmation may take longer)</source> @@ -1904,7 +2035,7 @@ </message> <message> <source>Send to multiple recipients at once</source> - <translation>Verstuur aan verschillende ontvangers ineens</translation> + <translation>Verstuur in een keer aan verschillende ontvangers</translation> </message> <message> <source>Add &Recipient</source> @@ -1932,7 +2063,7 @@ </message> <message> <source>S&end</source> - <translation>&Verstuur</translation> + <translation>V&erstuur</translation> </message> <message> <source>Confirm send coins</source> @@ -1952,11 +2083,11 @@ </message> <message> <source>Copy fee</source> - <translation>Kopieer vergoeding</translation> + <translation>Kopieerkosten</translation> </message> <message> <source>Copy after fee</source> - <translation>Kopieer na vergoeding</translation> + <translation>Kopieernaheffing</translation> </message> <message> <source>Copy bytes</source> @@ -1971,8 +2102,8 @@ <translation>Kopieer wijziging</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Totaal bedrag %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Totaalbedrag %1</translation> </message> <message> <source>or</source> @@ -1999,12 +2130,20 @@ <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 absurdly high fee.</source> + <translation>Transactiekosten van meer dan %1 wordt beschouwd als een absurd hoge transactiekosten.</translation> + </message> + <message> <source>Payment request expired.</source> <translation>Betalingsverzoek verlopen.</translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Betaal alleen de minimale transactiekosten van %1</translation> + <source>Pay only the required fee of %1</source> + <translation>Betaal alleen de verplichte transactiekosten van %1</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Schatting is dat bevestiging begint over %n blok.</numerusform><numerusform>Schatting is dat bevestiging begint over %n blokken.</numerusform></translation> </message> <message> <source>The recipient address is not valid. Please recheck.</source> @@ -2016,7 +2155,7 @@ </message> <message> <source>Warning: Invalid Bitcoin address</source> - <translation>Waarschuwing: Ongeldig Bitcoin adres</translation> + <translation>Waarschuwing: Ongeldig Bitcoinadres</translation> </message> <message> <source>(no label)</source> @@ -2032,7 +2171,7 @@ </message> <message> <source>Are you sure you want to send?</source> - <translation>Weet u zeker dat u wilt verzenden?</translation> + <translation>Weet u zeker dat u wilt versturen?</translation> </message> <message> <source>added as transaction fee</source> @@ -2043,7 +2182,7 @@ <name>SendCoinsEntry</name> <message> <source>A&mount:</source> - <translation>Bedra&g:</translation> + <translation>B&edrag:</translation> </message> <message> <source>Pay &To:</source> @@ -2067,7 +2206,7 @@ </message> <message> <source>The Bitcoin address to send the payment to</source> - <translation>Het Bitcoin adres om betaling aan te voldoen</translation> + <translation>Het Bitcoinadres om betaling aan te versturen</translation> </message> <message> <source>Alt+A</source> @@ -2086,6 +2225,14 @@ <translation>Verwijder deze toevoeging</translation> </message> <message> + <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> + <translation>De transactiekosten zal worden afgetrokken van het bedrag dat verstuurd wordt. De ontvangers zullen minder bitcoins ontvangen dan ingevoerd is in het hoeveelheidsveld. Als er meerdere ontvangers geselecteerd zijn, dan worden de transactiekosten gelijk verdeeld.</translation> + </message> + <message> + <source>S&ubtract fee from amount</source> + <translation>Trek de transactiekosten a&f van het bedrag.</translation> + </message> + <message> <source>Message:</source> <translation>Bericht:</translation> </message> @@ -2103,7 +2250,7 @@ </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>Een bericht dat werd toegevoegd aan de bitcoin: URI dewelke wordt opgeslagen met de transactie ter referentie. Opmerking: Dit bericht zal niet worden verzonden over het Bitcoin netwerk.</translation> + <translation>Een bericht dat werd toegevoegd aan de bitcoin: URI welke wordt opgeslagen met de transactie ter referentie. Opmerking: Dit bericht zal niet worden verzonden over het Bitcoinnetwerk.</translation> </message> <message> <source>Pay To:</source> @@ -2129,19 +2276,19 @@ <name>SignVerifyMessageDialog</name> <message> <source>Signatures - Sign / Verify a Message</source> - <translation>Handtekeningen - Onderteken een bericht / Verifiëer een handtekening</translation> + <translation>Handtekeningen – Onderteken een bericht / Verifiëer een handtekening</translation> </message> <message> <source>&Sign Message</source> - <translation>O&nderteken Bericht</translation> + <translation>&Onderteken Bericht</translation> </message> <message> <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> - <translation>U kunt berichten/overeenkomsten ondertekenen met uw adres om te bewijzen dat u Bitcoins kunt versturen. Wees voorzichtig met het ondertekenen van iets vaags of willekeurigs, omdat phishing-aanvallen u kunnen proberen te misleiden tot het ondertekenen van overeenkomsten om uw identiteit aan hen toe te vertrouwen. Onderteken alleen volledig gedetailleerde verklaringen voordat u akkoord gaat.</translation> + <translation>U kunt berichten/overeenkomsten ondertekenen met uw adres om te bewijzen dat u Bitcoins kunt versturen. Wees voorzichtig met het ondertekenen van iets vaags of willekeurigs, omdat phishingaanvallen u kunnen proberen te misleiden tot het ondertekenen van overeenkomsten om uw identiteit aan hen toe te vertrouwen. Onderteken alleen volledig gedetailleerde verklaringen voordat u akkoord gaat.</translation> </message> <message> <source>The Bitcoin address to sign the message with</source> - <translation>Het Bitcoin adres om bericht mee te ondertekenen</translation> + <translation>Het Bitcoinadres om bericht mee te ondertekenen</translation> </message> <message> <source>Choose previously used address</source> @@ -2192,8 +2339,12 @@ <translation>&Verifiëer Bericht</translation> </message> <message> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Voer het adres van de ontvanger in, bericht (zorg ervoor dat de regeleinden, spaties, tabs etc. precies kloppen) en onderteken onderaan om het bericht te verifiëren. Wees voorzicht om niet meer in de ondertekening te lezen dan in het getekende bericht zelf, om te voorkomen dat je wordt aangevallen met een man-in-the-middle attack. Houd er mee rekening dat dit alleen de ondertekende partij bewijst met het ontvangen adres, er kan niet bewezen worden dat er een transactie heeft plaatsgevonden!</translation> + </message> + <message> <source>The Bitcoin address the message was signed with</source> - <translation>Het Bitcoin adres waarmee het bericht ondertekend is</translation> + <translation>Het Bitcoinadres waarmee het bericht ondertekend is</translation> </message> <message> <source>Verify the message to ensure it was signed with the specified Bitcoin address</source> @@ -2264,11 +2415,11 @@ <name>SplashScreen</name> <message> <source>Bitcoin Core</source> - <translation>Bitcoin Kern</translation> + <translation>Bitcoin Core</translation> </message> <message> <source>The Bitcoin Core developers</source> - <translation>De Bitcoin Core ontwikkelaars</translation> + <translation>De Bitcoin Core-ontwikkelaars</translation> </message> <message> <source>[testnet]</source> @@ -2398,7 +2549,7 @@ </message> <message> <source>Debug information</source> - <translation>Debug-informatie</translation> + <translation>Debuginformatie</translation> </message> <message> <source>Transaction</source> @@ -2456,7 +2607,7 @@ </message> <message> <source>Immature (%1 confirmations, will be available after %2)</source> - <translation>immatuur (%1 bevestigingen, zal beschikbaar zijn na %2)</translation> + <translation>Premature (%1 bevestigingen, zal beschikbaar zijn na %2)</translation> </message> <message numerus="yes"> <source>Open for %n more block(s)</source> @@ -2508,7 +2659,7 @@ </message> <message> <source>Sent to</source> - <translation>Verzonden aan</translation> + <translation>Verstuurd aan</translation> </message> <message> <source>Payment to yourself</source> @@ -2543,6 +2694,10 @@ <translation>Of er een alleen-bekijken adres is betrokken bij deze transactie.</translation> </message> <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Door gebruiker gedefinieerde intentie/doel van de transactie</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Bedrag verwijderd van of toegevoegd aan saldo</translation> </message> @@ -2583,7 +2738,7 @@ </message> <message> <source>Sent to</source> - <translation>Verzonden aan</translation> + <translation>Verstuurd aan</translation> </message> <message> <source>To yourself</source> @@ -2622,6 +2777,10 @@ <translation>Kopieer transactie-ID</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>Kopieer ruwe transactie</translation> + </message> + <message> <source>Edit label</source> <translation>Bewerk label</translation> </message> @@ -2631,7 +2790,7 @@ </message> <message> <source>Export Transaction History</source> - <translation>Exporteer Transactieverleden</translation> + <translation>Exporteer Transactiegeschiedenis</translation> </message> <message> <source>Watch-only</source> @@ -2643,7 +2802,7 @@ </message> <message> <source>There was an error trying to save the transaction history to %1.</source> - <translation>Er is een fout opgetreden bij het opslaan van het transactieverleden naar %1.</translation> + <translation>Er is een fout opgetreden bij het opslaan van het transactiegeschiedenis naar %1.</translation> </message> <message> <source>Exporting Successful</source> @@ -2651,7 +2810,7 @@ </message> <message> <source>The transaction history was successfully saved to %1.</source> - <translation>Het transactieverleden was succesvol bewaard in %1.</translation> + <translation>Het transactiegeschiedenis was succesvol bewaard in %1.</translation> </message> <message> <source>Comma separated file (*.csv)</source> @@ -2708,7 +2867,7 @@ <name>WalletModel</name> <message> <source>Send Coins</source> - <translation>Verstuur munten</translation> + <translation>Verstuur Munten</translation> </message> </context> <context> @@ -2727,7 +2886,7 @@ </message> <message> <source>Wallet Data (*.dat)</source> - <translation>Portemonnee-data (*.dat)</translation> + <translation>Portemonneedata (*.dat)</translation> </message> <message> <source>Backup Failed</source> @@ -2735,7 +2894,7 @@ </message> <message> <source>There was an error trying to save the wallet data to %1.</source> - <translation>Er is een fout opgetreden bij het wegschrijven van de portemonnee-data naar %1.</translation> + <translation>Er is een fout opgetreden bij het wegschrijven van de portemonneedata naar %1.</translation> </message> <message> <source>The wallet data was successfully saved to %1.</source> @@ -2766,15 +2925,55 @@ </message> <message> <source>Accept command line and JSON-RPC commands</source> - <translation>Aanvaard commandoregel- en JSON-RPC-commando's</translation> + <translation>Aanvaard opdrachtregel- en JSON-RPC-opdrachten</translation> + </message> + <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>Als er geen <categorie> is opgegeven of als de <categorie> 1 is, laat dan alle debugginginformatie zien.</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Maximum totale transactiekosten (in %s) om te gebruiken voor een enkele portemonneetransactie; als dit te laag is ingesteld kan het grote transacties verhinderen (default: %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Check a.u.b. of de datum en tijd van uw computer correct zijn! Als uw klok verkeerd staat zal Bitcoin Core niet correct werken.</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>Snoeien is geconfigureerd on het minimum van %d MiB. Gebruik a.u.b. een hoger aantal.</translation> + </message> + <message> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation>Snoei: laatste portemoneesynchronisatie gaat verder dan de gesnoeide data. U moet -reindex gebruiken (download opnieuw de gehele blokketen voor een weggesnoeide node)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Beperk benodigde opslag door snoeien (verwijderen) van oude blokken. Deze modus is niet-compatibele met -txindex en -rescan. Waarschuwing: Terugzetten van deze instellingen vereist opnieuw downloaden van gehele de blokketen. (standaard:0 = uitzetten snoeimodus, >%u = doelgrootte in MiB voor blokbestanden)</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>Herscannen is niet mogelijk in de snoeimodus. U moet -reindex gebruiken dat de hele blokketen opnieuw zal downloaden.</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Fout: er is een fout opgetreden, zie debug.log voor details</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Transactiekosten (in %s/kB) toevoegen aan transacties die u doet (standaard: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Snoei blokopslag...</translation> </message> <message> <source>Run in the background as a daemon and accept commands</source> - <translation>Draai in de achtergrond als daemon en aanvaard commando's</translation> + <translation>Draai in de achtergrond als daemon en aanvaard opdrachten</translation> </message> <message> - <source>Use the test network</source> - <translation>Gebruik het testnetwerk</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>Niet mogelijk ok HTTP-server te starten. Zie debuglogboek voor details.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2786,11 +2985,11 @@ </message> <message> <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source> - <translation>Verwijder alle transacties van de portemonnee en herstel alleen de delen van de blockchain door -rescan tijdens het opstarten</translation> + <translation>Verwijder alle transacties van de portemonnee en herstel alleen de delen van de blokketen door -rescan tijdens het opstarten</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>Uitgegeven onder de MIT software licentie, zie het bijgevoegde bestand COPYING of <http://www.opensource.org/licenses/mit-license.php>.</translation> + <translation>Uitgegeven onder de MIT-softwarelicentie, zie het bijgevoegde bestand COPYING of <http://www.opensource.org/licenses/mit-license.php>.</translation> </message> <message> <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source> @@ -2798,23 +2997,31 @@ </message> <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> - <translation>Kies het aantal script verificatie processen (%u tot %d, 0 = auto, <0 = laat dit aantal kernen vrij, standaard: %d)</translation> + <translation>Kies het aantal scriptverificatie processen (%u tot %d, 0 = auto, <0 = laat dit aantal kernen vrij, standaard: %d)</translation> + </message> + <message> + <source>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>De blokdatabase bevat een blok dat lijkt uit de toekomst te komen. Dit kan gebeuren omdat de datum en tijd van uw computer niet goed staat. Herbouw de blokdatabase pas nadat u de datum en tijd van uw computer correct heeft ingesteld.</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> + <translation>Dit is een prerelease testversie – gebruik op eigen risico! Gebruik deze niet voor het delven van munten of handelsdoeleinden</translation> </message> <message> <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source> <translation>Niet in staat om %s te verbinden op deze computer. Bitcoin Core draait waarschijnlijk al.</translation> </message> <message> - <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> - <translation>WAARSCHUWING: controleer uw netwerkverbinding, %d blokken ontvangen in de laatste %d uren (%d verwacht)</translation> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>Gebruik UPnP om de luisterende poort te mappen (standaard: 1 als er geluisterd worden en geen -proxy is meegegeven)</translation> + </message> + <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>WAARSCHUWING: abnormaal hoog aantal blokken is gegenereerd, %d blokken ontvangen in de laatste %d uren (%d verwacht)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Waarschuwing: -paytxfee is zeer hoog ingesteld. Dit zijn de transactiekosten die u betaalt bij het versturen van een transactie.</translation> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>WAARSCHUWING: controleer uw netwerkverbinding, %d blokken ontvangen in de laatste %d uren (%d verwacht)</translation> </message> <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> @@ -2825,10 +3032,6 @@ <translation>Waarschuwing: Het lijkt erop dat we geen consensus kunnen vinden met onze peers! Mogelijk dient u te upgraden, of andere nodes moeten wellicht upgraden.</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>Waarschuwing: Fout bij het lezen van wallet.dat! Alle sleutels zijn in goede orde uitgelezen, maar transactiedata of adresboeklemma's zouden kunnen ontbreken of fouten bevatten.</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>Waarschuwing: wallet.dat is corrupt, data is veiliggesteld! Originele wallet.dat is opgeslagen als wallet.{tijdstip}.bak in %s; als uw balans of transacties incorrect zijn dient u een backup terug te zetten.</translation> </message> @@ -2837,16 +3040,12 @@ <translation>Goedgekeurde peers die verbinden van het ingegeven netmask of IP adres. Kan meerdere keren gespecificeerd worden.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(standaard: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool moet tenminste %d MB zijn</translation> </message> <message> <source><category> can be:</source> - <translation><category> kan zijn:</translation> - </message> - <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Poog de geheime sleutels uit een corrupt wallet.dat bestand terug te halen</translation> + <translation><categorie> kan zijn:</translation> </message> <message> <source>Block creation options:</source> @@ -2877,6 +3076,22 @@ <translation>Wilt u de blokkendatabase nu herbouwen?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation>Sta toe om hashblok te publiceren in <adres></translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>Stat toe om hashtransactie te publiceren in <adres></translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>Sta toe rauw blok te publiceren in <adres></translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation>Sta toe ruwe transacties te publiceren in <adres></translation> + </message> + <message> <source>Error initializing block database</source> <translation>Fout bij intialisatie blokkendatabase</translation> </message> @@ -2893,10 +3108,6 @@ <translation>Fout bij openen blokkendatabase</translation> </message> <message> - <source>Error: A fatal internal error occured, see debug.log for details</source> - <translation>Fout: Een fatale interne fout is opgetreden, zie debug.log voor details</translation> - </message> - <message> <source>Error: Disk space is low!</source> <translation>Fout: Weinig vrije diskruimte!</translation> </message> @@ -2905,22 +3116,22 @@ <translation>Mislukt om op welke poort dan ook te luisteren. Gebruik -listen=0 as u dit wilt.</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> - <message> <source>Importing...</source> <translation>Importeren...</translation> </message> <message> <source>Incorrect or no genesis block found. Wrong datadir for network?</source> - <translation>Incorrect of geen genesis-blok gevonden. Verkeerde datamap voor het netwerk?</translation> + <translation>Incorrect of geen genesisblok gevonden. Verkeerde datamap voor het netwerk?</translation> </message> <message> <source>Invalid -onion address: '%s'</source> <translation>Ongeldig -onion adres '%s'</translation> </message> <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>De transactiegeheugenpool moet onder de <n> megabytes blijven (standaard: %u)</translation> + </message> + <message> <source>Not enough file descriptors available.</source> <translation>Niet genoeg file descriptors beschikbaar.</translation> </message> @@ -2929,6 +3140,14 @@ <translation>Verbind alleen met nodes in netwerk <net> (ipv4, ipv6 of onion)</translation> </message> <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>Snoeien kan niet worden geconfigureerd met een negatieve waarde.</translation> + </message> + <message> + <source>Prune mode is incompatible with -txindex.</source> + <translation>Snoeimodus is niet-compatibel met -txindex</translation> + </message> + <message> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation>Zet database cache grootte in megabytes (%d tot %d, standaard: %d)</translation> </message> @@ -2941,10 +3160,26 @@ <translation>Specificeer het portemonnee bestand (vanuit de gegevensmap)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Niet-ondersteund argument -benchmark genegeerd, gebruik -debug=bench.</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Niet-ondersteund argument -debugnet genegeerd, gebruik -debug=net</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>Niet-ondersteund argument -tor gevonden, gebruik -onion.</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>User Agent comment (%s) contains unsafe characters.</source> + <translation>User Agentcommentaar (%s) bevat onveilige karakters.</translation> + </message> + <message> <source>Verifying blocks...</source> <translation>Blokken aan het controleren...</translation> </message> @@ -2966,21 +3201,13 @@ </message> <message> <source>You need to rebuild the database using -reindex to change -txindex</source> - <translation>Om -txindex te kunnen veranderen dient u de database opnieuw te bouwen met gebruik van -reindex.</translation> - </message> - <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importeert blokken van extern blk000??.dat bestand</translation> + <translation>Om -txindex te kunnen veranderen dient u de database herbouwen met gebruik van -reindex.</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>Sta JSON-RPC verbindingen toe vanuit een gespecificeerde bron. Geldig voor <ip> zijn een enkel IP (bijv. 1.2.3.4), een netwerk/netmask (bijv. 1.2.3.4/255.255.255.0) of een netwerk/CIDR (bijv. 1.2.3.4/24). Deze optie kan meerdere keren gespecificeerd worden.</translation> </message> <message> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation>Er is een fout opgetreden tijdens het opzetten van het RPC adres %s poort %u voor luisteren: %s</translation> - </message> - <message> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> <translation>Bind aan opgegeven adres en keur peers die ermee verbinden goed. Gebruik [host]:poort notatie voor IPv6</translation> </message> @@ -2997,37 +3224,40 @@ <translation>Creër nieuwe bestanden met standaard systeem bestandsrechten in plaats van umask 077 (alleen effectief met uitgeschakelde portemonnee functionaliteit)</translation> </message> <message> - <source>Error: Listening for incoming connections failed (listen returned error %s)</source> - <translation>Fout: luisteren naar binnenkomende verbindingen mislukt (luisteren gaf foutmelding %s)</translation> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Ontdek eigen IP-adressen (standaard: 1 voor luisteren en geen -externalip of -proxy)</translation> </message> <message> - <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> - <translation>Fout: er is een niet-ondersteund argument -socks aangetroffen. Het instellen van de SOCKS-versie is niet langer mogelijk. Alleen SOCKS5-proxy's worden ondersteund.</translation> + <source>Error: Listening for incoming connections failed (listen returned error %s)</source> + <translation>Fout: luisteren naar binnenkomende verbindingen mislukt (luisteren gaf foutmelding %s)</translation> </message> <message> <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source> - <translation>Voer commando uit zodra een waarschuwing is ontvangen of wanneer we een erg lange fork detecteren (%s in commando wordt vervangen door bericht)</translation> + <translation>Voer opdracht uit zodra een waarschuwing is ontvangen of wanneer we een erg lange fork detecteren (%s in opdracht wordt vervangen door bericht)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Toeslagen (in BTC/Kb) kleiner dan dit worden beschouwd als geen vergoeding (voor doorgeven) (standaard: %s)</translation> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>Transactiekosten (in %s/kB) kleiner dan dit worden beschouw dat geen transactiekosten in rekening worden gebracht voor doorgeven, mijnen en transactiecreatie (standaard: %s)</translation> </message> <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> - <translation>Als paytxfee niet is ingesteld, het pakket voldoende vergoeding zodat transacties beginnen bevestiging gemiddeld binnen in blokken (default: %u)</translation> + <translation>Als paytxfee niet is ingesteld, voeg voldoende transactiekosten toe zodat transacties starten met bevestigingen binnen in n blokken (standaard: %u)</translation> </message> <message> <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> - <translation>ongeldig bedrag voor -maxtxfee=<amount>: '%s' (moet ten minste de minrelay vergoeding van %s het voorkomen geplakt transacties voorkomen)</translation> + <translation>ongeldig bedrag voor -maxtxfee=<bedrag>: '%s' (moet ten minste de minimale doorgeeftransactiekosten van %s het voorkomen geplakt transacties voorkomen)</translation> </message> <message> <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> - <translation>Maximale grootte va n de gegevens in gegevensdrager transacties we relais en de mijnen -(default: %u)</translation> + <translation>Maximale grootte va n de gegevens in gegevensdragertransacties die we doorgeven en mijnen (standaard: %u)</translation> </message> <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> - <translation>Query voor peer- adressen via DNS- lookup , als laag op adressen (default: 1 unless -connect)</translation> + <translation>Query voor peeradressen via DNS- lookup , als laag op adressen (standaard: 1 unless -connect)</translation> + </message> + <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Gebruik willekeurige inloggegevens voor elke proxyverbinding. Dit maakt streamislatie voor Tor mogelijk (standaard: %u)</translation> </message> <message> <source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source> @@ -3039,46 +3269,19 @@ </message> <message> <source>The transaction amount is too small to send after the fee has been deducted</source> - <translation>Het transactiebedrag is te klein om te versturen nadat de vergoeding in mindering is gebracht</translation> + <translation>Het transactiebedrag is te klein om te versturen nadat de transactiekosten in mindering zijn gebracht</translation> </message> <message> <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> <translation>Dit product bevat software dat ontwikkeld is door het OpenSSL Project voor gebruik in de OpenSSL Toolkit <https://www.openssl.org/> en cryptografische software geschreven door Eric Young en UPnP software geschreven door Thomas Bernard.</translation> </message> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>Om bitcoind of de -server optie naar bitcoin-gt te gebruiken, dient u een rpcwachtwoord in te stellen in het configuratiebestand: - %s -Wij raden u aan om het volgende wachtwoord willekeurig te gebruiken: -rpcuser=bitcoinrpc -rpcpassword=%s -(u hoeft dit wachtwoord niet te onthouden) -De gebruikersnaam en het wachtwoorden moeten NIET hetzelfde zijn. -Indien het bestand niet bestaat, maak het bestand aan met bestandsrechten: alleen lezen voor eigenaar. -Het is ook aan te raden om een alarmnotificatie in te stellen, zodat u op de hoogte bent van de problemen; -Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Let op: -maxtxfee is erg hoog ingesteld! Transactiekosten van dergelijke groottes kunnen in een enkele transactie worden betaald.</translation> - </message> - <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>Waarschuwing: Controleer dat de datum en tijd van uw computer correct zijn ingesteld! Bij een onjuist ingestelde klok zal Bitcoin Core niet goed werken.</translation> + <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>Goedgekeurde peers kunnen niet ge-DoS-banned worden en hun transacties worden altijd doorgegeven, zelfs als ze reeds in de mempool aanwezig zijn, nuttig voor bijv. een gateway</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>Goedgekeurde peers kunnen niet ge-DoS-banned worden en hun transacties worden altijd doorgestuurd, zelfs als ze reeds in de mempool aanwezig zijn, nuttig voor bijv. een gateway</translation> + <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> + <translation>U moet de database herbouwen met -reindex om terug te gaan naar de ongesnoeide modus. Dit zal de gehele blokkketen opnieuw downloaden.</translation> </message> <message> <source>(default: %u)</source> @@ -3086,19 +3289,27 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla </message> <message> <source>Accept public REST requests (default: %u)</source> - <translation>Accepteer publieke REST-requests (standaard: %u)</translation> + <translation>Accepteer publieke REST-verzoeken (standaard: %u)</translation> </message> <message> <source>Activating best chain...</source> <translation>Beste reeks activeren...</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>Kan -whitebind adres niet herleiden: '%s'</translation> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>Geef transacties altijd door aan goedgekeurde peers (standaard: %d)</translation> + </message> + <message> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Probeer privésleutels te herstellen van een corrupte wallet.dat bij opstarten</translation> + </message> + <message> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Creëer automatisch verborgen dienst van Tor (standaard:%d)</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Kies de gegevensmap tijdens het opstarten (standaard: 0)</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Kan -whitebind adres niet herleiden: '%s'</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3109,10 +3320,6 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla <translation>Auteursrecht (C) 2009-%i De Bitcoin Core Ontwikkelaars</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Niet mogelijk om -rpcbind waarde %s te verwerken als netwerk adres</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> @@ -3121,12 +3328,8 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla <translation>Fout bij het lezen van de database, afsluiten. </translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Fout: Niet ondersteund argument -tor gevonden, gebruik -onion.</translation> - </message> - <message> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation>Transactiekosten (in BTC/kB) om toe te voegen aan transacties die u verstuurd (standaard: %s)</translation> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Importeer blokken van externe blk000??.dat-bestand bij opstarten</translation> </message> <message> <source>Information</source> @@ -3138,7 +3341,7 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla </message> <message> <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> - <translation>Ongeldig bedrag voor -maxtxfee=<amount>: '%s'</translation> + <translation>Ongeldig bedrag voor -maxtxfee=<bedrag>: '%s'</translation> </message> <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> @@ -3166,43 +3369,39 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla </message> <message> <source>Node relay options:</source> - <translation>Node relay opties:</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> + <translation>Nodedoorgeefopties:</translation> </message> <message> <source>RPC server options:</source> <translation>RPC server opties:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>RPC ondersteuning voor HTTP persisten verbindingen (default: %d)</translation> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Herbouwen blokketenindex vanuit huidige blk000??.dat-bestanden bij opstarten?</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> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Ontvang en toon P2P-netwerkwaarschuwingen (standaard: %u)</translation> </message> <message> - <source>Send transactions as zero-fee transactions if possible (default: %u)</source> - <translation>Verstuur transacties zonder verzendkosten indien mogelijk (standaard: %u)</translation> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> + <translation>Verminder -maxconnections van %d naar %d, vanwege systeembeperkingen.</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Zet SSL root certificaten voor betalingsverzoek (standaard: -sytem-)</translation> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Herscan de blokketen voor missende portemonneetransacties bij opstarten</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Stel taal in, bijvoorbeeld ''de_DE" (standaard: systeeminstellingen)</translation> + <source>Send trace/debug info to console instead of debug.log file</source> + <translation>Verzend trace/debug-info naar de console in plaats van het debug.log-bestand</translation> </message> <message> - <source>Show all debugging options (usage: --help -help-debug)</source> - <translation>Toon alle foutopsporingsopties (gebruik: --help -help-debug)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Indien mogelijk, verstuur zonder transactiekosten (standaard: %u)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Laat laadscherm zien bij het opstarten. (standaard: 1)</translation> + <source>Show all debugging options (usage: --help -help-debug)</source> + <translation>Toon alle foutopsporingsopties (gebruik: --help -help-debug)</translation> </message> <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> @@ -3213,18 +3412,22 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla <translation>Ondertekenen van transactie mislukt</translation> </message> <message> - <source>Start minimized</source> - <translation>Geminimaliseerd starten</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> - <translation>Het transactiebedrag is te klein om de vergoeding te betalen</translation> + <translation>Het transactiebedrag is te klein om transactiekosten in rekening te brengen</translation> </message> <message> <source>This is experimental software.</source> <translation>Dit is experimentele software.</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>Tor bepaalt poortwachtwoord (standaard: empty)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>Tor bepaalt welke poort te gebruiken als luisteren naar onion wordt gebruikt (standaard: %s)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Transactiebedrag te klein</translation> </message> @@ -3234,23 +3437,19 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla </message> <message> <source>Transaction too large for fee policy</source> - <translation>De transactie is te groot voor het toeslagenbeleid</translation> + <translation>De transactie is te groot voor het transactiekostenbeleid</translation> </message> <message> <source>Transaction too large</source> <translation>Transactie te groot</translation> </message> <message> - <source>UI Options:</source> - <translation>UI Opties:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Niet in staat om aan %s te binden op deze computer (bind gaf error %s)</translation> </message> <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> + <source>Upgrade wallet to latest format on startup</source> + <translation>Upgrade portemonee naar laatste formaat bij opstarten</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3265,20 +3464,16 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla <translation>Waarschuwing</translation> </message> <message> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation>Waarschuwing: Niet ondersteund argument -benchmark genegeerd, gebruik -debug=bench.</translation> - </message> - <message> - <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> - <translation>Waarschuwing: Niet ondersteund argument -debugnet genegeerd, gebruik -debug=net.</translation> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>Om in alleen een blokmodus te opereren (standaard: %u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> <translation>Bezig met het zappen van alle transacties van de portemonnee...</translation> </message> <message> - <source>on startup</source> - <translation>bij opstarten</translation> + <source>ZeroMQ notification options:</source> + <translation>ZeroMQ notificatieopties:</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3290,19 +3485,7 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla </message> <message> <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source> - <translation>Voer commando uit zodra het beste blok verandert (%s in cmd wordt vervangen door blockhash)</translation> - </message> - <message> - <source>Upgrade wallet to latest format</source> - <translation>Vernieuw portemonnee naar nieuwste versie</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Doorzoek de blokketen op ontbrekende portemonnee-transacties</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Gebruik OpenSSL (https) voor JSON-RPC-verbindingen</translation> + <translation>Voer opdracht uit zodra het beste blok verandert (%s in cmd wordt vervangen door blokhash)</translation> </message> <message> <source>This help message</source> @@ -3325,6 +3508,26 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla <translation>(1 = behoudt tx meta data bijv. account eigenaar en betalingsverzoek informatie, 2. sla tx meta data niet op)</translation> </message> <message> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>-maxtxfee staat zeer hoog! Transactiekosten van de grootte kunnen worden gebruikt in een enkele transactie.</translation> + </message> + <message> + <source>-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> + <translation>-paytxfee staat zeer hoog! Dit is de transactiekosten die u betaalt als u een transactie doet.</translation> + </message> + <message> + <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>Bewaar transactie niet langer dan <n> uren in de geheugenpool (standaard: %u)</translation> + </message> + <message> + <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> + <translation>Fout tijdens lezen van wallet.dat! Alle sleutels zijn correct te lezen, maar de transactiondatabase of adresboekingangen zijn mogelijk verdwenen of incorrect.</translation> + </message> + <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>Transactiekosten (in %s/kB) kleiner dan dit worden beschouwd dat geen transactiekosten in rekening worden gebracht voor transactiecreatie (standaard: %s)</translation> + </message> + <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Hoe grondig de blokverificatie van -checkblocks is (0-4, standaard: %u)</translation> </message> @@ -3338,15 +3541,35 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla </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> + <translation>Output extra debugginginformatie (standaard: %u, het leveren van <categorie> is optioneel)</translation> + </message> + <message> + <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> + <translation>Ondersteun filtering van blokken en transacties met bloomfilters (standaard: %u)</translation> + </message> + <message> + <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> + <translation>Totale lengte van netwerkversiestring (%i) overschrijdt maximale lengte (%i). Verminder het aantal of grootte van uacomments.</translation> + </message> + <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>Pogingen om uitgaand verkeer onder een bepaald doel te houden (in MiB per 24u), 0 = geen limiet (standaard: %d)</translation> + </message> + <message> + <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Niet-ondersteund argument -socks gevonden. Instellen van SOCKS-versie is niet meer mogelijk, alleen SOCKS5-proxies worden ondersteund.</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> + <translation>Gebruik een aparte SOCKS5 proxy om verborgen diensten van Tor te bereiken (standaard: %s)</translation> + </message> + <message> + <source>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source> + <translation>Gebruikersnaam en gehasht wachtwoord voor JSON-RPC-verbindingen. De velden <userpw> is in het formaat: <GEBRUIKERSNAAM>:<SALT>$<HASH>. Een kanoniek Pythonscript is inbegrepen in de share/rpcuser. Deze optie kan meerdere keren worden meegegeven</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Geaccepteerde versleutelingen (standaard: %s)</translation> + <source>(default: %s)</source> + <translation>(standaard: %s)</translation> </message> <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> @@ -3374,7 +3597,7 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla </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> + <translation>Luister naar JSON-RPC-verbindingen op <poort> (standaard: %u of testnet: %u)</translation> </message> <message> <source>Listen for connections on <port> (default: %u or testnet: %u)</source> @@ -3394,7 +3617,7 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla </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> + <translation>Maximum per-connectie verstuurbuffer, <n>*1000 bytes (standaard: %u)</translation> </message> <message> <source>Prepend debug output with timestamp (default: %u)</source> @@ -3402,23 +3625,15 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla </message> <message> <source>Relay and mine data carrier transactions (default: %u)</source> - <translation>Gegevensdrager transacties relay en de mijnen (default: %u)</translation> + <translation>Geef gegevensdragertransacties door en mijn ze ook (standaard: %u)</translation> </message> <message> <source>Relay non-P2SH multisig (default: %u)</source> - <translation>Relay non-P2SH multisig (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> + <translation>Geef non-P2SH multisig door (standaard: %u)</translation> </message> <message> <source>Set key pool size to <n> (default: %u)</source> - <translation>Stel sleutelpoelgrootte in op <&> (standaard: %u)</translation> + <translation>Stel sleutelpoelgrootte in op <n> (standaard: %u)</translation> </message> <message> <source>Set minimum block size in bytes (default: %u)</source> @@ -3430,7 +3645,7 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla </message> <message> <source>Specify configuration file (default: %s)</source> - <translation>Specificeer configuratie bestand (standaard: %s)</translation> + <translation>Specificeer configuratiebestand (standaard: %s)</translation> </message> <message> <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source> @@ -3442,7 +3657,7 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla </message> <message> <source>Spend unconfirmed change when sending transactions (default: %u)</source> - <translation>Besteed onbevestigd wisselgeld bij het versturen van transacties (standaard: %u)</translation> + <translation>Besteed onbevestigd wisselgeld bij het doen van transacties (standaard: %u)</translation> </message> <message> <source>Threshold for disconnecting misbehaving peers (default: %u)</source> @@ -3490,7 +3705,7 @@ Voorbeeld: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com</transla </message> <message> <source>Rescanning...</source> - <translation>Blokketen aan het doorzoeken...</translation> + <translation>Blokketen aan het herscannen...</translation> </message> <message> <source>Done loading</source> diff --git a/src/qt/locale/bitcoin_pam.ts b/src/qt/locale/bitcoin_pam.ts index 4939dff4b0..233918ff2b 100644 --- a/src/qt/locale/bitcoin_pam.ts +++ b/src/qt/locale/bitcoin_pam.ts @@ -1,4 +1,4 @@ -<TS language="pam" version="2.0"> +<TS language="pam" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -189,6 +189,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -247,6 +250,10 @@ <translation>&Alilan ing Passphrase...</translation> </message> <message> + <source>&Receiving addresses...</source> + <translation>Address king pamag-Tanggap</translation> + </message> + <message> <source>Send coins to a Bitcoin address</source> <translation>Magpadalang barya king Bitcoin address</translation> </message> @@ -307,6 +314,10 @@ <translation>Kapilubluban ning Bitcoin</translation> </message> <message> + <source>&Command-line options</source> + <translation>Pipamilian command-line</translation> + </message> + <message> <source>Last received block was generated %1 ago.</source> <translation>Ing tatauling block a metanggap, me-generate ya %1 ing milabas</translation> </message> @@ -361,6 +372,10 @@ <context> <name>CoinControlDialog</name> <message> + <source>Amount:</source> + <translation>Alaga:</translation> + </message> + <message> <source>Amount</source> <translation>Alaga</translation> </message> @@ -461,7 +476,7 @@ <source>command-line options</source> <translation>pipamilian command-line</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -637,6 +652,10 @@ <translation>&Impormasion</translation> </message> <message> + <source>Debug window</source> + <translation>I-Debug ing awang</translation> + </message> + <message> <source>Using OpenSSL version</source> <translation>Gagamit bersion na ning OpenSSL</translation> </message> @@ -715,6 +734,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>&Kopyan ing address</translation> + </message> + <message> <source>Address</source> <translation>Address</translation> </message> @@ -761,6 +784,18 @@ <translation>Magpadalang Barya</translation> </message> <message> + <source>Insufficient funds!</source> + <translation>Kulang a pondo</translation> + </message> + <message> + <source>Amount:</source> + <translation>Alaga:</translation> + </message> + <message> + <source>Transaction Fee:</source> + <translation>Bayad king Transaksion:</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Misanang magpadala kareng alialiuang tumanggap</translation> </message> @@ -839,6 +874,14 @@ <source>Alt+P</source> <translation>Alt+P</translation> </message> + <message> + <source>Message:</source> + <translation>Mensayi:</translation> + </message> + <message> + <source>Pay To:</source> + <translation>Ibayad kang:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -1327,18 +1370,10 @@ <translation>Gumana king gulut bilang daemon at tumanggap commands</translation> </message> <message> - <source>Use the test network</source> - <translation>Gamitan ing test network</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Tumanggap koneksion menibat king kilwal (default: 1 if no -proxy or -connect)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Kapabaluan: Sobra ya katas ing makalage king -paytxfee. Ini ing maging bayad mu para king bayad na ning transaksion istung pepadala me ing transaksion a ini.</translation> - </message> - <message> <source>Block creation options:</source> <translation>Pipamilian king pamag-gawang block:</translation> </message> @@ -1371,24 +1406,28 @@ <translation>Memali ya ing pamakiramdam kareng gang nanung port. Gamita me ini -listen=0 nung buri me ini.</translation> </message> <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Eya me-resolve ing -whitebind address: '%s'</translation> + </message> + <message> <source>Information</source> <translation>&Impormasion</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Magpadalang trace/debug info okeng console kesa keng debug.log file</translation> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Eya maliari ing alaga keng -maxtxfee=<amount>: '%s'</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Mamiling Amanu, alimbawa "de_DE"(default: system locale)</translation> + <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> + <translation>Eya maliari ing alaga keng -minrelaytxfee=<amount>: '%s'</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Ipalto ing splash screen keng umpisa (default: 1)</translation> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>Eya maliari ing alaga keng -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>Start minimized</source> - <translation>Umpisan ing pamaglati</translation> + <source>Send trace/debug info to console instead of debug.log file</source> + <translation>Magpadalang trace/debug info okeng console kesa keng debug.log file</translation> </message> <message> <source>Transaction too large</source> @@ -1411,18 +1450,6 @@ <translation>I-execute ing command istung mialilan ya ing best block (%s in cmd is replaced by block hash)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>I-upgrade ing wallet king pekabayung porma</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Gumamit OpenSSL(https) para king JSON-RPC koneksion</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 5bc7df0aca..8a8c377480 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -1,4 +1,4 @@ -<TS language="pl" version="2.0"> +<TS language="pl" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/Maska Sieci</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Blokada do</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -867,6 +878,34 @@ <source>command-line options</source> <translation>opcje konsoli</translation> </message> + <message> + <source>UI Options:</source> + <translation>Opcje interfejsu</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Katalog danych używany podczas uruchamiania programu (domyślny: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Wybierz język, na przykład "de_DE" (domyślnie: język systemowy)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Uruchom zminimalizowany</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Ustaw certyfikaty główne SSL dla żądań płatności (domyślnie: -system-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Wyświetl okno powitalne podczas uruchamiania (domyślnie: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Ustaw jako domyślne wszystkie ustawienia interfejsu</translation> + </message> </context> <context> <name>Intro</name> @@ -1065,6 +1104,26 @@ <translation>Port proxy (np. 9050)</translation> </message> <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Pokazuje, czy wspierane domyślnie proxy SOCKS5 jest używane do łączenia się z peerami w tej sieci</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Użyj oddzielnego prozy SOCKS5 aby osiągnąć węzły w ukrytych usługach Tor:</translation> + </message> + <message> <source>&Window</source> <translation>&Okno</translation> </message> @@ -1283,10 +1342,6 @@ <translation>Żądanie płatności %1 jest zbyt duże (%2 bajtów, dozwolone %3 bajtów).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Zabezpieczenie żądania płatności przed atakiem DoS</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Błąd komunikacji z %1 : %2</translation> </message> @@ -1439,6 +1494,14 @@ <translation>Aktualna liczba bloków</translation> </message> <message> + <source>Current number of transactions</source> + <translation>Obecna liczba transakcji</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Zużycie pamięci</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>Otwórz plik logowania debugowania Bitcoin Core z obecnego katalogu z danymi. Może to potrwać kilka sekund przy większych plikach.</translation> </message> @@ -1455,10 +1518,18 @@ <translation>&Węzły</translation> </message> <message> + <source>Banned peers</source> + <translation>Blokowane węzły</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Wybierz węzeł żeby zobaczyć szczegóły.</translation> </message> <message> + <source>Whitelisted</source> + <translation>Biała lista</translation> + </message> + <message> <source>Direction</source> <translation>Kierunek</translation> </message> @@ -1467,20 +1538,24 @@ <translation>Wersja</translation> </message> <message> - <source>User Agent</source> - <translation>Aplikacja kliencka</translation> + <source>Starting Block</source> + <translation>Blok startowy</translation> </message> <message> - <source>Services</source> - <translation>Usługi</translation> + <source>Synced Headers</source> + <translation>Zsynchronizowane nagłówki</translation> </message> <message> - <source>Starting Height</source> - <translation>Początkowa wysokość</translation> + <source>Synced Blocks</source> + <translation>Zsynchronizowane bloki</translation> + </message> + <message> + <source>User Agent</source> + <translation>Aplikacja kliencka</translation> </message> <message> - <source>Sync Height</source> - <translation>Zsynchronizowana wysokość</translation> + <source>Services</source> + <translation>Usługi</translation> </message> <message> <source>Ban Score</source> @@ -1499,15 +1574,11 @@ <translation>Ostatnio odebrano</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Bajtów wysłano</translation> - </message> - <message> - <source>Bytes Received</source> - <translation>Bajtów pobrano</translation> + <source>Ping Time</source> + <translation>Czas odpowiedzi</translation> </message> <message> - <source>Ping Time</source> + <source>Ping Wait</source> <translation>Czas odpowiedzi</translation> </message> <message> @@ -1559,6 +1630,14 @@ <translation>Wyczyść konsolę</translation> </message> <message> + <source>Ban Node for</source> + <translation>Blokuj węzeł na okres</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>Odblokuj węzeł</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Witaj w konsoli Bitcoin Core RPC.</translation> </message> @@ -1587,6 +1666,10 @@ <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(id węzła: %1)</translation> + </message> + <message> <source>via %1</source> <translation>przez %1</translation> </message> @@ -1603,12 +1686,16 @@ <translation>Wyjściowy</translation> </message> <message> - <source>Unknown</source> - <translation>Nieznany</translation> + <source>Yes</source> + <translation>Tak</translation> + </message> + <message> + <source>No</source> + <translation>Nie</translation> </message> <message> - <source>Fetching...</source> - <translation>Pobieram...</translation> + <source>Unknown</source> + <translation>Nieznany</translation> </message> </context> <context> @@ -1630,6 +1717,10 @@ <translation>Użyj jednego z poprzednio użytych adresów odbiorczych. Podczas ponownego używania adresów występują problemy z bezpieczeństwem i prywatnością. Nie korzystaj z tej opcji, chyba że odtwarzasz żądanie płatności wykonane już wcześniej.</translation> </message> <message> + <source>R&euse an existing receiving address (not recommended)</source> + <translation>U&żyj ponownie istniejącego adresu odbiorczego (niepolecane)</translation> + </message> + <message> <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source> <translation>Opcjonalna wiadomość do dołączenia do żądania płatności, która będzie wyświetlana, gdy żądanie zostanie otwarte. Uwaga: wiadomość ta nie zostanie wysłana wraz z płatnością w sieci Bitcoin.</translation> </message> @@ -1971,8 +2062,8 @@ <translation>Skopiuj resztę</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Łączna kwota %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Łączna kwota %1</translation> </message> <message> <source>or</source> @@ -2006,15 +2097,15 @@ <source>Payment request expired.</source> <translation>Żądanie płatności upłynęło.</translation> </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>Zapłać tylko wymaganą opłatę %1</translation> + </message> <message numerus="yes"> <source>Estimated to begin confirmation within %n block(s).</source> <translation><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Płac tylko minimalna opłatę %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>Adres odbiorcy jest nieprawidłowy, proszę sprawić ponownie.</translation> </message> @@ -2642,6 +2733,10 @@ <translation>Skopiuj ID transakcji</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>Skopiuj surowe dane transakcji</translation> + </message> + <message> <source>Edit label</source> <translation>Zmień etykietę</translation> </message> @@ -2789,12 +2884,24 @@ <translation>Akceptuj linię poleceń oraz polecenia JSON-RPC</translation> </message> <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Błąd: Wystąpił fatalny błąd wewnętrzny, sprawdź szczegóły w debug.log</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Prowizja (w %s/kB) dodawana do wysyłanych transakcji (domyślnie: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Przycinanie zapisu bloków...</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>Uruchom w tle jako daemon i przyjmuj polecenia</translation> </message> <message> - <source>Use the test network</source> - <translation>Użyj sieci testowej</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>Uruchomienie serwera HTTP nie powiodło się. Zobacz dziennik debugowania, aby uzyskać więcej szczegółów.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2829,8 +2936,12 @@ <translation>Nie można przywiązać z portem %s na tym komputerze. Bitcoin Core prawdopodobnie już działa.</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>Ostrzeżenie: -paytxfee jest bardzo duże! Jest to prowizja za transakcje, którą płacisz, gdy wysyłasz monety.</translation> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>UWAGA: nienaturalnie duża liczba wygenerowanych bloków, %d bloków otrzymano w ostatnich %d godzinach (%d oczekiwanych)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>UWAGA: sprawdź swoje połączenie sieciowe, %d bloków otrzymano w ostatnich %d godzinach (%d oczekiwanych)</translation> </message> <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> @@ -2841,10 +2952,6 @@ <translation>Uwaga: Wygląda na to, że nie ma pełnej zgodności z naszymi peerami! Możliwe, że potrzebujesz aktualizacji bądź inne węzły jej potrzebują</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>Ostrzeżenie: błąd odczytu wallet.dat! Wszystkie klucze zostały odczytane, ale może brakować pewnych danych transakcji lub wpisów w książce adresowej lub mogą one być nieprawidłowe.</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>Ostrzeżenie: Odtworzono dane z uszkodzonego pliku wallet.dat! Oryginalny wallet.dat został zapisany jako wallet.{timestamp}.bak w %s; jeśli twoje saldo lub transakcje są niepoprawne powinieneś odtworzyć kopię zapasową.</translation> </message> @@ -2853,18 +2960,10 @@ <translation>Dodawaj do białej listy węzły łączące się z podanej maski sieciowej lub adresu IP. Może być określona kilka razy.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(domyślnie: 1)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> mogą być:</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> - <message> <source>Block creation options:</source> <translation>Opcje tworzenia bloku:</translation> </message> @@ -2909,10 +3008,6 @@ <translation>Błąd otwierania bazy bloków</translation> </message> <message> - <source>Error: A fatal internal error occured, see debug.log for details</source> - <translation>Błąd: Wystąpił krytyczny błąd wewnętrzny, sprawdź w debug.log</translation> - </message> - <message> <source>Error: Disk space is low!</source> <translation>Błąd: Mało miejsca na dysku!</translation> </message> @@ -2921,10 +3016,6 @@ <translation>Próba nasłuchiwania na jakimkolwiek porcie nie powiodła się. Użyj -listen=0 jeśli tego chcesz.</translation> </message> <message> - <source>If <category> is not supplied, output all debugging information.</source> - <translation>Jeżeli <category> nie zostanie określona, wyświetl wszystkie informacje debugowania.</translation> - </message> - <message> <source>Importing...</source> <translation>Importowanie…</translation> </message> @@ -2945,6 +3036,10 @@ <translation>Łącz z węzłami tylko w sieci <net> (ipv4, piv6 lub onion)</translation> </message> <message> + <source>Prune cannot be configured with a negative value.</source> + <translation>Przycinanie nie może być skonfigurowane z negatywną wartością.</translation> + </message> + <message> <source>Prune mode is incompatible with -txindex.</source> <translation>Tryb ograniczony jest niekompatybilny z -txindex.</translation> </message> @@ -2961,6 +3056,14 @@ <translation>Określ plik portfela (w obrębie folderu danych)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Niewspierany argument -benchmark zignorowany, użyj -debug=bench.</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Niewspierany argument -debugnet zignorowany, użyj -debug=net.</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Użyj UPnP do przekazania portu nasłuchu (domyślnie : %u)</translation> </message> @@ -2989,18 +3092,10 @@ <translation>Musisz przebudować bazę używając parametru -reindex aby zmienić -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importuj bloki z zewnętrznego pliku 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>Pozwól na połączenia JSON-RPC z podanego źródła. Jako <ip> prawidłowe jest pojedyncze IP (np. 1.2.3.4), podsieć/maska (np. 1.2.3.4/255.255.255.0) lub sieć/CIDR (np. 1.2.3.4/24). Opcja ta może być użyta wiele razy.</translation> </message> <message> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation>Napotkano błąd podczas ustawiania adres RPC %s port %u dla nasłuchiwania: %s</translation> - </message> - <message> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> <translation>Podepnij się do podanego adresu i dodawaj do białej listy węzły łączące się z nim. Użyj notacji [host]:port dla IPv6</translation> </message> @@ -3017,22 +3112,18 @@ <translation>Twórz nowe pliki z domyślnymi dla systemu uprawnieniami, zamiast umask 077 (skuteczne tylko przy wyłączonej funkcjonalności portfela)</translation> </message> <message> - <source>Error: Listening for incoming connections failed (listen returned error %s)</source> - <translation>Błąd: Nasłuchiwanie połączeń przychodzących nie powiodło się (nasłuch zwrócił błąd %s)</translation> + <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> + <translation>Odkryj własny adres IP (domyślnie: 1 kiedy w trybie nasłuchu i brak -externalip lub -proxy)</translation> </message> <message> - <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> - <translation>Błąd: Znaleziono niewspierany argument -socks . Ustawienie wersji SOCKS nie jest już możliwe, tylko serwery proxy SOCKS5 są wspierane.</translation> + <source>Error: Listening for incoming connections failed (listen returned error %s)</source> + <translation>Błąd: Nasłuchiwanie połączeń przychodzących nie powiodło się (nasłuch zwrócił błąd %s)</translation> </message> <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>Uruchom polecenie przy otrzymaniu odpowiedniego powiadomienia lub gdy zobaczymy naprawdę długie rozgałęzienie (%s w poleceniu jest podstawiane za komunikat)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Opłaty (w BTC/Kb) mniejsze niż ta będą traktowane jako bez opłaty przy propagowaniu (domyślnie: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Jeżeli nie ustawiono paytxfee, dołącz wystarczająca opłatę, aby transakcja mogła zostać zatwierdzona w ciągu średniej ilości n bloków (domyślnie: %u)</translation> </message> @@ -3065,38 +3156,6 @@ <translation>Program ten zawiera oprogramowanie stworzone przez OpenSSL Project do użycia w OpensSSL Toolkit <https://www.openssl.org/>, oprogramowanie kryptograficzne napisane przez Eric Young oraz oprogramowanie UPnP napisane przez Thomas Bernard.</translation> </message> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>Aby korzystać z bitcoind, lub opcji -server w bitcoin-qt, musisz ustawić opcję rpcpassword w pliku konfiguracyjnym: -%s -Zalecane jest użycie poniższego losowego hasła: -rpcuser=bitcoinrpc -rpcpassword=%s -(nie musisz pamiętać tego hasła) -Nazwa użytkownika i hasło NIE MOGĄ być takie same. -Jeżeli ten plik nie istnieje, utwórz go z uprawnieniami tylko-do-odczytu przez właściciela. -Zalecane jest także ustawienie opcji alertnotify, dzięki której będziesz powiadamiany o problemach; -na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Ostrzeżenie: -matxfee jest ustawione bardzo wysokie! Tak wysokie opłaty mogą być zapłacone w jednej transakcji.</translation> - </message> - <message> - <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> - <translation>Ostrzeżenie: Proszę sprawdzić czy data i czas na Twoim komputerze są poprawne! Jeżeli ustawienia zegara będą złe, Bitcoin Core nie będzie działał prawidłowo.</translation> - </message> - <message> <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source> <translation>Węzły z białej listy nie mogą zostać zbanowane za ataki DoS, a ich transakcje będą zawsze przekazywane, nawet jeżeli będą znajdywać się już w pamięci, przydatne np. dla bramek płatniczych</translation> </message> @@ -3113,16 +3172,20 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>Aktywuje najlepszy łańcuch</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>Nie można uruchomić z portfela w trybie ograniczonym.</translation> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>Zawsze przekazuj informacje o transakcjach otrzymanych od osób z białej listy (domyślnie: %d)</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>Nie można rozwiązać adresu -whitebind: '%s'</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Próbuj podczas uruchamiania programu odzyskać klucze prywatne z uszkodzonego pliku wallet.dat</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Wybierz folder danych przy starcie (domyślnie: 0)</translation> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Stwórz automatycznie ukrytą usługę Tora (domyślnie: %d)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Nie można rozwiązać adresu -whitebind: '%s'</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3133,10 +3196,6 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Nie można przetworzyć wartości -rpcbind %s jako adresu sieciowego</translation> - </message> - <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Błąd ładowania wallet.dat: Portfel wymaga nowszej wersji Bitcoin Core</translation> </message> @@ -3145,12 +3204,8 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>Błąd odczytu z bazy danych, wyłączam się.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Błąd: Znaleziono nieprawidłowy argument -tor, użyj -onion.</translation> - </message> - <message> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation>Prowizja (w BTC za kB) dodawana do wysyłanej transakcji (domyślnie: %s)</translation> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Importuj bloki z zewnętrznego pliku blk000??.dat podczas uruchamiania programu</translation> </message> <message> <source>Information</source> @@ -3185,22 +3240,18 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>Przechowuj w pamięci maksymalnie <n> transakcji nie możliwych do połączenia (domyślnie: %u)</translation> </message> <message> - <source>Node relay options:</source> - <translation>Opcje przekaźnikowe węzła:</translation> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>Musisz określić port z -whitebind: '%s'</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> + <source>Node relay options:</source> + <translation>Opcje przekaźnikowe węzła:</translation> </message> <message> <source>RPC server options:</source> <translation>Opcje serwera RPC:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>Wsparcie RPC dla ciągłych połączeń HTTP (domyślnie: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Odbuduj indeks łańcucha bloków z obecnych plików blk000??.dat podczas ponownego uruchomienia</translation> </message> @@ -3209,6 +3260,10 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>Odbieranie i wyświetlanie alertów sieci P2P (domyślnie: %u)</translation> </message> <message> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Przeskanuj podczas ładowania programu łańcuch bloków w poszukiwaniu zaginionych transakcji portfela</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> @@ -3217,22 +3272,10 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>Wyślij bez opłaty jeżeli to możliwe (domyślnie: %u)</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Ustaw certyfikaty główne SSL dla żądań płatności (domyślnie: -system-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Ustaw Język, na przykład "pl_PL" (domyślnie: systemowy)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Pokaż wszystkie opcje odpluskwiania (użycie: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Pokazuj okno powitalne przy starcie (domyślnie: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Zmniejsz plik debug.log przy starcie programu (domyślnie: 1 jeśli nie użyto -debug)</translation> </message> @@ -3241,10 +3284,6 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>Podpisywanie transakcji nie powiodło się</translation> </message> <message> - <source>Start minimized</source> - <translation>Uruchom zminimalizowany</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>Zbyt niska kwota transakcji by zapłacić opłatę</translation> </message> @@ -3253,6 +3292,10 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>To oprogramowanie eksperymentalne.</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>Hasło zabezpieczające portu kontrolnego Tora (domyślnie: puste)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Zbyt niska kwota transakcji </translation> </message> @@ -3269,16 +3312,12 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>Transakcja zbyt duża</translation> </message> <message> - <source>UI Options:</source> - <translation>Opcje UI</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Nie można przywiązać do %s na tym komputerze (bind zwrócił błąd %s)</translation> </message> <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> + <source>Upgrade wallet to latest format on startup</source> + <translation>Zaktualizuj portfel do najnowszego formatu podczas ładowania programu</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3293,22 +3332,10 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>Ostrzeżenie</translation> </message> <message> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation>Uwaga: Zignorowano nieprawidłowy argument -benchmark, użyj -debug=bench.</translation> - </message> - <message> - <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> - <translation>Uwaga: Zignorowano nieprawidłowy argument -debugnet , użyj -debug=net.</translation> - </message> - <message> <source>Zapping all transactions from wallet...</source> <translation>Usuwam wszystkie transakcje z portfela...</translation> </message> <message> - <source>on startup</source> - <translation>podczas uruchamiania</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat uszkodzony, odtworzenie się nie powiodło</translation> </message> @@ -3321,18 +3348,6 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>Wykonaj polecenie kiedy najlepszy blok ulegnie zmianie (%s w komendzie zastanie zastąpione przez hash bloku)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Zaktualizuj portfel do najnowszego formatu.</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Przeskanuj łańcuch bloków w poszukiwaniu zaginionych transakcji portfela</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Użyj OpenSSL (https) do połączeń JSON-RPC</translation> - </message> - <message> <source>This help message</source> <translation>Ta wiadomość pomocy</translation> </message> @@ -3353,6 +3368,14 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>(1 = zachowaj wysłane metadane np. właściciel konta i informacje o żądaniach płatności, 2 = porzuć wysłane metadane)</translation> </message> <message> + <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>Nie trzymaj w pamięci transakcji starszych niż <n> godzin (domyślnie: %u)</translation> + </message> + <message> + <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> + <translation>Ostrzeżenie: błąd odczytu wallet.dat! Wszystkie klucze zostały odczytane, ale może brakować pewnych danych transakcji lub wpisów w książce adresowej lub mogą one być nieprawidłowe.</translation> + </message> + <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Jak dokładna jest weryfikacja bloków przy -checkblocks (0-4, domyślnie: %u)</translation> </message> @@ -3369,6 +3392,10 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>Wypuść informacje debugowania (domyślnie: %u, podanie <category> jest opcjonalne)</translation> </message> <message> + <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Znaleziono niewspierany argument -socks. Wybieranie wersji SOCKS nie jest już możliwe, wsparcie programu obejmuje tylko proxy SOCKS5</translation> + </message> + <message> <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> <translation>Użyj oddzielnego prozy SOCKS5 aby osiągnąć węzły w ukrytych usługach Tor (domyślnie: %s)</translation> </message> @@ -3377,10 +3404,6 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>(domyślnie: %s)</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Akceptowane szyfry (domyślne: %s)</translation> - </message> - <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> <translation>Zawsze wypytuj o adresy węzłów poprzez podejrzenie DNS (domyślnie: %u)</translation> </message> @@ -3441,14 +3464,6 @@ na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com <translation>Przekazuj transakcje multisig inne niż P2SH (domyślnie: %u)</translation> </message> <message> - <source>Server certificate file (default: %s)</source> - <translation>Plik certyfikatu serwera (domyślnie: %s)</translation> - </message> - <message> - <source>Server private key (default: %s)</source> - <translation>Klucz prywatny serwera (domyślnie: %s)</translation> - </message> - <message> <source>Set key pool size to <n> (default: %u)</source> <translation>Ustaw rozmiar puli kluczy na <n> (domyślnie: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index cd2a5a6323..5cea349fbc 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.0"> +<TS language="pt_BR" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -67,7 +67,7 @@ </message> <message> <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source> - <translation>Esses são seus endereços Bitcoin para enviar pagamentos. Certifique-se sempre da quantia e do destinatário antes de enviar moedas.</translation> + <translation>Esses são seus endereços Bitcoin para enviar pagamentos. Confira sempre a quantia e o destinatário antes de enviar moedas.</translation> </message> <message> <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/Máscara</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Banido até</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -376,7 +387,7 @@ </message> <message> <source>&Settings</source> - <translation>&Configurações</translation> + <translation>&definições</translation> </message> <message> <source>&Help</source> @@ -431,6 +442,10 @@ <translation>Nenhum servidor disponível...</translation> </message> <message numerus="yes"> + <source>Processed %n block(s) of transaction history.</source> + <translation><numerusform>%n bloco processado do histórico de transações.</numerusform><numerusform>%n blocos processados do histórico de transações.</numerusform></translation> + </message> + <message numerus="yes"> <source>%n hour(s)</source> <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation> </message> @@ -867,6 +882,34 @@ <source>command-line options</source> <translation>opções da linha de comando</translation> </message> + <message> + <source>UI Options:</source> + <translation>Opções de Interface:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Escolher diretório de dados na inicialização (padrão: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Definir idioma, por exemplo "de_DE" (padrão: idioma do sistema)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Iniciar minimizado</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Definir certificados de root SSL para requisições de pagamento (padrão: -sistema-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Exibir tela de abertura na inicialização (padrão: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Desfazer todas as mudanças de configuração feitas na interface</translation> + </message> </context> <context> <name>Intro</name> @@ -1065,6 +1108,34 @@ <translation>Porta do serviço de proxy (ex. 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Usado para alcançar participantes via:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Exibe, caso o proxy padrão SOCKS5 fornecido seja usado para se conectar a peers através deste tipo de rede.</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Conecte-se à rede Bitcoin através de um proxy SOCKS5 separado para utilizar serviços ocultos Tor.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Use um proxy SOCKS5 separado para alcançar participantes da rede via serviços ocultos Tor:</translation> + </message> + <message> <source>&Window</source> <translation>&Janela</translation> </message> @@ -1227,6 +1298,10 @@ <translation>Solicitação de pagamento rejeitada</translation> </message> <message> + <source>Payment request network doesn't match client network.</source> + <translation>Rede de pedido de pagamento não corresponde rede do cliente.</translation> + </message> + <message> <source>Payment request is not initialized.</source> <translation>Pedido de pagamento não é inicializado.</translation> </message> @@ -1247,10 +1322,18 @@ <translation>URL de cobrança é invá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>URI não pode ser analisado ! Isto pode ser causado por um endereço Bitcoin inválido ou parâmetros URI informados incorretamente.</translation> + </message> + <message> <source>Payment request file handling</source> <translation>Manipulação de arquivo de cobrança</translation> </message> <message> + <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source> + <translation>Arquivo de pedido de pagamento não pode ser lido ! Isto pode ser causado por uma requisição de pagamento inválida.</translation> + </message> + <message> <source>Payment request expired.</source> <translation>Pedido de pagamento expirado.</translation> </message> @@ -1271,10 +1354,6 @@ <translation>Pedido de pagamento %1 é muito grande (%2 bytes, permitido %3 bytes).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Pagamento requer proteção DoS</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Erro na comunicação com %1: %2</translation> </message> @@ -1427,6 +1506,18 @@ <translation>Quantidade atual de blocos</translation> </message> <message> + <source>Memory Pool</source> + <translation>Pool de Memória</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>Número atual de transações</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Uso de memória</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>Abrir o arquivo de log de depuração do Bitcoin na pasta de dados atual. Isso pode demorar para arquivos grandes.</translation> </message> @@ -1443,10 +1534,18 @@ <translation>&Pares</translation> </message> <message> + <source>Banned peers</source> + <translation>Nós banidos</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Selecione um cliente para ver informações detalhadas.</translation> </message> <message> + <source>Whitelisted</source> + <translation>Lista branca</translation> + </message> + <message> <source>Direction</source> <translation>Direção</translation> </message> @@ -1455,20 +1554,24 @@ <translation>Versão</translation> </message> <message> - <source>User Agent</source> - <translation>User Agent</translation> + <source>Starting Block</source> + <translation>Bloco inicial</translation> </message> <message> - <source>Services</source> - <translation>Serviços</translation> + <source>Synced Headers</source> + <translation>Cabeçalhos Sincronizados</translation> </message> <message> - <source>Starting Height</source> - <translation>Altura inicial</translation> + <source>Synced Blocks</source> + <translation>Blocos Sincronizados</translation> </message> <message> - <source>Sync Height</source> - <translation>Altura sincronizada</translation> + <source>User Agent</source> + <translation>User Agent</translation> + </message> + <message> + <source>Services</source> + <translation>Serviços</translation> </message> <message> <source>Ban Score</source> @@ -1487,16 +1590,20 @@ <translation>Ultimo Recebido</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Bytes Enviados</translation> + <source>Ping Time</source> + <translation>Ping</translation> </message> <message> - <source>Bytes Received</source> - <translation>Bytes recebidos</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>A duração de um ping excepcional no momento.</translation> </message> <message> - <source>Ping Time</source> - <translation>Ping</translation> + <source>Ping Wait</source> + <translation>Espera de ping</translation> + </message> + <message> + <source>Time Offset</source> + <translation>Offset de tempo</translation> </message> <message> <source>Last block time</source> @@ -1543,6 +1650,34 @@ <translation>Limpar console</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>&Desconectar Nó</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Banir nó por</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &hora</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &dia</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &semana</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &ano</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>&Desbanir nó</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Bem vindo ao console de RPC do Bitcoin.</translation> </message> @@ -1571,6 +1706,10 @@ <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(id do nó: %1)</translation> + </message> + <message> <source>via %1</source> <translation>por %1</translation> </message> @@ -1587,12 +1726,16 @@ <translation>Saída</translation> </message> <message> - <source>Unknown</source> - <translation>Desconhecido</translation> + <source>Yes</source> + <translation>Sim</translation> + </message> + <message> + <source>No</source> + <translation>Não</translation> </message> <message> - <source>Fetching...</source> - <translation>Buscando...</translation> + <source>Unknown</source> + <translation>Desconhecido</translation> </message> </context> <context> @@ -1816,7 +1959,7 @@ </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>Se isso estiver ativo e o endereço de troco estiver vazio ou inválido, o troco será enviado a um novo endereço gerado na hora.</translation> + <translation>Se essa opção for ativada e o endereço de troco estiver vazio ou inválido, o troco será enviado a um novo endereço gerado na hora.</translation> </message> <message> <source>Custom change address</source> @@ -1959,8 +2102,8 @@ <translation>Copia alteração</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Quantidade Total %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Quantia Total %1</translation> </message> <message> <source>or</source> @@ -1994,15 +2137,15 @@ <source>Payment request expired.</source> <translation>Pedido de pagamento expirado.</translation> </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>Pagar somente a taxa requerida de %1</translation> + </message> <message numerus="yes"> <source>Estimated to begin confirmation within %n block(s).</source> <translation><numerusform>Confirmação estimada em %n bloco.</numerusform><numerusform>Confirmação estimada em %n blocos.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Pagar somente a taxa mínima de %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>O endereço do destinatário é inválido. Favor confirmar.</translation> </message> @@ -2083,7 +2226,7 @@ </message> <message> <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> - <translation>A taxa será deduzida da quantia sendo enviada. O beneficiario receberá menos bitcoins do que você colocou no campo de quantidade. Se varios beneficiarios estão selecionados, a taxa é dividida igualmente.</translation> + <translation>A taxa será deduzida da quantia sendo enviada. O destinatário receberá menos bitcoins do que você colocou no campo de quantidade. Se varios destinatários estão selecionados, a taxa é dividida igualmente.</translation> </message> <message> <source>S&ubtract fee from amount</source> @@ -2122,7 +2265,7 @@ <name>ShutdownWindow</name> <message> <source>Bitcoin Core is shutting down...</source> - <translation>Bitcoin está desligando...</translation> + <translation>Bitcoin está sendo encerrado...</translation> </message> <message> <source>Do not shut down the computer until this window disappears.</source> @@ -2140,6 +2283,10 @@ <translation>&Assinar mensagem</translation> </message> <message> + <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> + <translation>Você pode assinar mensagens com seus endereços para provar que você pode receber bitcoins enviados por alguém. Cuidado para não assinar nada vago ou aleatório, pois ataques phishing podem tentar te enganar para assinar coisas para eles como se fosse você. Somente assine termos bem detalhados que você concorde.</translation> + </message> + <message> <source>The Bitcoin address to sign the message with</source> <translation>O enderesso Bitcoin que assinará a mensagem</translation> </message> @@ -2192,6 +2339,10 @@ <translation>&Verificar mensagem</translation> </message> <message> + <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> + <translation>Coloque o endereço do destinatário, a mensagem (certifique-se de copiar toda a mensagem, incluindo quebras de linha, espaços, tabulações, etc.) e a assinatura embaixo para verificar a mensagem. Cuidado para não ler mais da assinatura do que está assinado na mensagem, para evitar ser enganado pelo ataque man-in-the-middle. Note que isso somente prova a propriedade de um endereço, e não o remetende de qualquer transação.</translation> + </message> + <message> <source>The Bitcoin address the message was signed with</source> <translation>O enderesso Bitcoin que assionou a mesnagem</translation> </message> @@ -2543,6 +2694,10 @@ <translation>Mostrar ou não endereços Bitcoin na lista de transações.</translation> </message> <message> + <source>User-defined intent/purpose of the transaction.</source> + <translation>Intenção/Propósito definido pelo usuário para a transação</translation> + </message> + <message> <source>Amount removed from or added to balance.</source> <translation>Quantidade debitada ou creditada ao saldo.</translation> </message> @@ -2622,6 +2777,10 @@ <translation>Copiar ID da transação</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>Copia os dados brutos da transação</translation> + </message> + <message> <source>Edit label</source> <translation>Editar rótulo</translation> </message> @@ -2769,12 +2928,52 @@ <translation>Aceitar linha de comando e comandos JSON-RPC</translation> </message> <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>Se <category> não for suprida ou se <category> = 1, mostrar toda informação de depuração.</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Total máximo de comissão (em %s) que será usado em uma única transação; um valor muito baixo pode cancelar uma transação grande (padrão: %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Por favor verifique se a data e horário estão corretos no seu computador! Se o seu relógio estiver incorreto, a Carteira Bitcoin não irá funcionar corretamente.</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>Corte configurado abaixo do nível mínimo de %d de MiB. Por favor use um número mais alto.</translation> + </message> + <message> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation>Corte: a ultima sincronização da carteira foi além do dado comprimido. Você precisa reindexar ( -reindex , faça o download de toda a blockchain novamente)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Reduza os requerimentos de armazenamento de dados (cortando) deletando blocos mais antigos. Esse modo é incompatível com -txindex e -rescan. Cuidado: Reverter essa configuração requer um novo download de toda a blockchain. (Padrão: 0 = desabilita o corte de blocos, >%u = tamanho alvo em MiB para o uso de blocos cortados)</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>Rescans não são possíveis no modo de corte. Você precisa usar -reindex, que irá fazer o download de toda a blockchain novamente.</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Erro: Um erro interno fatal ocorreu, veja debug.log para detalhes</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Taxa (em %s/kB) a ser adicionada às transações que você mandar (padrão: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Prunando os blocos existentes...</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>Rodar em segundo plano como serviço e aceitar comandos</translation> </message> <message> - <source>Use the test network</source> - <translation>Usar rede de teste</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>Não foi possível iniciar o servidor HTTP. Veja o log para detaihes.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2797,14 +2996,14 @@ <translation>Executa um comando quando uma transação da carteira mudar (%s no comando será substituído por TxID)</translation> </message> <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Reduz o armazenamento requerido prunando (apagando) blocos antigos. Este modo desativa o suporte a carteira e é incompatível com -txindex. Aviso: Reverter essa opção requer re-baixar o blockchain inteiro. (padrão: 0 = disativado, >%u = Tamanho em mega para os arquivos de bloco)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <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>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>O banco de dados de blocos contém um bloco que parece ser do futuro. Isso pode ser devido à data e hora do seu computador estarem configuradas incorretamente. Apenas reconstrua o banco de dados de blocos se você estiver certo de que a data e hora de seu computador estão corretas.</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> @@ -2813,8 +3012,16 @@ <translation>Impossível ouvir em %s neste computador. Provavelmente o Bitcoin já está sendo executado.</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> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>Use UPnP para mapear a porta escutada (padrão: 1 quando escutando e sem -proxy)</translation> + </message> + <message> + <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> + <translation>AVISO: números estranhamente altos de blocos gerados, %d blocos recebidos nas últimas %d horas (%d esperados)</translation> + </message> + <message> + <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source> + <translation>ATENÇÃO: verifique sua conexão %d blocos recebidos nas últimas %d horas (%d tempo estimado)</translation> </message> <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> @@ -2825,10 +3032,6 @@ <translation>Atenção: Nós não parecemos concordar plenamente com nossos colegas! Você pode precisar atualizar ou outros nós podem precisar atualizar.</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>Atenção: erro ao ler arquivo wallet.dat! Todas as chaves foram lidas corretamente, mas dados de transações e do catálogo de endereços podem estar faltando ou incorretos.</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>Atenção: wallet.dat corrompido, dados recuperados! Arquivo wallet.dat original salvo como wallet.{timestamp}.bak em %s; se seu saldo ou transações estiverem incorretos, você deve restaurar o backup.</translation> </message> @@ -2837,18 +3040,14 @@ <translation>Lista Branca pares de ligação da máscara de rede dado ou o endereço IP . Pode ser especificado várias vezes.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(padrão: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool deve ser pelo menos %d MB</translation> </message> <message> <source><category> can be:</source> <translation><category> pode ser:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Tentar recuperar chaves privadas de um arquivo wallet.dat corrompido</translation> - </message> - <message> <source>Block creation options:</source> <translation>Opções de criação de blocos:</translation> </message> @@ -2877,6 +3076,22 @@ <translation>Você quer reconstruir o banco de dados de blocos agora?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation>Abilitar a publicação da hash do block em <endereço></translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>Abilitar a publicação da hash da transação em <endereço></translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>Abilitar a publicação dos dados brutos do block em <endereço></translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation>Abilitar a publicação dos dados brutos da transação em <endereço></translation> + </message> + <message> <source>Error initializing block database</source> <translation>Erro ao inicializar banco de dados de blocos</translation> </message> @@ -2893,10 +3108,6 @@ <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> @@ -2905,10 +3116,6 @@ <translation>Falha ao escutar em qualquer porta. Use -listen=0 se você quiser isso.</translation> </message> <message> - <source>If <category> is not supplied, output all debugging information.</source> - <translation>Se <category> não for informada, registrar toda informação de depuração.</translation> - </message> - <message> <source>Importing...</source> <translation>Importando...</translation> </message> @@ -2921,6 +3128,10 @@ <translation>Endereço -onion inválido: '%s'</translation> </message> <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>Mantenha a mempool de transações abaixo de <n> megabytes (padrão: %u)</translation> + </message> + <message> <source>Not enough file descriptors available.</source> <translation>Decriptadores de arquivos disponíveis insuficientes.</translation> </message> @@ -2949,10 +3160,26 @@ <translation>Especifique o arquivo da carteira (dentro do diretório de dados)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Argumento não suportado -benchmark ignorado, use -debug=bench.</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Argumento não suportado -debugnet ignorado, use -debug=net</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>Argumento não suportador encontrado: -tor. Use -onion.</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Use UPnP para mapear a porta de entrada (padrão: %u)</translation> </message> <message> + <source>User Agent comment (%s) contains unsafe characters.</source> + <translation>Comentário do Agente de Usuário (%s) contém caracteres inseguros.</translation> + </message> + <message> <source>Verifying blocks...</source> <translation>Verificando blocos...</translation> </message> @@ -2977,26 +3204,26 @@ <translation>Você precisa reconstruir o banco de dados utilizando -reindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importar blocos de um arquivo externo 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>Permitir conexões JSON-RPC de uma fonte específica. Válido para um único ip (ex. 1.2.3.4), até uma rede/máscara (ex. 1.2.3.4/255.255.255.0) ou uma rede/CIDR (ex. 1.2.3.4/24). Esta opção pode ser usada múltiplas vezes</translation> </message> <message> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation>Um erro ocorreu enquanto configurando o endereço RPC %s porta %u para escuta: %s</translation> - </message> - <message> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> <translation>Vincular ao endereço fornecido e sempre escutar nele. Use a notação [host]:port para IPv6</translation> </message> <message> + <source>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>Conecte ao endereço dado para receber conecções JSON-RPC. Use a notação [destino]:porta para IPv6. Essa opção pode ser especificada várias vezes (padrão: conecte a todas as interfaces)</translation> + </message> + <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Não foi possível obter acesso exclusivo ao diretório de dados %s. Provavelmente Bitcoin já está sendo executado.</translation> </message> <message> + <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source> + <translation>Criar novos arquivos com permissões padrão do sistema, em vez de umask 077 (apenas efetivo com funcionalidade de carteira desabilitada)</translation> + </message> + <message> <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source> <translation>Descobrir o próprio IP (padrão: 1 enquanto aguardando conexões e sem -externalip ou -proxy)</translation> </message> @@ -3009,40 +3236,48 @@ <translation>Executa um comando quando um alerta relevante é recebido ou vemos uma longa segregação (%s em cmd é substituído pela mensagem)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Taxas (em BTC/Kb) menores do que este valor são consideradas inexistentes para divulgação (padrão: %s)</translation> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>Comissões (em %s/kB) menores serão consideradas como zero para relaying, mineração e criação de transação (padrão %s)</translation> + </message> + <message> + <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> + <translation>Se paytxfee não estiver definida, incluir comissão suficiente para que as transações comecem a ter confirmações em média dentro de N blocos (padrão %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>Prunagem configurada abaixo do mínimo de %d MB. Use um número maior.</translation> + <source>Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> + <translation>Valor inválido para -maxtxfee = <valor>: '%s'( precisa ser pelo menos a comissão mínima de %s para prevenir travamento de transações)</translation> + </message> + <message> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation>Tamanho máximo de dados em transações de dados de operadora (padrão %u)</translation> + </message> + <message> + <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> + <translation>Buscar por endereços de peers via busca DNS, se estiver baixo em endereços (padrão: 1 a não ser que -connect)</translation> + </message> + <message> + <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source> + <translation>Gerar credenciais aleatórias para cada conexão por proxy. Isto habilita o isolamento de stream do Tor (padrão: %u)</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> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>Para usar o bitcoind, ou a opção -server do bitcoin-qt, você deve definir rpcpassword no arquivo de configuração: -%s -É recomendado que use a seguinte senha randômica: -rpcuser=bitcoinrpc -rpcpassword=%s -(você não precisa lembrar esta senha) -O usuário e senha NÃO DEVEM ser os mesmos. -Se o arquivo não existir, crie com permissão de proprietário criador somente. -É também recomendado definir a opção alertnotify se deseja ser notificado de problemas; -por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br -</translation> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <translation>Determina o número de núcleos para a geração de moedas se ativado (-1 = todos os núcleos, padrão: %d)</translation> + </message> + <message> + <source>The transaction amount is too small to send after the fee has been deducted</source> + <translation>A quantia da transação é muito pequena para mandar </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>Esse produto inclui software desenvolvido pelo Open SSL Project para uso na OpenSSL Toolkit<https://www.openssl.org/> e software criptográfico escrito por Eric Young e software UPnP escrito por Thomas Bernard. </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>Peers permitidos não podem ser banidos do DoS e suas transações sempre são transmitidas, até mesmo se eles já estão no pool de memória, útil, por exemplo, para um gateway</translation> </message> <message> <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> @@ -3053,16 +3288,28 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>(padrão: %u)</translation> </message> <message> + <source>Accept public REST requests (default: %u)</source> + <translation>Aceitar pedidos restantes públicas (padrão: %u)</translation> + </message> + <message> <source>Activating best chain...</source> <translation>Ativando a melhor sequência...</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>Impossível resolver endereço -whitebind: '%s'</translation> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>Sempre transmitir transações recebidas de peers confiáveis (padrão: %d)</translation> + </message> + <message> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Tentar recuperar na inicialização chaves privadas de um arquivo wallet.dat corrompido</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Escolha o diretório de dados na inicialização (padrão: 0)</translation> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Criar automaticamente serviços ocultos do Tor (padrão: %d)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Impossível resolver endereço -whitebind: '%s'</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3073,10 +3320,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Copyright (C) 2009-%i Desenvolvedores Bitcoin Core</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Impossível interpretar o valor -rpcbind %s como um endereço da rede</translation> - </message> - <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Erro ao carregar wallet.dat: A carteira requer a nova versão do Bitcoin</translation> </message> @@ -3085,18 +3328,18 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Erro ao ler o banco de dados. Finalizando.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Erro: Argumento não suportado -tor, use -onion.</translation> - </message> - <message> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation>Taxa (em BTC/kB) a adicionar nas transações que você envia (padrão: %s)</translation> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Importar blocos a partir de arquivo externo blk000??.dat durante a inicialização</translation> </message> <message> <source>Information</source> <translation>Informação</translation> </message> <message> + <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source> + <translation>O teste de integridade da inicialização falhou. O Core do Bitcoin está sendo desligado.</translation> + </message> + <message> <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> <translation>Quantidade inválida para -maxtxfee=<quantidade>: '%s'</translation> </message> @@ -3117,6 +3360,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Máscara de rede especificada em -whitelist: '%s' é inválida</translation> </message> <message> + <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source> + <translation>Manter ao máximo <n> transações inconectáveis na memória (padrão: %u)</translation> + </message> + <message> <source>Need to specify a port with -whitebind: '%s'</source> <translation>Necessário informar uma porta com -whitebind: '%s'</translation> </message> @@ -3125,38 +3372,30 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Opções de relé nó :</translation> </message> <message> - <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> - <translation>Opções RPC SSL: (veja o Bitcoin Wiki para instruções de configuração SSL)</translation> - </message> - <message> <source>RPC server options:</source> <translation>Opções do servidor RPC:</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> + <source>Rebuild block chain index from current blk000??.dat files on startup</source> + <translation>Reconstruir índice de cadeia de bloco a partir dos arquivos blk000??.dat atuais durante a inicialização</translation> </message> <message> - <source>Send transactions as zero-fee transactions if possible (default: %u)</source> - <translation>Enviar transação sem taxa, se possível (padrão: %u)</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>Receba e mostre P2P alerta de rede (padrão: %u)</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Define certificados SSL root para requisição de pagamento (padrão: -system-)</translation> + <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 language, for example "de_DE" (default: system locale)</source> - <translation>Escolher língua, por exemplo "de_DE" (padrão: localização do sistema)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>Enviar transação sem taxa, se possível (padrão: %u)</translation> </message> <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Exibir todas opções de depuração (uso: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostrar tela inicial ao ligar (padrão: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Encolher arquivo debug.log ao iniciar o cliente (padrão 1 se opção -debug não estiver presente)</translation> </message> @@ -3165,8 +3404,8 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Assinatura de transação falhou</translation> </message> <message> - <source>Start minimized</source> - <translation>Inicializar minimizado</translation> + <source>The transaction amount is too small to pay the fee</source> + <translation>A quantidade da transação é pequena demais para pagar a taxa</translation> </message> <message> <source>This is experimental software.</source> @@ -3189,18 +3428,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Transação muito larga</translation> </message> <message> - <source>UI Options:</source> - <translation>Opções da interface:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Impossível se ligar a %s neste computador (bind retornou erro %s)</translation> </message> <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> - <message> <source>Username for JSON-RPC connections</source> <translation>Nome de usuário para conexões JSON-RPC</translation> </message> @@ -3217,10 +3448,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Aniquilando todas as transações da carteira...</translation> </message> <message> - <source>on startup</source> - <translation>ao iniciar</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat corrompido, recuperação falhou</translation> </message> @@ -3233,18 +3460,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Executa um comando quando o melhor bloco mudar (%s no comando será substituído pelo hash do bloco)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Atualizar carteira para o formato mais recente</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Usar OpenSSL (https) para conexões JSON-RPC</translation> - </message> - <message> <source>This help message</source> <translation>Exibe esta mensagem de ajuda</translation> </message> @@ -3261,12 +3476,20 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Erro ao carregar wallet.dat: Carteira corrompida</translation> </message> <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>Comissões (em %s/kB) menores serão consideradas como zero para criação de transação (padrão %s)</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> + <translation>Use um proxy SOCKS5 separado para alcançar participantes da rede via serviços ocultos Tor (padrão: %s)</translation> + </message> + <message> <source>(default: %s)</source> <translation>(padrão: %s)</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Cífras aceitas (padrão: %s)</translation> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <translation>Sempre pergunte pelo endereço de peer via pesquisa DNS (padrão: %u)</translation> </message> <message> <source>Error loading wallet.dat</source> @@ -3289,30 +3512,46 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br <translation>Endereço -proxy inválido: '%s'</translation> </message> <message> + <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source> + <translation>Escutar por conexões JSON-RPC na porta <port> (padrão: %u ou testnet: %u)</translation> + </message> + <message> <source>Listen for connections on <port> (default: %u or testnet: %u)</source> <translation>Aguardar por conexões na porta <port> (padrão: %u ou testnet: %u)</translation> </message> <message> - <source>Prepend debug output with timestamp (default: %u)</source> - <translation>Adiciona timestamp como prefixo no debug (default: %u)</translation> + <source>Maintain at most <n> connections to peers (default: %u)</source> + <translation>Manter, no máximo, <n> conexões com peers (padrão: %u)</translation> </message> <message> - <source>Relay non-P2SH multisig (default: %u)</source> - <translation>Retransmitir P2SH não multisig (default: %u)</translation> + <source>Make the wallet broadcast transactions</source> + <translation>Fazer a carteira transmitir transações</translation> </message> <message> - <source>Server certificate file (default: %s)</source> - <translation>Arquivo de certificado do servidor (padrão: %s)</translation> + <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source> + <translation>Buffer máximo de recebimento por conexão, <n>*1000 bytes (padrão: %u)</translation> </message> <message> - <source>Server private key (default: %s)</source> - <translation>Chave privada do servidor (padrão: %s)</translation> + <source>Prepend debug output with timestamp (default: %u)</source> + <translation>Adiciona timestamp como prefixo no debug (padrão: %u)</translation> + </message> + <message> + <source>Relay non-P2SH multisig (default: %u)</source> + <translation>Retransmitir P2SH não multisig (padrão: %u)</translation> + </message> + <message> + <source>Set key pool size to <n> (default: %u)</source> + <translation>Defina o tamanho da chave para piscina<n> (padrão: %u)</translation> </message> <message> <source>Set minimum block size in bytes (default: %u)</source> <translation>Definir tamanho mínimo do bloco, em bytes (padrão: %u)</translation> </message> <message> + <source>Set the number of threads to service RPC calls (default: %d)</source> + <translation>Defina o número de threads para chamadas do serviço RPC (padrão: %d)</translation> + </message> + <message> <source>Specify configuration file (default: %s)</source> <translation>Especificar arquivo de configuração (padrão: %s)</translation> </message> @@ -3322,7 +3561,11 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br </message> <message> <source>Specify pid file (default: %s)</source> - <translation>Especificar aqrquivo pid (default: %s)</translation> + <translation>Especificar aqrquivo pid (padrão: %s)</translation> + </message> + <message> + <source>Spend unconfirmed change when sending transactions (default: %u)</source> + <translation>Gastar troco não confirmado quando enviar transações (padrão: %u)</translation> </message> <message> <source>Unknown network specified in -onlynet: '%s'</source> diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index 7ac0a4fa5c..ffed44a61c 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.0"> +<TS language="pt_PT" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -871,7 +874,7 @@ <source>command-line options</source> <translation>opções da linha de comandos</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -1288,10 +1291,6 @@ <translation>Pedido de pagamento %1 excede o tamanho (%2 bytes, permitido %3 bytes).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Pedido de pagamento proteção DdS</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Erro ao comunicar com %1: %2</translation> </message> @@ -1476,14 +1475,6 @@ <translation>Serviços</translation> </message> <message> - <source>Starting Height</source> - <translation>Iniciando Altura</translation> - </message> - <message> - <source>Sync Height</source> - <translation>Sincronização da Altura</translation> - </message> - <message> <source>Ban Score</source> <translation>Resultado da Suspensão</translation> </message> @@ -1500,14 +1491,6 @@ <translation>Ultimo Recebimento</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 Latência</translation> </message> @@ -1603,10 +1586,6 @@ <source>Unknown</source> <translation>Desconhecido</translation> </message> - <message> - <source>Fetching...</source> - <translation>Em busca...</translation> - </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -1972,10 +1951,6 @@ <translation>Copiar alteração</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Quantia Total %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>ou</translation> </message> @@ -2004,10 +1979,6 @@ <translation>Pedido de pagamento expirou.</translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Pagar somente a taxa minima de %1</translation> - </message> - <message> <source>Warning: Invalid Bitcoin address</source> <translation>Aviso: Endereço Bitcoin inválido</translation> </message> @@ -2754,10 +2725,6 @@ <translation>Correr o processo em segundo plano e aceitar comandos</translation> </message> <message> - <source>Use the test network</source> - <translation>Utilizar a rede de testes</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Aceitar ligações externas (padrão: 1 sem -proxy ou -connect)</translation> </message> @@ -2790,10 +2757,6 @@ <translation>Incapaz de vincular à porta %s neste computador. O Bitcoin Core provavelmente já está a correr.</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> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Aviso: A rede não parece estar completamente de acordo! Parece que alguns mineiros estão com dificuldades técnicas.</translation> </message> @@ -2802,10 +2765,6 @@ <translation>Atenção: Parecemos não estar de acordo com os nossos pares! Poderá ter que atualizar o seu cliente, ou outros nós poderão ter que atualizar os seus clientes.</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>Atenção: erro ao ler wallet.dat! Todas as chaves foram lidas correctamente, mas dados de transação ou do livro de endereços podem estar em falta ou incorrectos.</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>Atenção: wallet.dat corrompido, dados recuperados! wallet.dat original salvo como wallet.{timestamp}.bak em %s; se o seu saldo ou transações estiverem incorrectos deverá recuperar uma cópia de segurança.</translation> </message> @@ -2814,18 +2773,10 @@ <translation>Ligações na lista branca conectam desde a seguinte netmask ou endereço IP. Posse ser especificado varias vezes.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(padrão: 1)</translation> - </message> - <message> <source><category> can be:</source> <translation><categoria> pode ser:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Tentar recuperar chaves privadas de um wallet.dat corrupto</translation> - </message> - <message> <source>Block creation options:</source> <translation>Opções de criação de bloco:</translation> </message> @@ -2870,10 +2821,6 @@ <translation>Erro ao abrir a base de dados de blocos</translation> </message> <message> - <source>Error: A fatal internal error occured, see debug.log for details</source> - <translation>Erro: Um erro fatal interno ocorreu, verificar debug.log para mais informação</translation> - </message> - <message> <source>Error: Disk space is low!</source> <translation>Erro: Pouco espaço em disco!</translation> </message> @@ -2882,10 +2829,6 @@ <translation>Falhou a escutar em qualquer porta. Use -listen=0 se quiser isto.</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> - <message> <source>Importing...</source> <translation>A importar...</translation> </message> @@ -2946,22 +2889,18 @@ <translation>É necessário reconstruir as bases de dados usando -reindex para mudar o -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importar blocos de um ficheiro 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 conexções JSON-RPC de fontes especificas. Valido para <ip> um unico IP (ex. 1.2.3.4), uma rede/netmask (ex. 1.2.3.4/255.255.255.0) ou uma rede/CIDR (ex. 1.2.3.4/24). Esta opção pode ser especificada varias vezes</translation> </message> <message> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation>Um erro ocorreu durante a definição do endereço RPC %s porto %u para escutar: %s</translation> - </message> - <message> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> <translation>Vincualar o endereço dado e listar as ligações conectadas ao mesmo na lista branca. Use a notação [anfitrião]:porta para 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>Vinculado para dar o endereço para atender as ligações JSON-RPC. Use [host]: Notação de porta para IPv6. Esta opção pode ser especificada várias vezes (padrão: ligam-se a todas as interfaces)</translation> + </message> + <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Impossível trancar a pasta de dados %s. Provavelmente o Bitcoin Core já está a ser executado.</translation> </message> @@ -2974,16 +2913,12 @@ <translation>Definir tamanho máximo de transações com alta-prioridade/baixa-taxa em bytes (por defeito: %d)</translation> </message> <message> - <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> - <translation>Atenção: Por favor verifique que a data e hora do seu computador estão correctas! Se o seu relógio não estiver certo o Bitcoin Core não irá funcionar correctamente.</translation> - </message> - <message> <source>(default: %u)</source> <translation>(por defeito: %u)</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Escolha a pasta de dados ao iniciar (por defeito: 0)</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Não foi possível resolver o endereço -whitebind: '%s'</translation> </message> <message> <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source> @@ -2998,6 +2933,10 @@ <translation>Informação</translation> </message> <message> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Quantia inválida para -maxtxfee=<quantidade>: '%s'</translation> + </message> + <message> <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> <translation>Quantia inválida para -minrelaytxfee=<quantidade>: '%s'</translation> </message> @@ -3010,18 +2949,6 @@ <translation>Enviar informação de rastreio/depuração para a consola e não para o ficheiro debug.log</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Configurar certificados SSL root para pedido de pagamento (default: -system-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Definir linguagem, por exemplo "pt_PT" (por defeito: linguagem do sistema)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Mostrar imagem ao iniciar (por defeito: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Encolher ficheiro debug.log ao iniciar o cliente (por defeito: 1 sem -debug definido)</translation> </message> @@ -3030,10 +2957,6 @@ <translation>Falhou assinatura da transação</translation> </message> <message> - <source>Start minimized</source> - <translation>Iniciar minimizado</translation> - </message> - <message> <source>Transaction amount too small</source> <translation>Quantia da transação é muito baixa</translation> </message> @@ -3046,10 +2969,6 @@ <translation>Transação grande demais</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> - <message> <source>Username for JSON-RPC connections</source> <translation>Nome de utilizador para ligações JSON-RPC</translation> </message> @@ -3078,18 +2997,6 @@ <translation>Executar comando quando o melhor bloco mudar (no comando, %s é substituído pela hash do bloco)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Atualize a carteira para o formato mais recente</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Usar OpenSSL (https) para ligações JSON-RPC</translation> - </message> - <message> <source>This help message</source> <translation>Esta mensagem de ajuda</translation> </message> @@ -3106,6 +3013,10 @@ <translation>Erro ao carregar wallet.dat: Carteira danificada</translation> </message> <message> + <source>(default: %s)</source> + <translation>(por defeito: %s)</translation> + </message> + <message> <source>Error loading wallet.dat</source> <translation>Erro ao carregar wallet.dat</translation> </message> @@ -3138,14 +3049,6 @@ <translation>Adicionar data e hora à informação de depuração (por defeito: %u)</translation> </message> <message> - <source>Server certificate file (default: %s)</source> - <translation>Ficheiro de certificado do servidor (por defeito: %s)</translation> - </message> - <message> - <source>Server private key (default: %s)</source> - <translation>Chave privada do servidor (por defeito: %s)</translation> - </message> - <message> <source>Set key pool size to <n> (default: %u)</source> <translation>Definir o tamanho da memória de chaves para <n> (por defeito: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index be24668536..8bccf037a7 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.0"> +<TS language="ro_RO" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -707,6 +710,10 @@ <translation>cea mai scăzută</translation> </message> <message> + <source>(%1 locked)</source> + <translation>(%1 blocat)</translation> + </message> + <message> <source>none</source> <translation>nimic</translation> </message> @@ -735,6 +742,10 @@ <translation>nu</translation> </message> <message> + <source>This means a fee of at least %1 per kB is required.</source> + <translation>Aceasta înseamnă o taxă de cel puţin %1 pe kB necesar.</translation> + </message> + <message> <source>Can vary +/- 1 byte per input.</source> <translation>Poate varia +/- 1 octet pentru fiecare intrare.</translation> </message> @@ -863,7 +874,7 @@ <source>command-line options</source> <translation>Opţiuni linie de comandă</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -879,6 +890,10 @@ <translation>Dacă aceasta este prima dată cînd programul este lansat, puteţi alege unde Nucleul Bitcoin va stoca datele.</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>Nucleul Bitcoin se va descărca şi va stoca o copie a lanţului blocului Bitcoin. Cel puţin %1GB de date vor fi stocate în acest dosar şi se va mări în timp. Portofelul va fi, de asemenea, stocat în acest dosar.</translation> + </message> + <message> <source>Use the default data directory</source> <translation>Foloseşte dosarul de date implicit</translation> </message> @@ -1271,10 +1286,6 @@ <translation>Cererea de plată %1 este prea mare (%2 octeţi, permis %3 octeţi).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Protecţie DoS cerere de plată</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Eroare la comunicarea cu %1: %2</translation> </message> @@ -1467,14 +1478,6 @@ <translation>Ultima primire</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Octeţi trimişi</translation> - </message> - <message> - <source>Bytes Received</source> - <translation>Octeţi primiţi</translation> - </message> - <message> <source>Ping Time</source> <translation>Timp ping</translation> </message> @@ -1570,10 +1573,6 @@ <source>Unknown</source> <translation>Necunoscut</translation> </message> - <message> - <source>Fetching...</source> - <translation>Preluare...</translation> - </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -1919,10 +1918,6 @@ <translation>Copiază rest</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Suma totală %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>sau</translation> </message> @@ -1951,10 +1946,6 @@ <translation>Cererea de plată a expirat.</translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Plăteşte doar taxa minimă de %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>Adresa destinatarului nu este validă, vă rugăm să o verificaţi.</translation> </message> @@ -2356,6 +2347,10 @@ <source>, has not been successfully broadcast yet</source> <translation>, nu s-a propagat încă</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Deschis pentru încă %n bloc</numerusform><numerusform>Deschis pentru încă %n blocuri</numerusform><numerusform>Deschis pentru încă %n de blocuri</numerusform></translation> + </message> <message> <source>unknown</source> <translation>necunoscut</translation> @@ -2386,6 +2381,10 @@ <source>Immature (%1 confirmations, will be available after %2)</source> <translation>Imatur (%1 confirmări, va fi disponibil după %2)</translation> </message> + <message numerus="yes"> + <source>Open for %n more block(s)</source> + <translation><numerusform>Deschis pentru încă %n bloc</numerusform><numerusform>Deschis pentru încă %n blocuri</numerusform><numerusform>Deschis pentru încă %n de blocuri</numerusform></translation> + </message> <message> <source>Open until %1</source> <translation>Deschis până la %1</translation> @@ -2697,10 +2696,6 @@ <translation>Rulează în fundal ca un demon şi acceptă comenzi</translation> </message> <message> - <source>Use the test network</source> - <translation>Utilizează reţeaua de test</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Acceptă conexiuni din afară (implicit: 1 dacă nu se foloseşte -proxy sau -connect)</translation> </message> @@ -2729,10 +2724,6 @@ <translation>Nu se poate lega la %s pe acest calculator. Nucleul Bitcoin probabil deja rulează.</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ţie: setarea -paytxfee este foarte mare! Aceasta este taxa tranzacţiei pe care o veţi plăti dacă trimiteţi o tranzacţie.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Atenţie: Reţeaua nu pare să fie de acord în totalitate! Aparent nişte mineri au probleme.</translation> </message> @@ -2741,26 +2732,14 @@ <translation>Atenţie: Aparent, nu sîntem de acord cu toţi partenerii noştri! Va trebui să faceţi o actualizare, sau alte noduri necesită actualizare.</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>Atenţie: eroare la citirea fişierului wallet.dat! Toate cheile sînt citite corect, dar datele tranzactiei sau anumite intrări din agenda sînt incorecte sau lipsesc.</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>Atenţie: fişierul wallet.dat este corupt, date salvate! Fişierul original wallet.dat a fost salvat ca wallet.{timestamp}.bak in %s; dacă balansul sau tranzactiile sînt incorecte ar trebui să restauraţi dintr-o copie de siguranţă.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(iniţial: 1)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> poate fi:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Încercare de recuperare a cheilor private dintr-un wallet.dat corupt</translation> - </message> - <message> <source>Block creation options:</source> <translation>Opţiuni creare bloc:</translation> </message> @@ -2813,10 +2792,6 @@ <translation>Nu s-a reuşit ascultarea pe orice port. Folosiţi -listen=0 dacă vreţi asta.</translation> </message> <message> - <source>If <category> is not supplied, output all debugging information.</source> - <translation>Dacă <category> nu este furnizat, produce toate informaţiile de depanare.</translation> - </message> - <message> <source>Importing...</source> <translation>Import...</translation> </message> @@ -2873,18 +2848,10 @@ <translation>Trebuie să reconstruiţi baza de date folosind -reindex pentru a schimba -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importă blocuri dintr-un fişier extern 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>Permite conexiunile JSON-RPC din sursa specificată. Valid pentru <ip> sînt IP singulare (ex. 1.2.3.4), o reţea/mască-reţea (ex. 1.2.3.4/255.255.255.0) sau o reţea/CIDR (ex. 1.2.3.4/24). Această opţiune poate fi specificată de mai multe ori</translation> </message> <message> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation>A apărut o eroare la setarea adresei RPC %s portul %u pentru ascultare: %s</translation> - </message> - <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> <translation>Nu se poate obţine blocarea folderului cu date %s. Nucleul Bitcoin probabil deja rulează.</translation> </message> @@ -2901,12 +2868,16 @@ <translation>Acest produs include programe dezvoltate de către Proiectul OpenSSL pentru a fi folosite în OpenSSL Toolkit <https://www.openssl.org/> şi programe criptografice scrise de către Eric Young şi programe UPnP scrise de către Thomas Bernard.</translation> </message> <message> + <source>(default: %u)</source> + <translation>(implicit: %u)</translation> + </message> + <message> <source>Accept public REST requests (default: %u)</source> <translation>Acceptă cererile publice REST (implicit: %u)</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Alege dosarul de date la pornire (implicit: 0)</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Nu se poate rezolva adresa -whitebind: '%s'</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -2921,14 +2892,6 @@ <translation>Eroare la citirea bazei de date. Oprire.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Eroare: Argument nesuportat -tor găsit, folosiţi -onion.</translation> - </message> - <message> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation>Taxa (în BTC/kB) de adăugat la tranzacţiile pe care le trimiteţi(implicit: %s)</translation> - </message> - <message> <source>Information</source> <translation>Informaţie</translation> </message> @@ -2961,18 +2924,10 @@ <translation>Trebuie să specificaţi un port cu -whitebind: '%s'</translation> </message> <message> - <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> - <translation>Opţiuni RPC SSL: (vedeţi Wiki Bitcoin pentru intrucţiunile de setare SSL)</translation> - </message> - <message> <source>RPC server options:</source> <translation>Opţiuni server RPC:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>RPC suportă pentru HTTP conexiuni persistente (implicit: %d)</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> @@ -2981,22 +2936,10 @@ <translation>Trimitere tranzacţii ca tranzacţii taxă-zero dacă este posibil (implicit: %u)</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Setare rădăcină certificat SSL pentru cerere de plată (implicit: -sistem- )</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Setează limba, de exemplu: "de_DE" (implicit: sistem local)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Arată toate opţiunile de depanare (uz: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Afişează pe ecran splash la pornire (implicit: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Micşorează fişierul debug.log la pornirea clientului (implicit: 1 cînd nu se foloseşte -debug)</translation> </message> @@ -3005,10 +2948,6 @@ <translation>Nu s-a reuşit semnarea tranzacţiei</translation> </message> <message> - <source>Start minimized</source> - <translation>Începe minimizat</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Acesta este un program experimental.</translation> </message> @@ -3033,10 +2972,6 @@ <translation>Nu se poate lega la %s pe acest calculator. (Legarea a întors eroarea %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Foloseşte UPnP pentru a vedea porturile (implicit: 1 cînd ascultă)</translation> - </message> - <message> <source>Username for JSON-RPC connections</source> <translation>Utilizator pentru conexiunile JSON-RPC</translation> </message> @@ -3049,22 +2984,10 @@ <translation>Avertisment</translation> </message> <message> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation>Avertisment: Argument nesuportat -benchmark ignorat, folosiţi -debug=bench.</translation> - </message> - <message> - <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> - <translation>Avertisment: Argument nesuportat -debugnet ignorat, folosiţi -debug=net.</translation> - </message> - <message> <source>Zapping all transactions from wallet...</source> <translation>Şterge toate tranzacţiile din portofel...</translation> </message> <message> - <source>on startup</source> - <translation>la pornire</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat corupt, salvare nereuşită</translation> </message> @@ -3077,18 +3000,6 @@ <translation>Execută comanda cînd cel mai bun bloc se modifică (%s în cmd este înlocuit cu hash-ul blocului)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Actualizează portofelul la ultimul format</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Foloseşte OpenSSL (https) pentru conexiunile JSON-RPC</translation> - </message> - <message> <source>This help message</source> <translation>Acest mesaj de ajutor</translation> </message> @@ -3113,10 +3024,6 @@ <translation>(implicit: %s)</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Cifruri acceptabile (implicit: %s)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Eroare la încărcarea wallet.dat</translation> </message> @@ -3133,14 +3040,6 @@ <translation>Adresa -proxy nevalidă: '%s'</translation> </message> <message> - <source>Server certificate file (default: %s)</source> - <translation>Fişierul certificat al serverului (implicit: %s)</translation> - </message> - <message> - <source>Server private key (default: %s)</source> - <translation>Cheia privată a serverului (implicit: %s)</translation> - </message> - <message> <source>Set minimum block size in bytes (default: %u)</source> <translation>Setare mărime minimă bloc în octeţi (implicit: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 004208d345..00dfd833ab 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -1,4 +1,4 @@ -<TS language="ru" version="2.0"> +<TS language="ru" version="2.1"> <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> @@ -217,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/префикс</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Заблокировано до</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -418,6 +433,10 @@ <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><numerusform>%n активных соединений с сетью Bitcoin</numerusform></translation> + </message> <message> <source>No block source available...</source> <translation>Источник блоков недоступен...</translation> @@ -426,10 +445,26 @@ <source>Processed %n block(s) of transaction history.</source> <translation><numerusform>Обработан %n блок истории транзакций.</numerusform><numerusform>Обработано %n блока истории транзакций.</numerusform><numerusform>Обработано %n блоков истории транзакций.</numerusform><numerusform>Обработано %n блоков истории транзакций.</numerusform></translation> </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation><numerusform>%n час</numerusform><numerusform>%n часа</numerusform><numerusform>%n часов</numerusform><numerusform>%n часов</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation><numerusform>%n день</numerusform><numerusform>%n дня</numerusform><numerusform>%n дней</numerusform><numerusform>%n дней</numerusform></translation> + </message> + <message numerus="yes"> + <source>%n week(s)</source> + <translation><numerusform>%n неделю</numerusform><numerusform>%n недели</numerusform><numerusform>%n недель</numerusform><numerusform>%n недель</numerusform></translation> + </message> <message> <source>%1 and %2</source> <translation>%1 и %2</translation> </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation><numerusform>%n год</numerusform><numerusform>%n лет</numerusform><numerusform>%n лет</numerusform><numerusform>%n года</numerusform></translation> + </message> <message> <source>%1 behind</source> <translation>%1 позади</translation> @@ -847,6 +882,34 @@ <source>command-line options</source> <translation>параметры командной строки</translation> </message> + <message> + <source>UI Options:</source> + <translation>Настройки интерфейса:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Выбрать каталог данных при запуске (по умолчанию: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Выберите язык, например "de_DE" (по умолчанию: как в системе)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Запускать свёрнутым</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Указать корневые SSL-сертификаты для запроса платежа (по умолчанию: -system-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Показывать экран-заставку при запуске (по умолчанию: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Сбросить все настройки сделанные через графический интерфейс</translation> + </message> </context> <context> <name>Intro</name> @@ -886,7 +949,15 @@ <source>Error</source> <translation>Ошибка</translation> </message> - </context> + <message numerus="yes"> + <source>%n GB of free space available</source> + <translation><numerusform>%n ГБ свободного места доступно</numerusform><numerusform>%n ГБ свободного места доступно</numerusform><numerusform>%n ГБ свободного места доступно</numerusform><numerusform>%n ГБ свободного места доступно</numerusform></translation> + </message> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(из необходимых %n ГБ)</numerusform><numerusform>(из необходимых %n ГБ)</numerusform><numerusform>(из необходимых %n ГБ)</numerusform><numerusform>(из необходимых %n ГБ)</numerusform></translation> + </message> +</context> <context> <name>OpenURIDialog</name> <message> @@ -1037,6 +1108,34 @@ <translation>Порт прокси-сервера (например, 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Используется для достижения участников через:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Показывается, если включено прокси SOCKS5 по умолчанию, используемое для соединения с участниками по этому типу сети.</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Подключаться к сети Bitcoin через прокси SOCKS5 для скрытых сервисов Tor.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Использовать отдельный прокси SOCKS5 для соединения с участниками через скрытые сервисы Tor:</translation> + </message> + <message> <source>&Window</source> <translation>&Окно</translation> </message> @@ -1255,10 +1354,6 @@ <translation>Запрос платежа %1 слишком большой (%2 байтов, разрешено %3 байтов).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>DoS-защита запроса платежа</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Ошибка связи с %1: %2</translation> </message> @@ -1411,6 +1506,18 @@ <translation>Текущее число блоков</translation> </message> <message> + <source>Memory Pool</source> + <translation>Пул памяти</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>Текущее число транзакций</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Использование памяти</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>Открыть отладочный лог-файл Bitcoin Core из текущего каталога данных. Это может занять несколько секунд для больших лог-файлов.</translation> </message> @@ -1427,10 +1534,18 @@ <translation>&Участники</translation> </message> <message> + <source>Banned peers</source> + <translation>Заблокированные участники</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Выберите участника для просмотра подробностей.</translation> </message> <message> + <source>Whitelisted</source> + <translation>Доверенный</translation> + </message> + <message> <source>Direction</source> <translation>Направление</translation> </message> @@ -1439,20 +1554,24 @@ <translation>Версия</translation> </message> <message> - <source>User Agent</source> - <translation>Юзер-агент</translation> + <source>Starting Block</source> + <translation>Начальный блок</translation> </message> <message> - <source>Services</source> - <translation>Сервисы</translation> + <source>Synced Headers</source> + <translation>Синхронизировано заголовков</translation> </message> <message> - <source>Starting Height</source> - <translation>Начальная высота</translation> + <source>Synced Blocks</source> + <translation>Синхронизировано блоков</translation> </message> <message> - <source>Sync Height</source> - <translation>Высота синхронизации</translation> + <source>User Agent</source> + <translation>Юзер-агент</translation> + </message> + <message> + <source>Services</source> + <translation>Сервисы</translation> </message> <message> <source>Ban Score</source> @@ -1471,15 +1590,15 @@ <translation>Последний раз получено</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Байт передано</translation> + <source>Ping Time</source> + <translation>Время задержки</translation> </message> <message> - <source>Bytes Received</source> - <translation>Байт получено</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>Длительность текущего пинга.</translation> </message> <message> - <source>Ping Time</source> + <source>Ping Wait</source> <translation>Время задержки</translation> </message> <message> @@ -1531,6 +1650,34 @@ <translation>Очистить консоль</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>&Отключить узел</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Заблокировать узел на</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &час</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &день</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &неделю</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &год</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>&Разблокировать узел</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Добро пожаловать в RPC-консоль Bitcoin Core.</translation> </message> @@ -1559,6 +1706,10 @@ <translation>%1 ГБ</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(номер узла: %1)</translation> + </message> + <message> <source>via %1</source> <translation>через %1</translation> </message> @@ -1575,12 +1726,16 @@ <translation>Исходящие</translation> </message> <message> - <source>Unknown</source> - <translation>Неизвестно</translation> + <source>Yes</source> + <translation>Да</translation> </message> <message> - <source>Fetching...</source> - <translation>Получение...</translation> + <source>No</source> + <translation>Нет</translation> + </message> + <message> + <source>Unknown</source> + <translation>Неизвестно</translation> </message> </context> <context> @@ -1947,8 +2102,8 @@ <translation>Копировать размен</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Общая сумма %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Общая сумма %1</translation> </message> <message> <source>or</source> @@ -1983,6 +2138,14 @@ <translation>Запрос платежа просрочен.</translation> </message> <message> + <source>Pay only the required fee of %1</source> + <translation>Заплатить только обязательную комиссию %1</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Подтверждение ожидается через %n блок.</numerusform><numerusform>Подтверждение ожидается через %n блока.</numerusform><numerusform>Подтверждение ожидается через %n блоков.</numerusform><numerusform>Подтверждение ожидается через %n блоков.</numerusform></translation> + </message> + <message> <source>The recipient address is not valid. Please recheck.</source> <translation>Адрес получателя неверный. Пожалуйста, перепроверьте.</translation> </message> @@ -2296,6 +2459,10 @@ <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><numerusform>, разослано через %n узлов</numerusform></translation> + </message> <message> <source>Date</source> <translation>Дата</translation> @@ -2332,6 +2499,10 @@ <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><numerusform>будет доступно через %n блоков</numerusform></translation> + </message> <message> <source>not accepted</source> <translation>не принято</translation> @@ -2404,6 +2575,10 @@ <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><numerusform>Открыто для ещё %n блоков</numerusform></translation> + </message> <message> <source>unknown</source> <translation>неизвестно</translation> @@ -2434,6 +2609,10 @@ <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><numerusform>Открыто для ещё %n блоков</numerusform></translation> + </message> <message> <source>Open until %1</source> <translation>Открыто до %1</translation> @@ -2463,6 +2642,10 @@ <translation>Неподтверждено</translation> </message> <message> + <source>Confirming (%1 of %2 recommended confirmations)</source> + <translation>Подтверждено(%1 подтверждений, рекомендуется %2 подтверждений)</translation> + </message> + <message> <source>Conflicted</source> <translation>В противоречии</translation> </message> @@ -2594,6 +2777,10 @@ <translation>Скопировать ID транзакции</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>Скопировать исходную транзакции</translation> + </message> + <message> <source>Edit label</source> <translation>Изменить метку</translation> </message> @@ -2741,12 +2928,52 @@ <translation>Принимать командную строку и команды JSON-RPC</translation> </message> <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>Если <category> не предоставлена или равна 1, выводить всю отладочную информацию.</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Максимальная сумма комиссий (%s) для одной транзакции в бумажнике; слишком низкое значение может вызвать прерывание больших транзакций (по умолчанию: %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Внимание: убедитесь, что дата и время на Вашем компьютере выставлены верно! Если Ваши часы идут неправильно, Bitcoin Core будет работать некорректно.</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>Удаление блоков выставлено ниже, чем минимум в %d Мб. Пожалуйста, используйте большее значение.</translation> + </message> + <message> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation>Удаление: последняя синхронизация кошелька вышла за рамки удаленных данных. Вам нужен -reindex (скачать всю цепь блоков в случае удаленного узла)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Уменьшить размер хранилища за счёт удаления (обрезания) старых блоков. Этот режим несовместим с -txindex и -rescan. Внимание: переключение этой опции обратно потребует полной загрузки цепи блоков. (по умолчанию: 0 = отключить удаление блоков, >%u = целевой размер в Мб для файлов блоков)</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>Повторное сканирование не возможно в режиме удаления. Вам надо будет использовать -reindex, который загрузит заново всю цепь блоков.</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Ошибка: произошла неустранимая ошибка, подробности в debug.log</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Комиссия (в %s/Кб) для добавления к вашим транзакциям (по умолчанию: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Очистка хранилища блоков...</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>Запускаться в фоне как демон и принимать команды</translation> </message> <message> - <source>Use the test network</source> - <translation>Использовать тестовую сеть</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>Невозможно запустить HTTP сервер. Смотри debug лог для подробностей.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2769,18 +2996,14 @@ <translation>Выполнить команду, когда меняется транзакция в бумажнике (%s в команде заменяется на TxID)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Максимальная сумма комиссий для одной транзакции в бумажнике; слишком низкое значение может вызвать прерывание больших транзакций (по умолчанию: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Уменьшить размер хранилища за счёт удаления (обрезания) старых блоков. Этот режим отключает поддержку бумажника и несовместим с -txindex. Внимание: переключение этой опции обратно потребует полной загрузки цепи блоков. (по умолчанию: 0 = отключить удаление блоков, >%u = целевой размер в Мб для файлов блоков)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Задать число потоков проверки скрипта (от %u до %d, 0=авто, <0 = оставить столько ядер свободными, по умолчанию: %d)</translation> </message> <message> + <source>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>База данных блоков содержит блок, который появляется из будущего. Это может из-за некорректно установленных даты и времени на вашем компьютере. Остается только перестроивать базу блоков, если вы уверены, что дата и время корректны.</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> @@ -2789,6 +3012,10 @@ <translation>Не удалось забиндиться на %s на этом компьютере. Возможно, Bitcoin Core уже запущен.</translation> </message> <message> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>Использовать UPnP для проброса порта (по умолчанию: 1, если используется прослушивание и нет -proxy)</translation> + </message> + <message> <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> <translation>ВНИМАНИЕ: сгенерировано ненормально большое число блоков, %d блоков получено за последние %d часов (ожидалось %d)</translation> </message> @@ -2797,10 +3024,6 @@ <translation>ВНИМАНИЕ: проверьте сетевое подключение, получено %d блоков за последние %d часов (ожидалось %d)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Внимание: установлено очень большое значение -paytxfee. Это комиссия, которую вы заплатите при проведении транзакции.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Внимание: похоже, в сети нет полного согласия! Некоторый майнеры, возможно, испытывают проблемы.</translation> </message> @@ -2809,10 +3032,6 @@ <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> - <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> </message> @@ -2821,18 +3040,14 @@ <translation>Вносить в белый список участников, подключающихся с указанной маски сети или IP. Можно использовать многократно.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(по умолчанию: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool должен быть как минимум %d MB</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> - <message> <source>Block creation options:</source> <translation>Параметры создания блоков:</translation> </message> @@ -2861,6 +3076,22 @@ <translation>Пересобрать БД блоков прямо сейчас?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation>Включить публичный хеш блока в <address></translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>Включить публичный хеш транзакции в <address></translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>Включить публичный сырой блок в <address></translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation>Включить публичную сырую транзакцию в <address></translation> + </message> + <message> <source>Error initializing block database</source> <translation>Ошибка инициализации БД блоков</translation> </message> @@ -2877,10 +3108,6 @@ <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> @@ -2889,10 +3116,6 @@ <translation>Не удалось начать прослушивание на порту. Используйте -listen=0 если вас это устраивает.</translation> </message> <message> - <source>If <category> is not supplied, output all debugging information.</source> - <translation>Если <category> не предоставлена, выводить всю отладочную информацию.</translation> - </message> - <message> <source>Importing...</source> <translation>Импорт ...</translation> </message> @@ -2905,6 +3128,10 @@ <translation>Неверный -onion адрес: '%s'</translation> </message> <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>Сбрасывать транзакции из памяти на диск каждые <n> мегабайт (по умолчанию: %u)</translation> + </message> + <message> <source>Not enough file descriptors available.</source> <translation>Недостаточно файловых дескрипторов.</translation> </message> @@ -2933,10 +3160,26 @@ <translation>Укажите файл бумажника (внутри каталога данных)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Неподдерживаемый аргумент -benchmark проигнорирован, используйте -debug=bench.</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Неподдерживаемый аргумент -debugnet проигнорирован, используйте -debug=net.</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>Обнаружен не поддерживаемый параметр -tor, используйте -onion.</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>Использовать UPnP для проброса порта (по умолчанию: %u)</translation> </message> <message> + <source>User Agent comment (%s) contains unsafe characters.</source> + <translation>Комментарий пользователя (%s) содержит небезопасные символы.</translation> + </message> + <message> <source>Verifying blocks...</source> <translation>Проверка блоков...</translation> </message> @@ -2961,18 +3204,10 @@ <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), сеть/маска сети (например, 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> @@ -2997,16 +3232,12 @@ <translation>Ошибка: не удалось начать прослушивание входящих подключений (прослушивание вернуло ошибку %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> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>Комиссии (в %s/Кб) меньшие этого значения считаются нулевыми для создания, ретрансляции, получения транзакции (по умолчанию: %s)</translation> </message> <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> @@ -3021,10 +3252,6 @@ <translation>Наибольший размер данных в носителе данных транзакций, которые мы передаем и генерируем (по умолчанию: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>Удаление блоков выставлено ниже, чем минимум в %d Мб. Пожалуйста, используйте большее значение.</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Запрашивать адреса участников с помощью DNS, если адресов мало (по умолчанию: 1, если не указан -connect)</translation> </message> @@ -3049,38 +3276,6 @@ <translation>Этот продукт включает ПО, разработанное OpenSSL Project для использования в OpenSSL Toolkit <https://www.openssl.org/> и криптографическое ПО, написанное Eric Young и ПО для работы с UPnP, написанное Thomas Bernard.</translation> </message> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>Для использования bitcoind или опции bitcoin-qt -server, вы должны установить опцию rpcpassword в конфигурационном файле: - %s -Рекомендуется использовать следующий случайный пароль: -rpcuser=bitcoinrpc -rpcpassword=%s -(вам не нужно запоминать этот пароль) -Имя и пароль ДОЛЖНЫ различаться. -Если файл не существует, создайте его и установите право доступа только для чтения только для владельца. -Также рекомендуется включить alertnotify для оповещения о проблемах; -Например: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Внимание: установлено очень большое значение -paytxfee. Такие большие комиссии могут быть уплачены в отдельной транзакции.</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> @@ -3101,16 +3296,20 @@ rpcpassword=%s <translation>Активируется лучшая цепь...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>Нельзя работать с бумажником в режиме с удалением блоков.</translation> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>Всегда транслировать транзакции, полученные из белого списка участников (по умолчанию: %d)</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>Не удаётся разрешить адрес в параметре -whitebind: '%s'</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Попытаться восстановить приватные ключи из повреждённого wallet.dat при запуске</translation> + </message> + <message> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Автоматически создавать скрытый Tor сервис (по умолчанию: %d)</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Выбрать каталог данных при запуске (по умолчанию: 0)</translation> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Не удаётся разрешить адрес в параметре -whitebind: '%s'</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3121,10 +3320,6 @@ rpcpassword=%s <translation>Все права защищены © 2009-%i Разработчики Bitcoin Core</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Не удалось разобрать значение %s параметра -rpcbind как сетевой адрес</translation> - </message> - <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Ошибка загрузки wallet.dat: бумажник требует более новую версию Bitcoin Core</translation> </message> @@ -3133,12 +3328,8 @@ rpcpassword=%s <translation>Ошибка чтения базы данных, работа завершается.</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> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Импортировать блоки из внешнего файла blk000?.dat при запуске</translation> </message> <message> <source>Information</source> @@ -3181,18 +3372,10 @@ rpcpassword=%s <translation>Параметры трансляции узла:</translation> </message> <message> - <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> - <translation>Параметры RPC SSL: (см. Bitcoin вики для инструкций по настройке SSL)</translation> - </message> - <message> <source>RPC server options:</source> <translation>Параметры сервера RPC:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>Поддержка RPC постоянных HTTP подключений (по умолчанию: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Перестроить при запуске индекс цепи блоков из текущих файлов blk000??.dat</translation> </message> @@ -3201,30 +3384,26 @@ rpcpassword=%s <translation>Получать и отображать P2P сетевые тревоги (по умолчанию: %u)</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Выводить информацию трассировки/отладки на консоль вместо файла debug.log</translation> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> + <translation>Уменьшите -maxconnections с %d до %d, из-за ограничений системы.</translation> </message> <message> - <source>Send transactions as zero-fee transactions if possible (default: %u)</source> - <translation>Осуществить транзакцию бесплатно, если возможно (по умолчанию: %u)</translation> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Перепроверить цепь блоков на предмет отсутствующих в бумажнике транзакций при запуске</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Указать корневые SSL-сертификаты для запроса платежа (по умолчанию: -system-)</translation> + <source>Send trace/debug info to console instead of debug.log file</source> + <translation>Выводить информацию трассировки/отладки на консоль вместо файла debug.log</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Выберите язык, например "de_DE" (по умолчанию: как в системе)</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> <translation>Показать все отладочные параметры (использование: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Показывать сплэш при запуске (по умолчанию: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Сжимать файл debug.log при запуске клиента (по умолчанию: 1, если нет -debug)</translation> </message> @@ -3233,10 +3412,6 @@ rpcpassword=%s <translation>Не удалось подписать транзакцию</translation> </message> <message> - <source>Start minimized</source> - <translation>Запускать свёрнутым</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>Сумма транзакции слишком мала для уплаты комиссии</translation> </message> @@ -3245,6 +3420,14 @@ rpcpassword=%s <translation>Это экспериментальное ПО.</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>Пароль контроля порта Tor (по умолчанию: пустой)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>Порт контроля Tor используется, если включено прослушивание onion (по умолчанию: %s)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Сумма транзакции слишком мала</translation> </message> @@ -3261,16 +3444,12 @@ rpcpassword=%s <translation>Транзакция слишком большая</translation> </message> <message> - <source>UI Options:</source> - <translation>Настройки интерфейса:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Невозможно привязаться к %s на этом компьютере (bind вернул ошибку %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Использовать UPnP для проброса порта (по умолчанию: 1, если используется прослушивание)</translation> + <source>Upgrade wallet to latest format on startup</source> + <translation>Обновить бумажник до последнего формата при запуске</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3285,20 +3464,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> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>Будет работать в режиме только блоков (по умолчанию: %u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> <translation>Стираем все транзакции из кошелька...</translation> </message> <message> - <source>on startup</source> - <translation>при запуске</translation> + <source>ZeroMQ notification options:</source> + <translation>ZeroMQ параметры оповещения:</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3313,18 +3488,6 @@ rpcpassword=%s <translation>Выполнить команду, когда появляется новый блок (%s в команде заменяется на хэш блока)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Обновить бумажник до последнего формата</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Перепроверить цепь блоков на предмет отсутствующих в бумажнике транзакций</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Использовать OpenSSL (https) для подключений JSON-RPC</translation> - </message> - <message> <source>This help message</source> <translation>Эта справка</translation> </message> @@ -3345,6 +3508,26 @@ rpcpassword=%s <translation>(1 = сохранять метаданные транзакции: например, владельца аккаунта и информацию запроса платежа; 2 = отбросить метаданные)</translation> </message> <message> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>Установлено очень большое значение -maxtxfee. Такие большие комиссии могут быть уплачены в отдельной транзакции.</translation> + </message> + <message> + <source>-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>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>Не хранить транзакции в памяти дольше, чем <n> часов (по умолчанию %u)</translation> + </message> + <message> + <source>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> + <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>Комиссии (в %s/Кб) меньшие этого значения считаются нулевыми при создании транзакций (по умолчанию: %s)</translation> + </message> + <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Насколько тщательна проверка контрольных блоков -checkblocks (0-4, по умолчанию: %u)</translation> </message> @@ -3361,16 +3544,32 @@ rpcpassword=%s <translation>Выводить отладочную информацию (по умолчанию: %u, указание <category> необязательно)</translation> </message> <message> + <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> + <translation>Поддерживать фильтрацию блоков и транзакций с помощью фильтра Блума (по умолчанию: %u)</translation> + </message> + <message> + <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> + <translation>Текущая длина строки версии сети (%i) превышает максимальную длину (%i). Увеливается количество или размер uacomments.</translation> + </message> + <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>Пытается ограничить исходящий трафик до (в МБ за 24ч), 0 = не ограничивать (по умолчанию: %d)</translation> + </message> + <message> + <source>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>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> + <source>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source> + <translation>Имя пользователя и хэш пароля для JSON-RPC соединений. Поле <userpw> использует формат: <USERNAME>:<SALT>$<HASH>. Каноничный пример скрипта на питоне включен в "share/rpcuser". Эта опция может быть указана несколько раз</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Допустимые шифры (по умолчанию: %s)</translation> + <source>(default: %s)</source> + <translation>(по умолчанию: %s)</translation> </message> <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> @@ -3433,18 +3632,14 @@ rpcpassword=%s <translation>Транслировать не-P2SH мультиподпись (по умолчанию: %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> diff --git a/src/qt/locale/bitcoin_ru_RU.ts b/src/qt/locale/bitcoin_ru_RU.ts new file mode 100644 index 0000000000..53a1c1d8a4 --- /dev/null +++ b/src/qt/locale/bitcoin_ru_RU.ts @@ -0,0 +1,245 @@ +<TS language="ru_RU" version="2.1"> +<context> + <name>AddressBookPage</name> + </context> +<context> + <name>AddressTableModel</name> + </context> +<context> + <name>AskPassphraseDialog</name> + </context> +<context> + <name>BanTableModel</name> + </context> +<context> + <name>BitcoinGUI</name> + <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>&About Bitcoin Core</source> + <translation>О Bitcoin Core</translation> + </message> + <message> + <source>&Command-line options</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> + </context> +<context> + <name>ClientModel</name> + </context> +<context> + <name>CoinControlDialog</name> + <message> + <source>Date</source> + <translation>Дата</translation> + </message> + <message> + <source>Confirmations</source> + <translation>Подтверждения</translation> + </message> + <message> + <source>Confirmed</source> + <translation>Подтвержденные</translation> + </message> + <message> + <source>Copy address</source> + <translation>Копировать адрес</translation> + </message> + <message> + <source>yes</source> + <translation>Да</translation> + </message> + <message> + <source>no</source> + <translation>Нет</translation> + </message> + </context> +<context> + <name>EditAddressDialog</name> + <message> + <source>Edit Address</source> + <translation>Изменить адрес</translation> + </message> + </context> +<context> + <name>FreespaceChecker</name> + </context> +<context> + <name>HelpMessageDialog</name> + <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + <message> + <source>version</source> + <translation>версия</translation> + </message> + <message> + <source>About Bitcoin Core</source> + <translation>О Bitcoin Core</translation> + </message> + <message> + <source>Command-line options</source> + <translation>Опции командной строки</translation> + </message> + <message> + <source>command-line options</source> + <translation>Опции командной строки</translation> + </message> + </context> +<context> + <name>Intro</name> + <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</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>URI:</source> + <translation>URI:</translation> + </message> + </context> +<context> + <name>OptionsDialog</name> + </context> +<context> + <name>OverviewPage</name> + </context> +<context> + <name>PaymentServer</name> + </context> +<context> + <name>PeerTableModel</name> + </context> +<context> + <name>QObject</name> + </context> +<context> + <name>QRImageWidget</name> + </context> +<context> + <name>RPCConsole</name> + <message> + <source>&Information</source> + <translation>Информация</translation> + </message> + </context> +<context> + <name>ReceiveCoinsDialog</name> + </context> +<context> + <name>ReceiveRequestDialog</name> + </context> +<context> + <name>RecentRequestsTableModel</name> + <message> + <source>Date</source> + <translation>Дата</translation> + </message> + </context> +<context> + <name>SendCoinsDialog</name> + </context> +<context> + <name>SendCoinsEntry</name> + </context> +<context> + <name>ShutdownWindow</name> + </context> +<context> + <name>SignVerifyMessageDialog</name> + </context> +<context> + <name>SplashScreen</name> + <message> + <source>Bitcoin Core</source> + <translation>Bitcoin Core</translation> + </message> + </context> +<context> + <name>TrafficGraphWidget</name> + </context> +<context> + <name>TransactionDesc</name> + <message> + <source>Date</source> + <translation>Дата</translation> + </message> + </context> +<context> + <name>TransactionDescDialog</name> + </context> +<context> + <name>TransactionTableModel</name> + <message> + <source>Date</source> + <translation>Дата</translation> + </message> + </context> +<context> + <name>TransactionView</name> + <message> + <source>Copy address</source> + <translation>Копировать адрес</translation> + </message> + <message> + <source>Confirmed</source> + <translation>Подтвержденные</translation> + </message> + <message> + <source>Date</source> + <translation>Дата</translation> + </message> + </context> +<context> + <name>UnitDisplayStatusBarControl</name> + </context> +<context> + <name>WalletFrame</name> + </context> +<context> + <name>WalletModel</name> + </context> +<context> + <name>WalletView</name> + </context> +<context> + <name>bitcoin-core</name> + <message> + <source>Information</source> + <translation>Информация</translation> + </message> + <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_sah.ts b/src/qt/locale/bitcoin_sah.ts deleted file mode 100644 index 9ca08ee7da..0000000000 --- a/src/qt/locale/bitcoin_sah.ts +++ /dev/null @@ -1,110 +0,0 @@ -<TS language="sah" version="2.0"> -<context> - <name>AddressBookPage</name> - </context> -<context> - <name>AddressTableModel</name> - </context> -<context> - <name>AskPassphraseDialog</name> - </context> -<context> - <name>BitcoinGUI</name> - </context> -<context> - <name>ClientModel</name> - </context> -<context> - <name>CoinControlDialog</name> - </context> -<context> - <name>EditAddressDialog</name> - </context> -<context> - <name>FreespaceChecker</name> - </context> -<context> - <name>HelpMessageDialog</name> - </context> -<context> - <name>Intro</name> - </context> -<context> - <name>OpenURIDialog</name> - </context> -<context> - <name>OptionsDialog</name> - </context> -<context> - <name>OverviewPage</name> - </context> -<context> - <name>PaymentServer</name> - </context> -<context> - <name>PeerTableModel</name> - </context> -<context> - <name>QObject</name> - </context> -<context> - <name>QRImageWidget</name> - </context> -<context> - <name>RPCConsole</name> - </context> -<context> - <name>ReceiveCoinsDialog</name> - </context> -<context> - <name>ReceiveRequestDialog</name> - </context> -<context> - <name>RecentRequestsTableModel</name> - </context> -<context> - <name>SendCoinsDialog</name> - </context> -<context> - <name>SendCoinsEntry</name> - </context> -<context> - <name>ShutdownWindow</name> - </context> -<context> - <name>SignVerifyMessageDialog</name> - </context> -<context> - <name>SplashScreen</name> - </context> -<context> - <name>TrafficGraphWidget</name> - </context> -<context> - <name>TransactionDesc</name> - </context> -<context> - <name>TransactionDescDialog</name> - </context> -<context> - <name>TransactionTableModel</name> - </context> -<context> - <name>TransactionView</name> - </context> -<context> - <name>UnitDisplayStatusBarControl</name> - </context> -<context> - <name>WalletFrame</name> - </context> -<context> - <name>WalletModel</name> - </context> -<context> - <name>WalletView</name> - </context> -<context> - <name>bitcoin-core</name> - </context> -</TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index 48d5a09142..8c779cbe98 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -1,4 +1,4 @@ -<TS language="sk" version="2.0"> +<TS language="sk" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -871,7 +874,7 @@ <source>command-line options</source> <translation>voľby príkazového riadku</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -1069,6 +1072,10 @@ <translation>Port proxy (napr. 9050)</translation> </message> <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Použiť samostatný SOCKS5 proxy server na dosiahnutie počítačov cez skryté služby Tor:</translation> + </message> + <message> <source>&Window</source> <translation>Okno</translation> </message> @@ -1287,10 +1294,6 @@ <translation>Požiadavka na platbu %1 je príliš veľká (%2 bajtov, povolené je %3 bajtov).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Ochrana pred zahltením požiadavkami na platbu</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Chyba komunikácie s %1: %2 </translation> </message> @@ -1479,14 +1482,6 @@ <translation>Služby</translation> </message> <message> - <source>Starting Height</source> - <translation>Počiatočná výška</translation> - </message> - <message> - <source>Sync Height</source> - <translation>Synchronizovaná výška</translation> - </message> - <message> <source>Ban Score</source> <translation>Skóre zákazu</translation> </message> @@ -1503,14 +1498,6 @@ <translation>Posledné prijatie</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Odoslaných bajtov</translation> - </message> - <message> - <source>Bytes Received</source> - <translation>Prijatých bajtov</translation> - </message> - <message> <source>Ping Time</source> <translation>Čas odozvy</translation> </message> @@ -1610,10 +1597,6 @@ <source>Unknown</source> <translation>neznámy</translation> </message> - <message> - <source>Fetching...</source> - <translation>Získava sa...</translation> - </message> </context> <context> <name>ReceiveCoinsDialog</name> @@ -1979,10 +1962,6 @@ <translation>Kopírovať zmenu</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Celková suma %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>alebo</translation> </message> @@ -2015,10 +1994,6 @@ <translation>Vypršala platnosť požiadavky na platbu.</translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Zaplatiť minimálny poplatok %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>Adresa príjemcu je neplatná. Prosím, overte ju.</translation> </message> @@ -2777,10 +2752,6 @@ <translation>Bežať na pozadí ako démon a prijímať príkazy</translation> </message> <message> - <source>Use the test network</source> - <translation>Použiť testovaciu sieť</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Prijať spojenia zvonku (predvolené: 1 ak žiadne -proxy alebo -connect)</translation> </message> @@ -2813,10 +2784,6 @@ <translation>Nepodarilo sa pripojiť na %s na tomto počítači. Bitcoin Jadro je už pravdepodobne spustené.</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> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Varovanie: Javí sa že sieť sieť úplne nesúhlasí! Niektorí mineri zjavne majú ťažkosti. @@ -2827,10 +2794,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Varovanie: Zjavne sa úplne nezhodujeme s našimi peer-mi! Možno potrebujete prejsť na novšiu verziu alebo ostatné uzly potrebujú vyššiu verziu.</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>Varovanie: chyba pri čítaní wallet.dad! Všetky kľúče sú čitateľné ale transakčné dáta alebo záznamy v adresári môžu byť nesprávne.</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>Varovanie: wallet.dat je poškodený, údaje úspešne získané! Pôvodný wallet.dat uložený ako wallet.{timestamp}.bak v %s; ak váš zostatok alebo transakcie niesu správne, mali by ste súbor obnoviť zo zálohy.</translation> </message> @@ -2839,18 +2802,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Uzle na zoznam povolených, ktoré sa pripájajú z danej netmask alebo IP adresy. Môže byť zadané viac krát.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(predvolené: 1)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> môže byť:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Pokus zachrániť súkromné kľúče z poškodeného wallet.dat</translation> - </message> - <message> <source>Block creation options:</source> <translation>Voľby vytvorenia bloku:</translation> </message> @@ -2895,10 +2850,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Chyba otvárania databázy blokov</translation> </message> <message> - <source>Error: A fatal internal error occured, see debug.log for details</source> - <translation>Chyba: Nastala fatálna interná chyba. Pre podrobnosti pozrite debug.log</translation> - </message> - <message> <source>Error: Disk space is low!</source> <translation>Chyba: Málo miesta na disku!</translation> </message> @@ -2907,10 +2858,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Chyba počúvania na ktoromkoľvek porte. Použi -listen=0 ak toto chcete.</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> - <message> <source>Importing...</source> <translation>Prebieha import ...</translation> </message> @@ -2967,18 +2914,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Potrebujete prebudovať databázu použitím -reindex zmeniť -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importuje bloky z externého súboru blk000??.dat</translation> - </message> - <message> <source>Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source> <translation>Povoliť JSON-RPC pripojenia zo zadaného zdroja. Pre <ip> sú platné jednoduché IP (napr. 1.2.3.4), sieť/netmask (napr. 1.2.3.4/255.255.255.0) alebo sieť/CIDR (napr. 1.2.3.4/24). Táto možnosť môže byť zadaná niekoľko krát</translation> </message> <message> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation>Pri nastavovaní RPC adresy %s na porte %u pre počúvanie došlo k chybe: %s</translation> - </message> - <message> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> <translation>Spojiť s danou adresou a povolenými partnerskými zariadeniami ktoré sa tam pripájajú. Použite zápis [host]:port pre IPv6</translation> </message> @@ -2999,18 +2938,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Chyba: Počúvanie prichádzajúcich spojení zlyhalo (vrátená chyba je %s)</translation> </message> <message> - <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> - <translation>Chyba: Nájdený nepodporovaný argument -socks. Nastavenie SOCKS verzie nie je už možné, podporované sú už iba proxy SOCKS5.</translation> - </message> - <message> <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source> <translation>Vykonať príkaz po prijatí patričného varovania alebo uvidíme veľmi dlhé rozdvojenie siete (%s v cmd je nahradené správou)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Poplatky (v BTC/Kb) nižšie ako toľkoto sa považujú za nulové pri postupovaní transakcií (predvolené: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Ak nie je nastavené paytxfee, pridať dostatočný poplatok aby sa transakcia začala potvrdzovať priemerne v rámci bloku (predvolené: %u)</translation> </message> @@ -3039,10 +2970,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Tento produkt obsahuje softvér vyvinutý projektom OpenSSL pre použitie sady nástrojov OpenSSL <https://www.openssl.org/> a kryptografického softvéru napísaného Eric Young a UPnP softvér napísaný Thomas Bernard.</translation> </message> <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Upozornenie: -maxtxfee je nastavené príliš vysoko! Takto vysoké poplatky by mali byť zaplatené za jednu transakciu.</translation> - </message> - <message> <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source> <translation>Uzle na zoznam povolených nemôžu byť DoS zakázané a ich transakcie vždy postúpené ďalej, aj v prípade, ak sú už pamäťovej fronte. Užitočné napr. pre brány</translation> </message> @@ -3059,10 +2986,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Nedá sa vyriešiť -whitebind adresa: '%s'</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Zvoľte dátový priečinok pri štarte (prednastavené: 0)</translation> - </message> - <message> <source>Connect through SOCKS5 proxy</source> <translation>Pripojiť cez proxy server SOCKS5</translation> </message> @@ -3071,10 +2994,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Autorské práva (C) 2009-%i Vývojári jadra Bitcoin</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Nedá sa analyzovať -rpcbind hodnota %s ako sieťová adresa</translation> - </message> - <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Chyba pri čítaní wallet.dat: Peňaženka vyžaduje vyššiu verziu Jadra Bitcoin</translation> </message> @@ -3083,14 +3002,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Chyba pri načítaní z databázy, ukončuje sa.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Chyba: nájdený nepodporovaný argument -tor, použite -onion.</translation> - </message> - <message> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation>Poplatok (v BTC/kB), ktorý sa pridá k transakciám, ktoré odosielate (predvolený: %s)</translation> - </message> - <message> <source>Information</source> <translation>Informácia</translation> </message> @@ -3127,18 +3038,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Prenosové možnosti uzla:</translation> </message> <message> - <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> - <translation>Možnosti RPC SSL: (Pozri v Bitcoin Wiki pokyny pre SSL nastavenie)</translation> - </message> - <message> <source>RPC server options:</source> <translation>Možnosti servra RPC:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>Podpora RPC pre trvalé HTTP spojenia (predvolené: %d)</translation> - </message> - <message> <source>Receive and display P2P network alerts (default: %u)</source> <translation>Obdržať a zobraziť sieťové P2P varovania (predvolené: %u)</translation> </message> @@ -3151,22 +3054,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Poslať ako transakcie bez poplatku, ak je to možné (predvolené: %u)</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Nastaviť koreňový certifikát pre výzvy na platbu (prednastavené: -system-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Nastaviť jazyk, napríklad "sk_SK" (predvolené: systémový)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>Zobraziť všetky možnosti ladenia (použitie: --help --help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Zobraziť splash screen pri spustení (predvolené: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Zmenšiť debug.log pri spustení klienta (predvolené: 1 ak bez -debug)</translation> </message> @@ -3175,10 +3066,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>Start minimized</source> - <translation>Spustiť minimalizované</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Toto je experimentálny softvér.</translation> </message> @@ -3199,18 +3086,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Transakcia príliš veľká</translation> </message> <message> - <source>UI Options:</source> - <translation>Možnosti používateľského rozhrania:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Na tomto počítači sa nedá vytvoriť väzba %s (vytvorenie väzby vrátilo chybu %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Skúsiť použiť UPnP pre mapovanie počúvajúceho portu (default: 1 when listening)</translation> - </message> - <message> <source>Username for JSON-RPC connections</source> <translation>Užívateľské meno pre JSON-RPC spojenia</translation> </message> @@ -3219,22 +3098,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Upozornenie</translation> </message> <message> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation>Upozornenie: Nepodporovaný argument -benchmark bol ignorovaný, použite -debug=bench.</translation> - </message> - <message> - <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> - <translation>Upozornenie: Nepodporovaný argument -debugnet bol ignorovaný, použite -debug=net.</translation> - </message> - <message> <source>Zapping all transactions from wallet...</source> <translation>Zmazať všetky transakcie z peňaženky...</translation> </message> <message> - <source>on startup</source> - <translation>pri štarte</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>wallet.dat je poškodený, záchrana zlyhala</translation> </message> @@ -3247,18 +3114,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Vykonaj príkaz, ak zmeny v najlepšom bloku (%s v príkaze nahradí blok hash)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Aktualizuj peňaženku na najnovší formát.</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Použiť OpenSSL (https) pre JSON-RPC spojenia</translation> - </message> - <message> <source>This help message</source> <translation>Táto pomocná správa</translation> </message> @@ -3303,10 +3158,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>(predvolené: %s)</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Prijateľné šifry (predvolené: %s)</translation> - </message> - <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> <translation>Vždy sa dotazovať adresy partnerských uzlov cez vyhľadávanie DNS (predvolené: %u)</translation> </message> @@ -3315,6 +3166,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Chyba načítania wallet.dat</translation> </message> <message> + <source>Generate coins (default: %u)</source> + <translation>Generovať mince (predvolené: %u)</translation> + </message> + <message> <source>How many blocks to check at startup (default: %u, 0 = all)</source> <translation>Koľko blokov overiť pri spustení (predvolené: %u, 0 = všetky)</translation> </message> @@ -3359,14 +3214,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin <translation>Prenášať non-P2SH multi-podpis (predvolené: %u)</translation> </message> <message> - <source>Server certificate file (default: %s)</source> - <translation>Certifikačný súbor servera (predvolené: %s)</translation> - </message> - <message> - <source>Server private key (default: %s)</source> - <translation>Privátny kľúč servera (predvolené: %s)</translation> - </message> - <message> <source>Set key pool size to <n> (default: %u)</source> <translation>Nastaviť veľkosť kľúča fronty na <n> (predvolené: %u)</translation> </message> diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index 39dcb6e997..c62c8cf273 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.0"> +<TS language="sl_SI" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -871,7 +874,7 @@ <source>command-line options</source> <translation>možnosti ukazne vrstice</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -914,7 +917,11 @@ <source>%n GB of free space available</source> <translation><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform></translation> </message> - </context> + <message numerus="yes"> + <source>(of %n GB needed)</source> + <translation><numerusform>(od potrebnih %n GiB)</numerusform><numerusform>(od potrebnih %n GiB)</numerusform><numerusform>(od potrebnih %n GiB)</numerusform><numerusform>(od potrebnih %n GiB)</numerusform></translation> + </message> +</context> <context> <name>OpenURIDialog</name> <message> @@ -1065,6 +1072,10 @@ <translation>Vrata posredniškega strežnika (npr. 9050)</translation> </message> <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Za dostop do soležnikov preko skritih storitev Tor uporabi drug posredniški strežnik SOCKS5:</translation> + </message> + <message> <source>&Window</source> <translation>O&kno</translation> </message> @@ -1283,10 +1294,6 @@ <translation>Zahtevek za plačilo %1 je prevelik (%2 bajtov, dovoljenih je %3 bajtov.)</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Zaščita pred napadom denial-of-service zahtevka za plačilo</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Napaka pri povezavi z %1: %2</translation> </message> @@ -1475,14 +1482,6 @@ <translation>Storitve</translation> </message> <message> - <source>Starting Height</source> - <translation>Začetna višina</translation> - </message> - <message> - <source>Sync Height</source> - <translation>Trenutna višina</translation> - </message> - <message> <source>Ban Score</source> <translation>Kazenske točke</translation> </message> @@ -1499,14 +1498,6 @@ <translation>Nazadnje prejeto</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Oddanih bajtov</translation> - </message> - <message> - <source>Bytes Received</source> - <translation>Prejetih bajtov</translation> - </message> - <message> <source>Ping Time</source> <translation>Odzivni čas</translation> </message> @@ -1603,12 +1594,16 @@ <translation>Odhodna</translation> </message> <message> - <source>Unknown</source> - <translation>Neznano</translation> + <source>Yes</source> + <translation>Da</translation> </message> <message> - <source>Fetching...</source> - <translation>Pridobivam ...</translation> + <source>No</source> + <translation>Ne</translation> + </message> + <message> + <source>Unknown</source> + <translation>Neznano</translation> </message> </context> <context> @@ -1975,10 +1970,6 @@ <translation>Kopiraj vračilo</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Skupni znesek %1 (= %2)</translation> - </message> - <message> <source>or</source> <translation>ali</translation> </message> @@ -2015,10 +2006,6 @@ <translation><numerusform>Predviden začetek potrditev po %n najdenem bloku.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Plačilo samo minimalne provizije v znesku %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>Naslov prejemnika je neveljaven. Prosimo, preverite.</translation> </message> @@ -2801,10 +2788,6 @@ <translation>Teci v ozadju in sprejemaj ukaze</translation> </message> <message> - <source>Use the test network</source> - <translation>Uporabi testno omrežje</translation> - </message> - <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Sprejemaj zunanje povezave (privzeto: 1, razen če ste vklopili opciji -proxy ali -connect)</translation> </message> @@ -2821,14 +2804,6 @@ <translation>Izvedi ukaz, ko bo transakcija denarnice se spremenila (V cmd je bil TxID zamenjan za %s)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Največji še veljavni skupni znesek provizij pri transakcijah z uporabo ene denarnice. Prenizka nastavitev lahko povzroči izločitev večjih transakcij (privzeto %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Omogoči obrezovanje (brisanje) starejših blokov in s tem prihrani pri prostoru za shranjevanje. Ta način delovanja onemogoči uporabo denarnice in ni združljivo z opcijo -txindex. Opozorilo: Če kasneje to opcijo povrnete na privzeto vrednost, boste morali ponovno prenesti celotno verigo. (privzeto: 0 = onemogoči obrezovanje, >%u = ciljna velikost datotek blokov v MiB)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Nastavi število niti za preverjanje skript (%u do %d, 0 = samodejno, <0 toliko procesorskih jeder naj ostane prostih, privzeto: %d)</translation> </message> @@ -2849,10 +2824,6 @@ <translation>OPOZORILO: Preverite vašo omrežno povezavo. Št. prejetih blokov: %d v št. ur: %d (pričakovanih je %d blokov)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Opozorilo: Vrednost opcije -paytxfee je zelo visoka. To je provizija, ki jo boste plačali, če izvedete plačilo.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Opozorilo: Trenutno na omrežju ni videti konsenza! Videti je, kot da bi imeli nekateri rudarji težave.</translation> </message> @@ -2861,10 +2832,6 @@ <translation>Opozorilo: Trenutno se s soležniki ne strinjam v popolnosti! Mogoče bi morali vi ali drugi udeleženci posodobiti odjemalce.</translation> </message> <message> - <source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> - <translation>Opozorilo: napaka pri branju datoteke wallet.dat! Vsi ključi so bili pravilno prebrani, podatki o transakciji ali imenik vnešenih naslovov so morda izgubljeni ali nepravilni.</translation> - </message> - <message> <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source> <translation>Opozorilo: Datoteka wallet.dat je bila okvarjena, podatki pa so bili kljub temu rešeni! Originalna datoteka je bila shranjena kot wallet.{čas.oznaka}.bak v mapo %s. Če sta skupno stanje ali seznam transakcij napačna, morate datoteko restavrirati iz varnostne kopije.</translation> </message> @@ -2873,18 +2840,10 @@ <translation>Sprejemaj povezave samo od soležnikov, ki so na naslovih, ki ustrezajo navedeni omrežni maski ali naslovu. Opcijo lahko navedete večkrat.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(privzeto: 1)</translation> - </message> - <message> <source><category> can be:</source> <translation><category> je lahko:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Skušaj obnoviti zasebne ključe iz okvarjene datoteke wallet.dat</translation> - </message> - <message> <source>Block creation options:</source> <translation>Možnosti ustvarjanja blokov:</translation> </message> @@ -2929,10 +2888,6 @@ <translation>Napaka pri odpiranju podatkovne baze blokov</translation> </message> <message> - <source>Error: A fatal internal error occured, see debug.log for details</source> - <translation>Napaka: Med izvajanjem je prišlo do nepopravljive napake. Podrobnosti so v datoteki debug.log</translation> - </message> - <message> <source>Error: Disk space is low!</source> <translation>Opozorilo: Premalo prostora na disku!</translation> </message> @@ -2941,10 +2896,6 @@ <translation>Ni mogoče poslušati na nobenih vratih. Če to zares želite, uporabite opcijo -listen=0.</translation> </message> <message> - <source>If <category> is not supplied, output all debugging information.</source> - <translation>Če element <category> ni naveden, izpisuje vse informacije za razhroščevanje.</translation> - </message> - <message> <source>Importing...</source> <translation>Uvažam ...</translation> </message> @@ -3013,18 +2964,10 @@ <translation>Ob spremembi vrednosti opcije -txindex boste morali obnoviti bazo podatkov z uporabo opcije -reindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Uvozi bloke iz zunanje datoteke blk000??.dat</translation> - </message> - <message> <source>Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source> <translation>Iz navedenega vira dovoli povezave na JSON-RPC. Veljavne oblike vrednosti parametra <ip> so: edinstven naslov IP (npr.: 1.2.3.4), kombinacija omrežje/netmask (npr.: 1.2.3.4/255.255.255.0), ali pa kombinacija omrežje/CIDR (1.2.3.4/24). To opcijo lahko navedete večkrat.</translation> </message> <message> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation>Prišlo je do napake med zagonom poslušalca RPC na naslovu %s in vratih %u: %s</translation> - </message> - <message> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> <translation>Veži dani naslov in sprejemaj povezave samo od navedenih soležnikov. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata.</translation> </message> @@ -3049,18 +2992,10 @@ <translation>Napaka: Ni mogoče sprejemati dohodnih povezav (vrnjena napaka: %s)</translation> </message> <message> - <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> - <translation>Napaka: Navedli ste nepodprto vrednost opcije -socks. Različice protokola SOCKS ni več mogoče navesti, podprti so samo posredniški strežniki tipa SOCKS5.</translation> - </message> - <message> <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source> <translation>Ko bo prejeto ustrezno opozorilo, ali ko bo opažena zelo dolga razvejitev, izvedi navedeni ukazni niz. (Niz %s bo nadomeščen z vsebino sporočila.)</translation> </message> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Provizije (v BTC/KiB), ki so manjše od te vrednosti, se pri posredovanju smatrajo za nične (privzeto: %s)</translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>Če opcija -paytxfee ni nastavljena, nastavi znesek provizije tako visoko, da bodo transakcije potrjene v povprečno n blokih. (privzeto: %u)</translation> </message> @@ -3069,10 +3004,6 @@ <translation>Na vsak posredniški strežnik se prijavi z drugimi naključnimi podatki. Tako je omogočena osamitev tokov v omrežju Tor (privzeto: %u)</translation> </message> <message> - <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> - <translation>Opozorilo: Preverite, če sta datum in ura na vašem računalniku točna! Bitcoin Core ne bo dobro deloval, če je nastavljeni čas nepravilen.</translation> - </message> - <message> <source>(default: %u)</source> <translation>(privzeto: %u)</translation> </message> @@ -3081,18 +3012,10 @@ <translation>Preklapljam na najboljšo verigo ...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>Če je omogočena funkcija obrezovanja, ni mogoče uporabljati denarnice.</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>Naslova %s, podanega pri opciji -whitebind ni mogoče razrešiti.</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Ob zagonu pozovi uporabnika, naj izbere podatkovno mapo (privzeto: 0)</translation> - </message> - <message> <source>Connect through SOCKS5 proxy</source> <translation>Poveži se preko posredniškega strežnika SOCKS5</translation> </message> @@ -3101,32 +3024,28 @@ <translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Vrednost %s opcije -rpcbind ni prepoznaven omrežni naslov</translation> - </message> - <message> <source>Information</source> <translation>Informacije</translation> </message> <message> - <source>Need to specify a port with -whitebind: '%s'</source> - <translation>Pri opciji -whitebind morate navesti vrata: %s</translation> + <source>Invalid amount for -maxtxfee=<amount>: '%s'</source> + <translation>Neveljavna količina za -maxtxfee=<amount>: '%s'</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Pošilja sledilne/razhroščevalne informacije na konzolo namesto v datoteko debug.log</translation> + <source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source> + <translation>Neveljavna količina za -minrelaytxfee=<amount>: '%s'</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Nastavi korenske certifikate SSL za preverjanje zahtevkov za plačilo (privzeto: -system-)</translation> + <source>Invalid amount for -mintxfee=<amount>: '%s'</source> + <translation>Neveljavna količina za -mintxfee=<amount>: '%s'</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Nastavi jezik, npr. "sl_SI" (privzeto: jezik sistema)</translation> + <source>Need to specify a port with -whitebind: '%s'</source> + <translation>Pri opciji -whitebind morate navesti vrata: %s</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Ob zagonu prikaži uvodni zaslon (privzeto: 1)</translation> + <source>Send trace/debug info to console instead of debug.log file</source> + <translation>Pošilja sledilne/razhroščevalne informacije na konzolo namesto v datoteko debug.log</translation> </message> <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> @@ -3137,10 +3056,6 @@ <translation>Transakcije ni bilo mogoče podpisati.</translation> </message> <message> - <source>Start minimized</source> - <translation>Zaženi v minimiranem oknu</translation> - </message> - <message> <source>This is experimental software.</source> <translation>Program je eksperimentalne narave.</translation> </message> @@ -3157,10 +3072,6 @@ <translation>Transkacija je prevelika</translation> </message> <message> - <source>UI Options:</source> - <translation>Možnosti uporabniškega vmesnika:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Na tem računalniku ni bilo mogoče vezati naslova %s (vrnjena napaka: %s)</translation> </message> @@ -3177,10 +3088,6 @@ <translation>Brišem vse transakcije iz denarnice ...</translation> </message> <message> - <source>on startup</source> - <translation>ob zagonu</translation> - </message> - <message> <source>wallet.dat corrupt, salvage failed</source> <translation>Datoteka wallet.dat je poškodovana in je ni bilo mogoče obnoviti.</translation> </message> @@ -3193,18 +3100,6 @@ <translation>Izvedi ukaz, ko je najden najboljši blok (niz %s v ukazu bo zamenjan s hash vrednostjo bloka)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Nadgradi denarnico na najnovejšo različico</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>S ponovnim pregledom verige blokov poišči manjkajoče transakcije iz denarnice</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Uporabi OpenSSL (https) za povezave na JSON-RPC</translation> - </message> - <message> <source>This help message</source> <translation>To sporočilo pomoči</translation> </message> @@ -3229,10 +3124,6 @@ <translation>(privzeto: %s)</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Sprejemljivi tipi šifriranja (privzeto: %s)</translation> - </message> - <message> <source>Error loading wallet.dat</source> <translation>Napaka pri nalaganju wallet.dat</translation> </message> diff --git a/src/qt/locale/bitcoin_sq.ts b/src/qt/locale/bitcoin_sq.ts index 6ed9856889..994b065994 100644 --- a/src/qt/locale/bitcoin_sq.ts +++ b/src/qt/locale/bitcoin_sq.ts @@ -1,4 +1,4 @@ -<TS language="sq" version="2.0"> +<TS language="sq" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -169,6 +169,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Synchronizing with network...</source> @@ -199,6 +202,10 @@ <translation>&Opsione</translation> </message> <message> + <source>&Receiving addresses...</source> + <translation>Duke marr adresen</translation> + </message> + <message> <source>Change the passphrase used for wallet encryption</source> <translation>Ndrysho frazkalimin e përdorur per enkriptimin e portofolit</translation> </message> @@ -418,6 +425,10 @@ <source>Options</source> <translation>Opsionet</translation> </message> + <message> + <source>W&allet</source> + <translation>Portofol</translation> + </message> </context> <context> <name>OverviewPage</name> @@ -445,6 +456,10 @@ <context> <name>RPCConsole</name> <message> + <source>&Information</source> + <translation>Informacion</translation> + </message> + <message> <source>&Open</source> <translation>&Hap</translation> </message> @@ -460,17 +475,29 @@ <source>Unknown</source> <translation>i/e panjohur</translation> </message> - </context> +</context> <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>Shuma:</translation> + </message> + <message> <source>&Label:</source> <translation>&Etiketë:</translation> </message> + <message> + <source>Clear</source> + <translation>Pastro</translation> + </message> </context> <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>&Kopjo adresen</translation> + </message> + <message> <source>Address</source> <translation>Adresë</translation> </message> @@ -509,6 +536,10 @@ <translation>Dërgo Monedha</translation> </message> <message> + <source>Insufficient funds!</source> + <translation>Fonde te pamjaftueshme</translation> + </message> + <message> <source>Amount:</source> <translation>Shuma:</translation> </message> @@ -567,6 +598,10 @@ <source>Alt+P</source> <translation>Alt+P</translation> </message> + <message> + <source>Pay To:</source> + <translation>Paguaj drejt:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -619,6 +654,10 @@ <translation>Data</translation> </message> <message> + <source>Transaction</source> + <translation>transaksionit</translation> + </message> + <message> <source>Amount</source> <translation>Sasia</translation> </message> @@ -755,6 +794,10 @@ <context> <name>bitcoin-core</name> <message> + <source>Options:</source> + <translation>Opsionet:</translation> + </message> + <message> <source>Information</source> <translation>Informacion</translation> </message> diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts index ddaab9ab2b..b6ba896b38 100644 --- a/src/qt/locale/bitcoin_sr.ts +++ b/src/qt/locale/bitcoin_sr.ts @@ -1,4 +1,4 @@ -<TS language="sr" version="2.0"> +<TS language="sr" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -133,6 +133,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Synchronizing with network...</source> @@ -219,6 +222,10 @@ <translation>Трака са картицама</translation> </message> <message> + <source>&About Bitcoin Core</source> + <translation>O Bitcoin Coru</translation> + </message> + <message> <source>Up to date</source> <translation>Ажурно</translation> </message> @@ -335,6 +342,10 @@ <translation>Поставке</translation> </message> <message> + <source>W&allet</source> + <translation>новчаник</translation> + </message> + <message> <source>&Unit to show amounts in:</source> <translation>&Јединица за приказивање износа:</translation> </message> @@ -372,10 +383,18 @@ <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>Iznos:</translation> + </message> + <message> <source>&Label:</source> <translation>&Етикета</translation> </message> <message> + <source>&Message:</source> + <translation>Poruka:</translation> + </message> + <message> <source>Copy label</source> <translation>kopiraj naziv</translation> </message> @@ -387,6 +406,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>Kopirajte adresu</translation> + </message> + <message> <source>Address</source> <translation>Адреса</translation> </message> @@ -398,6 +421,10 @@ <source>Label</source> <translation>Етикета</translation> </message> + <message> + <source>Message</source> + <translation>Poruka</translation> + </message> </context> <context> <name>RecentRequestsTableModel</name> @@ -410,6 +437,10 @@ <translation>Етикета</translation> </message> <message> + <source>Message</source> + <translation>Poruka</translation> + </message> + <message> <source>Amount</source> <translation>iznos</translation> </message> @@ -448,6 +479,10 @@ <context> <name>SendCoinsEntry</name> <message> + <source>A&mount:</source> + <translation>Iznos:</translation> + </message> + <message> <source>&Label:</source> <translation>&Етикета</translation> </message> @@ -511,6 +546,14 @@ <translation>етикета</translation> </message> <message> + <source>Message</source> + <translation>Poruka</translation> + </message> + <message> + <source>Transaction</source> + <translation>transakcije</translation> + </message> + <message> <source>Amount</source> <translation>iznos</translation> </message> @@ -751,10 +794,6 @@ <translation>Radi u pozadini kao daemon servis i prihvati komande</translation> </message> <message> - <source>Use the test network</source> - <translation>Koristi testnu mrežu</translation> - </message> - <message> <source>Username for JSON-RPC connections</source> <translation>Korisničko ime za JSON-RPC konekcije</translation> </message> @@ -763,14 +802,6 @@ <translation>Lozinka za JSON-RPC konekcije</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Koristi OpenSSL (https) za JSON-RPC konekcije</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 0139154019..756114351f 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -1,4 +1,4 @@ -<TS language="sv" version="2.0"> +<TS language="sv" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -222,6 +222,17 @@ Var vänlig och försök igen.</translation> </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/nätmask</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Bannad tills</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -728,6 +739,10 @@ Var vänlig och försök igen.</translation> <translation>Denna etikett blir röd om någon mottagare får ett belopp mindre än %1.</translation> </message> <message> + <source>Can vary +/- %1 satoshi(s) per input.</source> + <translation>Kan variera +/- %1 satoshi per inmatning.</translation> + </message> + <message> <source>yes</source> <translation>ja</translation> </message> @@ -868,6 +883,34 @@ Var vänlig och försök igen.</translation> <source>command-line options</source> <translation>kommandoradsalternativ</translation> </message> + <message> + <source>UI Options:</source> + <translation>UI-inställningar:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Välj datakatalog vid uppstart (standard: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Ange språk, till exempel "de_DE" (standard: systemspråk)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Starta minimerad</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Ange SSL rotcertifikat för betalningsansökan (standard: -system-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Visa startbild vid uppstart (standard: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Återställ alla inställningar som gjorts över GUI</translation> + </message> </context> <context> <name>Intro</name> @@ -1066,6 +1109,34 @@ Var vänlig och försök igen.</translation> <translation>Proxyns port (t.ex. 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Används för att nå noder via:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Visas, om den angivna standard-SOCKS5-proxyn används för att nå noder via den här nätverkstypen.</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Anslut till Bitcoin-nätverket genom en separat SOCKS5-proxy för dolda tjänster i Tor.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Använd separat SOCKS5-proxy för att nå noder via dolda tjänster i Tor:</translation> + </message> + <message> <source>&Window</source> <translation>&Fönster</translation> </message> @@ -1284,10 +1355,6 @@ Var vänlig och försök igen.</translation> <translation>Betalningsbegäran %1 är för stor (%2 bytes, tillåten %3 bytes)</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Betalningsbegäran begär DoS-skydd</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Kommunikationsfel med %1: %2</translation> </message> @@ -1440,6 +1507,18 @@ Var vänlig och försök igen.</translation> <translation>Aktuellt antal block</translation> </message> <message> + <source>Memory Pool</source> + <translation>Minnespool</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>Nuvarande antal transaktioner</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Minnesåtgång</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>Öppna felsökningsloggfilen för Bitcoin Core från den nuvarande datakatalogen. Detta kan ta några sekunder om loggfilen är stor.</translation> </message> @@ -1456,10 +1535,18 @@ Var vänlig och försök igen.</translation> <translation>&Klienter</translation> </message> <message> + <source>Banned peers</source> + <translation>Bannade noder</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Välj en klient för att se detaljerad information.</translation> </message> <message> + <source>Whitelisted</source> + <translation>Vitlistad</translation> + </message> + <message> <source>Direction</source> <translation>Riktning</translation> </message> @@ -1468,20 +1555,24 @@ Var vänlig och försök igen.</translation> <translation>Version</translation> </message> <message> - <source>User Agent</source> - <translation>Användaragent</translation> + <source>Starting Block</source> + <translation>Startblock</translation> </message> <message> - <source>Services</source> - <translation>Tjänster</translation> + <source>Synced Headers</source> + <translation>Synkade huvuden</translation> </message> <message> - <source>Starting Height</source> - <translation>Starthöjd</translation> + <source>Synced Blocks</source> + <translation>Synkade block</translation> </message> <message> - <source>Sync Height</source> - <translation>Synchöjd</translation> + <source>User Agent</source> + <translation>Användaragent</translation> + </message> + <message> + <source>Services</source> + <translation>Tjänster</translation> </message> <message> <source>Ban Score</source> @@ -1500,16 +1591,16 @@ Var vänlig och försök igen.</translation> <translation>Senast mottagen</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Bytes sänt</translation> + <source>Ping Time</source> + <translation>Pingtid</translation> </message> <message> - <source>Bytes Received</source> - <translation>Bytes mottaget</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>Tidsåtgången för en nuvarande utestående ping.</translation> </message> <message> - <source>Ping Time</source> - <translation>Pingtid</translation> + <source>Ping Wait</source> + <translation>Pingväntetid</translation> </message> <message> <source>Time Offset</source> @@ -1560,6 +1651,34 @@ Var vänlig och försök igen.</translation> <translation>Rensa konsollen</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>&Koppla från nod</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Banna nod i</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &timme</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &dag</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &vecka</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &år</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>&Ta bort ban från nod</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Välkommen till RPC-konsolen för Bitcoin Core.</translation> </message> @@ -1588,6 +1707,10 @@ Var vänlig och försök igen.</translation> <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(nod-id: %1)</translation> + </message> + <message> <source>via %1</source> <translation>via %1</translation> </message> @@ -1604,17 +1727,25 @@ Var vänlig och försök igen.</translation> <translation>Utgående</translation> </message> <message> - <source>Unknown</source> - <translation>Okänd</translation> + <source>Yes</source> + <translation>Ja</translation> </message> <message> - <source>Fetching...</source> - <translation>Hämtar...</translation> + <source>No</source> + <translation>Nej</translation> + </message> + <message> + <source>Unknown</source> + <translation>Okänd</translation> </message> </context> <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>&Belopp:</translation> + </message> + <message> <source>&Label:</source> <translation>&Etikett:</translation> </message> @@ -1972,8 +2103,8 @@ Var vänlig och försök igen.</translation> <translation>Kopiera växel</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Totalt %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Total summa %1</translation> </message> <message> <source>or</source> @@ -2007,15 +2138,15 @@ Var vänlig och försök igen.</translation> <source>Payment request expired.</source> <translation>Betalningsbegäran löpte ut.</translation> </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>Betala endast den nödvändiga avgiften på %1</translation> + </message> <message numerus="yes"> <source>Estimated to begin confirmation within %n block(s).</source> <translation><numerusform>Uppskattas till att påbörja bekräftelse inom %n block.</numerusform><numerusform>Uppskattas till att påbörja bekräftelse inom %n block.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Betala endast den minimala avgiften på %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>Mottagarens adress är ogiltig. Kontrollera igen.</translation> </message> @@ -2099,6 +2230,10 @@ Var vänlig och försök igen.</translation> <translation>Avgiften dras från beloppet som skickas. Mottagaren kommer att få mindre bitcoins än du angivit i belopp-fältet. Om flera mottagare valts kommer avgiften delas jämt.</translation> </message> <message> + <source>S&ubtract fee from amount</source> + <translation>S&ubtrahera avgiften från beloppet</translation> + </message> + <message> <source>Message:</source> <translation>Meddelande:</translation> </message> @@ -2643,6 +2778,10 @@ Var vänlig och försök igen.</translation> <translation>Kopiera transaktions ID</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>Kopiera rå transaktion</translation> + </message> + <message> <source>Edit label</source> <translation>Ändra etikett</translation> </message> @@ -2790,12 +2929,52 @@ Var vänlig och försök igen.</translation> <translation>Tillåt kommandon från kommandotolken och JSON-RPC-kommandon</translation> </message> <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>Om <kategori> inte anges eller om <category> = 1, visa all avlusningsinformation.</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Maximal total avgift (i %s) att använda i en plånbokstransaktion. Sätts denna för lågtkan stora transaktioner komma att avbrytas (förvalt: %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Vänligen kontrollera att din dators datum och tid är korrekt! Om din klocka går fel kommer Bitcoin Core inte att fungera ordentligt.</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>Beskärning konfigurerad under miniminivån %d MiB. Vänligen använd ett högre värde.</translation> + </message> + <message> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation>Beskärning: sista plånbokssynkroniseringen ligger utanför beskuren data. Du måste använda -reindex (ladda ner hela blockkedjan igen eftersom noden beskurits)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Minska lagringsbehovet genom att beskära (ta bort) gamla block. Detta läge är inkompatibelt med -txindex och -rescan. Varning: Ändras denna inställning måste hela blockkedjan laddas ner igen. (förvalt: 0 = inaktivera beskärning av block, >%u = målstorlek i MiB att använda för blockfiler)</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>Omskanningar kan inte göras i beskuret läge. Du måste använda -reindex vilket kommer ladda ner hela blockkedjan igen.</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Fel: Ett kritiskt internt fel uppstod, se debug.log för detaljer</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Avgift (i %s/kB) att lägga till på transaktioner du skickar (förvalt: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Rensar blockstore...</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>Kör i bakgrunden som tjänst och acceptera kommandon</translation> </message> <message> - <source>Use the test network</source> - <translation>Använd testnätverket</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>Kunde inte starta HTTP-server. Se avlusningsloggen för detaljer.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2818,18 +2997,14 @@ Var vänlig och försök igen.</translation> <translation>Exekvera kommando när en plånbokstransaktion ändras (%s i cmd är ersatt av TxID)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Maximal total avgift att använda i en plånbokstransaktion. Sätts denna för lågt kommer stora transaktioner att avbrytas (förvalt: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Reducera lagringsbehovet genom att beskära (ta bort) gamla block. Detta läge avaktiverar plånbokssupport och är inkompatibel med -txindex. Varning: Ändras denna inställning måste hela blockkedjan laddas ner igen. 0 = avaktivera beskärning av blocks, >%u = målstorlek i MiB att använda för blockfiler)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <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>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>Blockdatabasen innehåller ett block som verkar vara från framtiden. Detta kan vara på grund av att din dators datum och tid är felaktiga. Bygg bara om blockdatabasen om du är säker på att datorns datum och tid är korrekt</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> @@ -2838,6 +3013,10 @@ Var vänlig och försök igen.</translation> <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 UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>Använd UPnP för att mappa den lyssnande porten (förvalt: 1 när lyssning aktiverat och utan -proxy)</translation> + </message> + <message> <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> <translation>Varning: Onormalt antal block block genererade. %d block mottagna senaste %d timmarna (%d förväntade)</translation> </message> @@ -2846,10 +3025,6 @@ Var vänlig och försök igen.</translation> <translation>Varning: Kontrollera din närverksanslutning. %d block mottagna senaste %d timmarna, (%d förväntade)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Varning: -paytxfee är satt väldigt hög! Detta är avgiften du kommer betala för varje transaktion.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Varning: Nätverket verkar inte vara helt överens! Några miners verkar ha problem.</translation> </message> @@ -2858,10 +3033,6 @@ Var vänlig och försök igen.</translation> <translation>Varning: Vi verkar inte helt överens med våra peers! Du kan behöva uppgradera, eller andra noder kan behöva uppgradera.</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>Varning: fel vid läsning av wallet.dat! Alla nycklar lästes korrekt, men transaktionsdatan eller adressbokens poster kanske saknas eller är felaktiga.</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>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> @@ -2870,18 +3041,14 @@ Var vänlig och försök igen.</translation> <translation>Vitlista klienter som ansluter från angivna nätmasker eller IP-adresser. Kan specificeras flera gånger.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(förvalt: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool måste vara minst %d MB</translation> </message> <message> <source><category> can be:</source> <translation><category> Kan vara:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Försök att rädda de privata nycklarna från en korrupt wallet.dat</translation> - </message> - <message> <source>Block creation options:</source> <translation>Block skapande inställningar:</translation> </message> @@ -2891,7 +3058,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Connection options:</source> - <translation>Anslutningsoptioner:</translation> + <translation>Anslutningsalternativ:</translation> </message> <message> <source>Corrupted block database detected</source> @@ -2899,7 +3066,7 @@ Var vänlig och försök igen.</translation> </message> <message> <source>Debugging/Testing options:</source> - <translation>Avlusnings/Testnings optioner:</translation> + <translation>Avlusnings/Test-alternativ:</translation> </message> <message> <source>Do not load the wallet and disable wallet RPC calls</source> @@ -2910,6 +3077,22 @@ Var vänlig och försök igen.</translation> <translation>Vill du bygga om blockdatabasen nu?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation>Aktivera publicering av hashblock i <adress></translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>Aktivera publicering av hashtransaktion i <adress></translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>Aktivera publicering av råa block i <adress></translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation>Aktivera publicering av råa transaktioner i <adress></translation> + </message> + <message> <source>Error initializing block database</source> <translation>Fel vid initiering av blockdatabasen</translation> </message> @@ -2926,10 +3109,6 @@ Var vänlig och försök igen.</translation> <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> @@ -2938,10 +3117,6 @@ Var vänlig och försök igen.</translation> <translation>Misslyckades att lyssna på någon port. Använd -listen=0 om du vill detta.</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> - <message> <source>Importing...</source> <translation>Importerar...</translation> </message> @@ -2954,6 +3129,10 @@ Var vänlig och försök igen.</translation> <translation>Ogiltig -onion adress:'%s'</translation> </message> <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>Håll minnespoolen över transaktioner under <n> megabyte (förvalt: %u)</translation> + </message> + <message> <source>Not enough file descriptors available.</source> <translation>Inte tillräckligt med filbeskrivningar tillgängliga.</translation> </message> @@ -2982,10 +3161,26 @@ Var vänlig och försök igen.</translation> <translation>Ange plånboksfil (inom datakatalogen)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Argumentet -benchmark stöds inte och ignoreras, använd -debug=bench.</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Argumentet -debugnet stöds inte och ignoreras, använd -debug=net.</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>Argumentet -tor hittades men stöds inte, använd -onion.</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>User Agent comment (%s) contains unsafe characters.</source> + <translation>Kommentaren i användaragent (%s) innehåller osäkra tecken.</translation> + </message> + <message> <source>Verifying blocks...</source> <translation>Verifierar block...</translation> </message> @@ -3010,16 +3205,8 @@ Var vänlig och försök igen.</translation> <translation>Du måste återskapa databasen med -reindex för att ändra -txindex</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Importerar block från extern blk000??.dat fil</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> - <message> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation>Ett fel uppstod vid upprättandet av RPC adress %s port %u för att lyssna: %s</translation> + <translation>Tillåt JSON-RPC-anslutningar från specifik källa. Tillåtna <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). Detta alternativ anges flera gånger</translation> </message> <message> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> @@ -3027,7 +3214,7 @@ Var vänlig och försök igen.</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>Bind till angiven adress för att lyssna på JSON-RPC anslutningar. Använd [värd]:port notation for IPv6. Denna option kan specificeras flera gånger (förvalt: bind till alla gränssnitt)</translation> + <translation>Bind till angiven adress för att lyssna på JSON-RPC-anslutningar. Använd [värd]:port-format for IPv6. Detta alternativ kan anges flera gånger (förvalt: bind till alla gränssnitt)</translation> </message> <message> <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source> @@ -3046,16 +3233,12 @@ Var vänlig och försök igen.</translation> <translation>Fel: Avlyssning av inkommande anslutningar misslyckades (Avlyssningen returnerade felkod %s)</translation> </message> <message> - <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> - <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 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> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Avgifter (i BTC/Kb) mindre än detta betraktas som nollavgift för vidarebefodran (förvalt: %s)</translation> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>Avgifter (i %s/kB) mindre än detta betraktas som nollavgift för vidarebefordran, mining och transaktionsskapande (förvalt: %s)</translation> </message> <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> @@ -3070,10 +3253,6 @@ Var vänlig och försök igen.</translation> <translation>Maximal storlek på data i databärartransaktioner som vi reläar och bryter (förvalt: %u) </translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>Beskärning konfigurerad under miniminivån %d MB. Var vänlig använd ett högre värde.</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Sök efter klientadresser med DNS sökningen, om det finns otillräckligt med adresser (förvalt: 1 om inte -connect)</translation> </message> @@ -3086,6 +3265,10 @@ Var vänlig och försök igen.</translation> <translation>Sätt den maximala storleken av hög-prioriterade/låg-avgifts transaktioner i byte (förvalt: %d)</translation> </message> <message> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <translation>Ange antalet trådar för myntgenerering om påslagen (-1= alla kärnor, förval: %d)</translation> + </message> + <message> <source>The transaction amount is too small to send after the fee has been deducted</source> <translation>Transaktionen är för liten att skicka efter det att avgiften har dragits</translation> </message> @@ -3094,40 +3277,8 @@ Var vänlig och försök igen.</translation> <translation>Denna produkten innehåller mjukvara utvecklad av OpenSSL Project för användning i OpenSSL Toolkit <https://www.openssl.org/> och kryptografisk mjukvara utvecklad av Eric Young samt UPnP-mjukvara skriven av Thomas Bernard.</translation> </message> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>För att använda bitconid,eller -server optionen till bitcoin-qt så mäste du sätta ett rpclösensord i konfigurationsfilen: -%s -Det är rekommenderat att använda följande slumpade lösenord: -rpcuser=bitcoinrpc -rpcpassword=%s -(du behöver inte komma ihåg lösenordet) -Användarnamnet och lösenordet FÅR INTE vara detsamma. -Om filen inte existerar, skapa den med enbart ägarläsbara filrättigheter. -Det är också rekommenderat att sätta alertnotify så du meddelas om problem; -till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Varning: -maxtxfee är satt väldigt hög! Så höga avgifter kan betalas för en enstaka transaktion.</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>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>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> + <translation>Vitlistade klienter kan inte bli DoS-bannade och deras transaktioner reläas alltid, även om dom redan är i mempoolen, användbart för t.ex en gateway </translation> </message> <message> <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> @@ -3146,16 +3297,20 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Aktiverar bästa kedjan...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>Kan inte köra med en plånbok i beskärningsläge.</translation> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>Vidarebefordra alltid transaktioner från vitlistade noder (förval: %d)</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>Kan inte matcha -whitebind adress: '%s'</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Försök att rädda privata nycklar från en korrupt wallet.dat vid uppstart</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Välj datakatalog vid uppstart (förvalt: 0)</translation> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Skapa automatiskt dold tjänst i Tor (förval: %d)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Kan inte matcha -whitebind adress: '%s'</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3166,10 +3321,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Copyright (C) 2009-%i Bitcoin Core Utvecklarna</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>Kunde inte tolka -rpcbind värdet %s som en nätverksadress</translation> - </message> - <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>Fel vid inläsningen av wallet.dat: Kontofilen kräver en senare version av Bitcoin Core</translation> </message> @@ -3178,12 +3329,8 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Fel vid läsning från databas, avslutar.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Fel: Argumentet -tor stöds inte, använd -onion.</translation> - </message> - <message> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation>Avgift (i BTC/Kb) att lägga till på transaktioner du skickar (förvalt: %s)</translation> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Importera block från extern blk000??.dat-fil vid uppstart</translation> </message> <message> <source>Information</source> @@ -3223,19 +3370,11 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Node relay options:</source> - <translation>Nodreläoptioner:</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> + <translation>Nodreläalternativ:</translation> </message> <message> <source>RPC server options:</source> - <translation>RPC serveroptioner:</translation> - </message> - <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>RPC support för HTTP permanent anslutning (förvalt: %d)</translation> + <translation>RPC-serveralternativ:</translation> </message> <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> @@ -3246,28 +3385,24 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Mottag och visa P2P nätverksvarningar (förvalt: %u)</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Skicka trace-/debuginformation till terminalen istället för till debug.log</translation> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> + <translation>Minskar -maxconnections från %d till %d, på grund av systembegränsningar.</translation> </message> <message> - <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> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Sök i blockkedjan efter saknade plånbokstransaktioner vid uppstart</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Sätt SSL root-certifikat för betalningsbegäran (förvalt: -system-)</translation> + <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 language, for example "de_DE" (default: system locale)</source> - <translation>Ändra språk, till exempel "de_DE" (förvalt: systemets språk)</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> - <translation>Visa alla avlusningsoptioner (använd: --help -help-debug)</translation> - </message> - <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Visa startbilden vid uppstart (förvalt: 1)</translation> + <translation>Visa alla avlusningsalternativ (använd: --help -help-debug)</translation> </message> <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> @@ -3278,10 +3413,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Signering av transaktion misslyckades</translation> </message> <message> - <source>Start minimized</source> - <translation>Starta som minimerad</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>Transaktionen är för liten för att betala avgiften</translation> </message> @@ -3290,6 +3421,14 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Detta är experimentmjukvara.</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>Lösenord för Tor-kontrollport (förval: inget)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>Tor-kontrollport att använda om onion är aktiverat (förval: %s)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Transaktions belopp för liten</translation> </message> @@ -3306,16 +3445,12 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Transaktionen är för stor</translation> </message> <message> - <source>UI Options:</source> - <translation>UI Alternativ:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Det går inte att binda till %s på den här datorn (bind returnerade felmeddelande %s)</translation> </message> <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> + <source>Upgrade wallet to latest format on startup</source> + <translation>Uppgradera plånbok till senaste formatet vid uppstart</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3330,20 +3465,16 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Varning</translation> </message> <message> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation>Varning: Argument -benchmark stöds inte och ignoreras, använd -debug=bench.</translation> - </message> - <message> - <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> - <translation>Varning: Argument -debugnet stöds inte och ignorerad, använd -debug=net.</translation> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>Ska allt göras i endast block-läge (förval: %u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> <translation>Töm plånboken på alla transaktioner...</translation> </message> <message> - <source>on startup</source> - <translation>under uppstarten</translation> + <source>ZeroMQ notification options:</source> + <translation>ZeroMQ-alternativ för notiser:</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3358,18 +3489,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Exekvera kommando när det bästa blocket ändras (%s i cmd är utbytt av blockhash)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Uppgradera plånboken till senaste formatet</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Använd OpenSSL (https) för JSON-RPC-anslutningar</translation> - </message> - <message> <source>This help message</source> <translation>Det här hjälp medelandet</translation> </message> @@ -3390,6 +3509,26 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = spara tx metadata t.ex. kontoägare och betalningsbegäransinformation, 2 = släng tx metadata)</translation> </message> <message> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>-maxtxfee är väldigt högt satt! Så höga avgifter kan komma att betalas för en enstaka transaktion.</translation> + </message> + <message> + <source>-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> + <translation>-paytxfee är väldigt högt satt! Det här är avgiften du kommer betala om du skickar en transaktion.</translation> + </message> + <message> + <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>Håll inte transaktioner i minnespoolen längre än <n> timmar (förvalt: %u)</translation> + </message> + <message> + <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> + <translation>Fel vid läsning av wallet.dat! Alla nycklar lästes korrekt, men transaktionsdata eller adressbokens poster kanske saknas eller är felaktiga.</translation> + </message> + <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>Avgifter (i %s/kB) mindre än detta anses vara nollavgifter vid skapande av transaktion (standard: %s)</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> @@ -3406,16 +3545,32 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Skriv ut avlusningsinformation (förvalt: %u, att ange <category> är frivilligt)</translation> </message> <message> + <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> + <translation>Stöd filtrering av block och transaktioner med bloomfilter (standard: %u)</translation> + </message> + <message> + <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> + <translation>Total längd på strängen för nätverksversion (%i) överskrider maxlängden (%i). Minska numret eller storleken på uacomments.</translation> + </message> + <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>Försöker hålla utgående trafik under givet mål (i MiB per 24 timmar), 0 = ingen gräns (förvalt: %d)</translation> + </message> + <message> + <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>Argumentet -socks hittades och stöds inte. Det är inte längre möjligt att sätta SOCKS-version längre, bara SOCKS5-proxy stöds.</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> + <source>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source> + <translation>Användarnamn och hashat lösenord för JSON-RPC-anslutningar. Fältet <userpw> kommer i formatet: <USERNAME>:<SALT>$<HASH>. Ett kanoniskt pythonskript finns inkluderat i share/rpcuser. Detta alternativ kan anges flera gånger</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Accepterbara chiffer (förvalt: %s)</translation> + <source>(default: %s)</source> + <translation>(förvalt: %s)</translation> </message> <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> @@ -3475,15 +3630,7 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com </message> <message> <source>Relay non-P2SH multisig (default: %u)</source> - <translation>Reläa icke P2SH multisig (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> + <translation>Reläa icke-P2SH multisig (förvalt: %u)</translation> </message> <message> <source>Set key pool size to <n> (default: %u)</source> diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts index 0980502968..79a55cdd51 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.0"> +<TS language="th_TH" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -105,6 +105,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Synchronizing with network...</source> @@ -279,6 +282,10 @@ </context> <context> <name>ReceiveCoinsDialog</name> + <message> + <source>&Label:</source> + <translation>&ชื่อ:</translation> + </message> </context> <context> <name>ReceiveRequestDialog</name> @@ -315,6 +322,10 @@ </context> <context> <name>SendCoinsEntry</name> + <message> + <source>&Label:</source> + <translation>&ชื่อ:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -382,5 +393,9 @@ </context> <context> <name>bitcoin-core</name> + <message> + <source>Options:</source> + <translation>ตัวเลือก:</translation> + </message> </context> </TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index dcc82e644d..96fca8bb24 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -1,4 +1,4 @@ -<TS language="tr" version="2.0"> +<TS language="tr" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/Ağ maskesi</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Şu vakte kadar yasaklı:</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -871,6 +882,34 @@ <source>command-line options</source> <translation>komut satırı seçenekleri</translation> </message> + <message> + <source>UI Options:</source> + <translation>Arayüz Seçenekleri:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Başlangıçta veri klasörü seç (varsayılan: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Lisan belirt, mesela "de_De" (varsayılan: sistem dili)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Küçültülmüş olarak başlat</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Ödeme talebi için SSL kök sertifikalarını belirle (varsayılan: -system-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Başlatıldığında başlangıç ekranını göster (varsayılan: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Arayüzde yapılan tüm seçenek değişikliklerini sıfırla</translation> + </message> </context> <context> <name>Intro</name> @@ -1069,6 +1108,34 @@ <translation>Vekil sunucunun portu (mesela 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Eşlere ulaşmak için kullanılır, şu yoluyla:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Bu şebeke türü yoluyla eşlere bağlanmak için belirtilen varsayılan SOCKS5 vekil sunucusunun kullanılıp kullanılmadığını gösterir.</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Bitcoin şebekesine gizli Tor servisleri için ayrı bir SOCKS5 vekil sunucusu vasıtasıyla bağlan.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Eşlere gizli Tor servisleri ile ulaşmak için ayrı SOCKS5 vekil sunucusu kullan:</translation> + </message> + <message> <source>&Window</source> <translation>&Pencere</translation> </message> @@ -1287,10 +1354,6 @@ <translation>%1 ödeme talebi çok büyük (%2 bayt, müsaade edilen %3 bayt).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Ödeme talebi DoS koruması</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>%1 ile iletişimde hata: %2</translation> </message> @@ -1443,6 +1506,18 @@ <translation>Güncel blok sayısı</translation> </message> <message> + <source>Memory Pool</source> + <translation>Bellek Alanı</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>Güncel muamele sayısı</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Bellek kullanımı</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>Güncel veri klasöründen Bitcoin Çekirdeği hata ayıklama kütük dosyasını açar. Büyük kütük dosyaları için bu birkaç saniye alabilir.</translation> </message> @@ -1459,10 +1534,18 @@ <translation>&Eşler</translation> </message> <message> + <source>Banned peers</source> + <translation>Yasaklı eşler</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Ayrıntılı bilgi görmek için bir eş seçin.</translation> </message> <message> + <source>Whitelisted</source> + <translation>Beyaz listedekiler</translation> + </message> + <message> <source>Direction</source> <translation>Yön</translation> </message> @@ -1471,20 +1554,24 @@ <translation>Sürüm</translation> </message> <message> - <source>User Agent</source> - <translation>Kullanıcı Yazılımı</translation> + <source>Starting Block</source> + <translation>Başlangıç Bloku</translation> </message> <message> - <source>Services</source> - <translation>Servisler</translation> + <source>Synced Headers</source> + <translation>Eşleşmiş Başlıklar</translation> </message> <message> - <source>Starting Height</source> - <translation>Başlama Yüksekliği</translation> + <source>Synced Blocks</source> + <translation>Eşleşmiş Bloklar</translation> + </message> + <message> + <source>User Agent</source> + <translation>Kullanıcı Yazılımı</translation> </message> <message> - <source>Sync Height</source> - <translation>Eşleşme Yüksekliği</translation> + <source>Services</source> + <translation>Servisler</translation> </message> <message> <source>Ban Score</source> @@ -1503,16 +1590,16 @@ <translation>Son Alma</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Yollanan Baytlar</translation> + <source>Ping Time</source> + <translation>Ping Süresi</translation> </message> <message> - <source>Bytes Received</source> - <translation>Alınan Baytlar</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>Güncel olarak göze çarpan bir ping'in süresi.</translation> </message> <message> - <source>Ping Time</source> - <translation>Ping Süresi</translation> + <source>Ping Wait</source> + <translation>Ping Beklemesi</translation> </message> <message> <source>Time Offset</source> @@ -1563,6 +1650,34 @@ <translation>Konsolu temizle</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>Düğümle Bağlantıyı &Kes</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Düğümü şu süre için yasakla:</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &saat</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &gün</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &hafta</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &yıl</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>Düğümün Yasağını Kald&ır</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Bitcoin Çekirdeği RPC konsoluna hoş geldiniz.</translation> </message> @@ -1591,6 +1706,10 @@ <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(düğüm kimliği: %1)</translation> + </message> + <message> <source>via %1</source> <translation>%1 vasıtasıyla</translation> </message> @@ -1607,12 +1726,16 @@ <translation>Giden</translation> </message> <message> - <source>Unknown</source> - <translation>Bilinmiyor</translation> + <source>Yes</source> + <translation>Evet</translation> </message> <message> - <source>Fetching...</source> - <translation>Alınıyor...</translation> + <source>No</source> + <translation>Hayır</translation> + </message> + <message> + <source>Unknown</source> + <translation>Bilinmiyor</translation> </message> </context> <context> @@ -1979,8 +2102,8 @@ <translation>Para üstünü kopyala</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Toplam meblağ %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Toplam Meblağ %1</translation> </message> <message> <source>or</source> @@ -2015,8 +2138,12 @@ <translation>Ödeme talebinin ömrü doldu.</translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Sadece asgari ücret olan %1 tutarını öde</translation> + <source>Pay only the required fee of %1</source> + <translation>Sadece gerekli ücret olan %1 tutarını öde</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>Tahmini olarak %n blok içinde teyide başlanacaktır.</numerusform><numerusform>Tahmini olarak %n blok içinde teyide başlanacaktır.</numerusform></translation> </message> <message> <source>The recipient address is not valid. Please recheck.</source> @@ -2650,6 +2777,10 @@ <translation>Muamele kimliğini kopyala</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>Ham muameleyi kopyala</translation> + </message> + <message> <source>Edit label</source> <translation>Etiketi düzenle</translation> </message> @@ -2797,12 +2928,52 @@ <translation>Komut satırı ve JSON-RPC komutlarını kabul et</translation> </message> <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>Eğer <kategori> belirtilmemişse ya da <kategori> = 1 ise, tüm hata ayıklama verilerini dök.</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Tek cüzdan muamelesinde kullanılacak azami toplam ücret (%s olarak); bunu çok düşük olarak ayarlamak büyük muameleleri iptal edebilir (varsayılan: %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>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>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>Prune, asgari değer olan %d MiB'den düşük olarak ayarlanmıştır. Lütfen daha yüksek bir sayı kullanınız.</translation> + </message> + <message> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation>Budama: son cüzdan eşleşmesi budanmış verilerin ötesine gitmektedir. -reindex kullanmanız gerekmektedir (Budanmış düğüm ise tüm blok zincirini tekrar indirmeniz gerekir.)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Depolama gerekliliğini eski blokları budayarak (silerek) düşür. Bu kip -txindex ve -rescan ile uyumsuzdur. İkaz: Bu ayarı geri almak tüm blok zincirini yeniden indirmeyi gerektirir. (varsayılan: 0 = blokları silmeyi devre dışı bırak, >%u = MiB olarak blok dosyaları için kullanılacak hedef boyut)</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>Tekrar taramalar budanmış kipte mümkün değildir. Tüm blok zincirini tekrar indirecek olan -reindex seçeneğini kullanmanız gerekecektir.</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, 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>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Yolladığınız muamelelere eklenecek ücret (%s/kB olarak) (varsayılan: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Blockstore budanıyor...</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>Arka planda daemon (servis) olarak çalış ve komutları kabul et</translation> </message> <message> - <source>Use the test network</source> - <translation>Deneme şebekesini kullan</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>HTTP sunucusu başlatılamadı. Ayrıntılar için debug.log dosyasına bakınız.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2825,18 +2996,14 @@ <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>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Tek cüzdan muamelesinde kullanılacak azami toplam ücret; bunu çok düşük olarak ayarlamak büyük muameleleri iptal edebilir (varsayılan: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Depolama gerekliliğini eski blokları silerek düşür. Bu kip cüzdan desteğini devre dışı bırakır ve -txindex ile uyumsuzdur. İkaz: Bu ayarı geri almak tüm blok zincirini yeniden indirmeyi gerektirir. (varsayılan: 0 = blokları silmeyi devre dışı bırak, >%u = MB olarak blok dosyaları için kullanılacak hedef boyut)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <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>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>Blok veritabanı gelecekten gibi görünen bir blok içermektedir. Bu, bilgisayarınızın saat ve tarihinin yanlış ayarlanmış olmasından kaynaklanabilir. Blok veritabanını sadece bilgisayarınızın tarih ve saatinin doğru olduğundan eminseniz yeniden derleyin.</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> @@ -2845,6 +3012,10 @@ <translation>Bu bilgisayarda %s unsuruna bağlanılamadı. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır.</translation> </message> <message> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>Dinlenecek portu haritalamak için UPnP kullan (varsayılan: dinlenildiğinde ve -proxy olmadığında 1)</translation> + </message> + <message> <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> <translation>İKAZ: anormal yüksek sayıda blok oluşturulmuştur, %d blok son %d saat içinde alınmıştır (%d bekleniyordu)</translation> </message> @@ -2853,10 +3024,6 @@ <translation>İKAZ: ağ bağlantınızı kontrol ediniz, %d blok son %d saat içinde alınmıştır (%d bekleniyordu)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Uyarı: -paytxfee çok yüksek bir değere ayarlanmış! Bu, muamele gönderirseniz ödeyeceğiniz muamele ücretidir.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Uyarı: şebeke tamamen mutabık değil gibi görünüyor! Bazı madenciler sorun yaşıyor gibi görünüyor.</translation> </message> @@ -2865,10 +3032,6 @@ <translation>Uyarı: eşlerimizle tamamen mutabık değiliz gibi görünüyor! Güncelleme yapmanız gerekebilir ya da diğer düğümlerin güncelleme yapmaları gerekebilir.</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>Uyarı: wallet.dat dosyasının okunması sırasında bir hata meydana geldi! Tüm anahtarlar doğru bir şekilde okundu, ancak muamele verileri ya da adres defteri unsurları hatalı veya eksik olabilir.</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>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> @@ -2877,18 +3040,14 @@ <translation>Belirtilen ağ maskesi ya da IP adresinden bağlanan eşleri beyaz listeye al. Birden fazla kez belirtilebilir.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(varsayılan: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool asgari %d MB olmalıdır</translation> </message> <message> <source><category> can be:</source> <translation><kategori> şunlar olabilir:</translation> </message> <message> - <source>Attempt to recover private keys from a corrupt wallet.dat</source> - <translation>Bozuk bir wallet.dat dosyasından özel anahtarları geri kazanmayı dene</translation> - </message> - <message> <source>Block creation options:</source> <translation>Blok oluşturma seçenekleri:</translation> </message> @@ -2917,6 +3076,22 @@ <translation>Blok veritabanını şimdi yeniden inşa etmek istiyor musunuz?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation>Blok karma değerinin <adres>te yayınlanmasını etkinleştir</translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>Karma değer muamelesinin <adres>te yayınlanmasını etkinleştir</translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>Ham blokun <adres>te yayınlanmasını etkinleştir</translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation>Ham muamelenin <adres>te yayınlanmasını etkinleştir</translation> + </message> + <message> <source>Error initializing block database</source> <translation>Blok veritabanını başlatılırken bir hata meydana geldi</translation> </message> @@ -2933,10 +3108,6 @@ <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> @@ -2945,10 +3116,6 @@ <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>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> - <message> <source>Importing...</source> <translation>İçe aktarılıyor...</translation> </message> @@ -2961,6 +3128,10 @@ <translation>Geçersiz -onion adresi: '%s'</translation> </message> <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>Muamele bellek alanını <n> megabayttan düşük tut (varsayılan: %u)</translation> + </message> + <message> <source>Not enough file descriptors available.</source> <translation>Kafi derecede dosya tanımlayıcıları mevcut değil.</translation> </message> @@ -2989,10 +3160,26 @@ <translation>Cüzdan dosyası belirtiniz (veri klasörünün içinde)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Desteklenmeyen -benchmark argümanı görmezden gelindi, -debug=bench kullanınız.</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Desteklenmeyen -debugnet argümanı görmezden gelindi, debug=net kullanınız.</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>Deskteklenmeyen -tor argümanı bulundu, -onion kullanınız.</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>User Agent comment (%s) contains unsafe characters.</source> + <translation>Kullanıcı Aracı açıklaması (%s) güvensiz karakterler içermektedir.</translation> + </message> + <message> <source>Verifying blocks...</source> <translation>Bloklar kontrol ediliyor...</translation> </message> @@ -3017,18 +3204,10 @@ <translation>-txindex'i değiştirmek için veritabanını -reindex kullanarak tekrar inşa etmeniz gerekmektedir</translation> </message> <message> - <source>Imports blocks from external blk000??.dat file</source> - <translation>Harici blk000??.dat dosyasından blokları içe aktarır</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> <message> - <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source> - <translation>Dinleme için RPC adresi %s port %u kurulurken bir hata meydana geldi: %s</translation> - </message> - <message> <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source> <translation>Belirtilen adrese bağlan ve ona bağlanan eşleri beyaz listeye al. IPv6 için [makine]:port imlasını kullanınız</translation> </message> @@ -3053,16 +3232,12 @@ <translation>Hata: İçeri gelen bağlantıların dinlenmesi başarısız oldu (dinleme %s hatasını verdi)</translation> </message> <message> - <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> - <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 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> <message> - <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source> - <translation>Kb başına BTC olarak bundan düşük ücretler aktarım için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</translation> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>Bundan düşük ücretler (%s/kB olarak) aktarma, oluşturma ve muamele yaratma için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</translation> </message> <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> @@ -3077,10 +3252,6 @@ <translation>Aktardığımız ve oluşturduğumuz veri taşıyıcı muamelelerindeki azami veri boyutu (varsayılan: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>Prune, asgari değer olan %d MB'den düşük olarak ayarlanmıştır. Lütfen daha yüksek bir sayı kullanınız.</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Adres sayısı azaldıysa DNS sorgulamasıyla eş adresleri ara (varsayılan: 1 -connect kullanılmadıysa)</translation> </message> @@ -3105,38 +3276,6 @@ <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> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>bitcoind ya da bitcoin-qt ile -server seçeneğini kullanmak için yapılandırma dosyasında bir rpc parolası belirtmeniz gerekir: -%s -Aşağıdaki rastgele oluşturulan parolayı kullanmanız tavsiye edilir: -rpcuser=bitcoinrpc -rpcpassword=%s -(bu parolayı hatırlamanız gerekli değildir) -Kullanıcı ismi ile parolanın FARKLI olmaları gerekir. -Dosya mevcut değilse, sadece sahibi için okumayla sınırlı izin ile oluşturunuz. -Sorunlar hakkında bildiri almak için alertnotify unsurunu ayarlamanız tavsiye edilir; -mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>İkaz: -maxtxfee çok yüksek bir değere ayarlanmış! Bu denli yüksek ücretler tek bir muamelede ödenebilir.</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>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>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> @@ -3157,16 +3296,20 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>En iyi zincir etkinleştiriliyor...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>Prune kipindeki bir cüzdan ile çalışamaz.</translation> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>Beyaz listedeki eşlerden gelen muameleleri daima aktar (varsayılan: %d)</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>-whitebind adresi çözümlenemedi: '%s'</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Başlangıçta bozuk bir wallet.dat dosyasından özel anahtarları geri kazanmayı dene</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Başlangıçta veri klasörü seç (varsayılan: 0)</translation> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Otomatik olarak gizli Tor servisi oluştur (varsayılan: %d)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>-whitebind adresi çözümlenemedi: '%s'</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3177,10 +3320,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Telif hakkı 2009-%i Bitcoin Çekirdeği Geliştiricileri</translation> </message> <message> - <source>Could not parse -rpcbind value %s as network address</source> - <translation>-rpcbind değeri %s şebeke adresi olarak ayrıştırılamadı</translation> - </message> - <message> <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source> <translation>wallet.dat dosyasının yüklenmesinde hata: Cüzdan Bitcoin Çekirdeğinin daha yeni bir sürümünü gerektirmektedir</translation> </message> @@ -3189,12 +3328,8 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Veritabanından okumada hata, kapatılıyor.</translation> </message> <message> - <source>Error: Unsupported argument -tor found, use -onion.</source> - <translation>Hata: Deskteklenmeyen -tor argümanı bulundu, -onion kullanınız.</translation> - </message> - <message> - <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source> - <translation>Yolladığınız muamelelere kB başına BTC olarak eklenecek ücret (varsayılan: %s)</translation> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Başlangıçta harici blk000??.dat dosyasından blokları içe aktarır</translation> </message> <message> <source>Information</source> @@ -3237,18 +3372,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Düğüm röle seçenekleri:</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> - <message> <source>RPC server options:</source> <translation>RPC sunucu seçenekleri:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>Kalıcı HTTP bağlantıları için RPC desteği (varsayılan: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>Başlangıçta blok zinciri indeksini güncel blk000??.dat dosyalarından tekrar inşa et</translation> </message> @@ -3257,30 +3384,26 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>P2P ağından gelen önemli uyarıları alın ve gösterin (önseçili değer: %u)</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Trace/hata ayıklama verilerini debug.log dosyası yerine konsola gönder</translation> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> + <translation>Sistem sınırlamaları sebebiyle -maxconnections %d değerinden %d değerine düşürülmüştür.</translation> </message> <message> - <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> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Başlangıçta blok zincirini eksik cüzdan muameleleri için tekrar tara</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Ödeme talebi için SSL kök sertifikalarını belirle (varsayılan: -system-)</translation> + <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 language, for example "de_DE" (default: system locale)</source> - <translation>Lisan belirt, mesela "de_De" (varsayılan: sistem dili)</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> <translation>Tüm hata ayıklama seçeneklerini göster (kullanımı: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Başlatıldığında başlangıç ekranını göster (varsayılan: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>İstemci başlatıldığında debug.log dosyasını küçült (varsayılan: -debug bulunmadığında 1)</translation> </message> @@ -3289,10 +3412,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Muamelenin imzalanması başarısız oldu</translation> </message> <message> - <source>Start minimized</source> - <translation>Küçültülmüş olarak başlat</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>Muamele meblağı ücreti ödemek için çok düşük</translation> </message> @@ -3301,6 +3420,14 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Bu, deneysel bir yazılımdır.</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>Tor kontrol portu parolası (varsayılan: boş)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>Eğer onion dinlenmesi etkinse kullanılacak Tor kontrol portu (varsayılan: %s)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Muamele meblağı çok düşük</translation> </message> @@ -3317,16 +3444,12 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Muamele çok büyük</translation> </message> <message> - <source>UI Options:</source> - <translation>Arayüz Seçenkleri:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Bu bilgisayarda %s unsuruna bağlanılamadı (bağlanma %s hatasını verdi)</translation> </message> <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> + <source>Upgrade wallet to latest format on startup</source> + <translation>Başlangıçta cüzdanı en yeni biçime güncelle</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3341,20 +3464,16 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Uyarı</translation> </message> <message> - <source>Warning: Unsupported argument -benchmark ignored, use -debug=bench.</source> - <translation>Uyarı: Deskteklenmeyen -benchmark argümanı görmezden gelindi, -debug=bench kullanınız.</translation> - </message> - <message> - <source>Warning: Unsupported argument -debugnet ignored, use -debug=net.</source> - <translation>Uyarı: Desteklenmeyen -debugnet argümanı görmezden gelindi, debug=net kullanınız.</translation> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>Salt blok kipinde çalışılıp çalışılmayacağı (varsayılan: %u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> <translation>Cüzdandaki tüm muameleler kaldırılıyor...</translation> </message> <message> - <source>on startup</source> - <translation>başlangıçta</translation> + <source>ZeroMQ notification options:</source> + <translation>ZeroMQ bildirim seçenekleri:</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3369,18 +3488,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>En iyi blok değiştiğinde komutu çalıştır (komut için %s parametresi blok hash değeri ile değiştirilecektir)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Cüzdanı en yeni biçime güncelle</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> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>JSON-RPC bağlantıları için OpenSSL (https) kullan</translation> - </message> - <message> <source>This help message</source> <translation>Bu yardım mesajı</translation> </message> @@ -3401,6 +3508,26 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>(1 = tx meta verilerini tut mesela hesap sahibi ve ödeme talebi bilgileri, 2 = tx meta verilerini at)</translation> </message> <message> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>-maxtxfee çok yüksek bir değere ayarlanmış! Bu denli yüksek ücretler tek bir muamelede ödenebilir.</translation> + </message> + <message> + <source>-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> + <translation>-paytxfee çok yüksek bir değere ayarlanmış! Bu, muamele gönderirseniz ödeyeceğiniz muamele ücretidir.</translation> + </message> + <message> + <source>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>Muameleleri bellek alanında <n> saatten fazla tutma (varsayılan: %u)</translation> + </message> + <message> + <source>Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> + <translation>wallet.dat dosyasının okunması sırasında bir hata meydana geldi! Tüm anahtarlar doğru bir şekilde okundu, ancak muamele verileri ya da adres defteri unsurları hatalı veya eksik olabilir.</translation> + </message> + <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>Bundan düşük ücretler (%s/kB olarak) muamele oluşturulması için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</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> @@ -3417,16 +3544,32 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>Hata ayıklama bilgisi dök (varsayılan: %u, <kategori> sağlanması seçime dayalıdır)</translation> </message> <message> + <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> + <translation>Blokların ve muamelelerin bloom filtreleri ile süzülmesini destekle (varsayılan: %u)</translation> + </message> + <message> + <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> + <translation>Şebeke sürümü zincirinin toplam boyutu (%i) azami boyutu geçmektedir (%i). Kullanıcı aracı açıklamasının sayısı veya boyutunu azaltınız.</translation> + </message> + <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>Giden trafiği belirtilen hedefin altında tutmaya çalışır (24 saat başı MiB olarak), 0 = sınırsız (varsayılan: %d)</translation> + </message> + <message> + <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>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>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> + <source>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source> + <translation>JSON-RPC bağlantıları için kullanıcı ismi ve karmalanmış parola. <userpw> alanı şu biçimdedir: <USERNAME>:<SALT>$<HASH>. Kanonik bir Python betiği share/rpcuser klasöründe bulunabilir. Bu seçenek birden çok kez belirtilebilir.</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Kabul edilebilir şifreler (varsayılan: %s)</translation> + <source>(default: %s)</source> + <translation>(varsayılan: %s)</translation> </message> <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> @@ -3489,14 +3632,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com <translation>P2SH olmayan çoklu imzaları aktar (varsayılan: %u)</translation> </message> <message> - <source>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> diff --git a/src/qt/locale/bitcoin_tr_TR.ts b/src/qt/locale/bitcoin_tr_TR.ts new file mode 100644 index 0000000000..10866b011b --- /dev/null +++ b/src/qt/locale/bitcoin_tr_TR.ts @@ -0,0 +1,281 @@ +<TS language="tr_TR" version="2.1"> +<context> + <name>AddressBookPage</name> + <message> + <source>Right-click to edit address or label</source> + <translation>Adresi veya etiketi düzenlemek için sağ tıklayın</translation> + </message> + <message> + <source>Create a new address</source> + <translation>Yeni adres oluştur</translation> + </message> + <message> + <source>&New</source> + <translation>&Yeni</translation> + </message> + <message> + <source>Copy the currently selected address to the system clipboard</source> + <translation>Seçili adresi panoya kopyala</translation> + </message> + <message> + <source>&Copy</source> + <translation>&Kopyala</translation> + </message> + <message> + <source>C&lose</source> + <translation>K&apat</translation> + </message> + <message> + <source>&Copy Address</source> + <translation>&Adresi Kopyala</translation> + </message> + <message> + <source>Delete the currently selected address from the list</source> + <translation>Seçili adresi listeden sil</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Seçili sekmedeki veriyi dosya olarak dışa aktar</translation> + </message> + <message> + <source>&Export</source> + <translation>&Dışa Aktar</translation> + </message> + <message> + <source>&Delete</source> + <translation>&Sil</translation> + </message> + <message> + <source>Choose the address to send coins to</source> + <translation>Para göndereceğiniz adresi seçin</translation> + </message> + <message> + <source>Choose the address to receive coins with</source> + <translation>Parayı alacağınız adresi seçin</translation> + </message> + <message> + <source>C&hoose</source> + <translation>S&eç</translation> + </message> + <message> + <source>Sending addresses</source> + <translation>Gönderim adresleri</translation> + </message> + <message> + <source>Receiving addresses</source> + <translation>Alış adresleri</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>Bunlar ödeme gönderebileceğiniz Bitcoin adreslerinizdir. Para göndermeden önce mutlaka alıcı adresini ve tutarı kontrol edin.</translation> + </message> + <message> + <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source> + <translation>Bunlar ödeme alabileceğiniz Bitcoin adreslerinizdir. Her işlem için yeni bir adres kullanmanız önerilir.</translation> + </message> + <message> + <source>Copy &Label</source> + <translation>Kopyala &Etiketle</translation> + </message> + <message> + <source>&Edit</source> + <translation>&Düzenle</translation> + </message> + <message> + <source>Export Address List</source> + <translation>Adres Listesini Dışa Aktar</translation> + </message> + <message> + <source>Exporting Failed</source> + <translation>Dışa Aktarma Başarısız Oldu</translation> + </message> + <message> + <source>There was an error trying to save the address list to %1. Please try again.</source> + <translation>Adres listesini %1'e kaydederken bir hata oluştu. Lütfen tekrar deneyin.</translation> + </message> +</context> +<context> + <name>AddressTableModel</name> + <message> + <source>Label</source> + <translation>Etiket</translation> + </message> + <message> + <source>Address</source> + <translation>Adres</translation> + </message> + <message> + <source>(no label)</source> + <translation>(etiket yok)</translation> + </message> +</context> +<context> + <name>AskPassphraseDialog</name> + </context> +<context> + <name>BanTableModel</name> + </context> +<context> + <name>BitcoinGUI</name> + <message> + <source>&Receiving addresses...</source> + <translation>Alış adresleri</translation> + </message> + </context> +<context> + <name>ClientModel</name> + </context> +<context> + <name>CoinControlDialog</name> + <message> + <source>(no label)</source> + <translation>(etiket yok)</translation> + </message> + </context> +<context> + <name>EditAddressDialog</name> + <message> + <source>&Label</source> + <translation>Etiket</translation> + </message> + <message> + <source>&Address</source> + <translation>Adres</translation> + </message> + </context> +<context> + <name>FreespaceChecker</name> + </context> +<context> + <name>HelpMessageDialog</name> + </context> +<context> + <name>Intro</name> + </context> +<context> + <name>OpenURIDialog</name> + </context> +<context> + <name>OptionsDialog</name> + </context> +<context> + <name>OverviewPage</name> + </context> +<context> + <name>PaymentServer</name> + </context> +<context> + <name>PeerTableModel</name> + </context> +<context> + <name>QObject</name> + </context> +<context> + <name>QRImageWidget</name> + </context> +<context> + <name>RPCConsole</name> + </context> +<context> + <name>ReceiveCoinsDialog</name> + </context> +<context> + <name>ReceiveRequestDialog</name> + <message> + <source>Copy &Address</source> + <translation>&Adresi Kopyala</translation> + </message> + <message> + <source>Address</source> + <translation>Adres</translation> + </message> + <message> + <source>Label</source> + <translation>Etiket</translation> + </message> + </context> +<context> + <name>RecentRequestsTableModel</name> + <message> + <source>Label</source> + <translation>Etiket</translation> + </message> + <message> + <source>(no label)</source> + <translation>(etiket yok)</translation> + </message> + </context> +<context> + <name>SendCoinsDialog</name> + <message> + <source>(no label)</source> + <translation>(etiket yok)</translation> + </message> + </context> +<context> + <name>SendCoinsEntry</name> + </context> +<context> + <name>ShutdownWindow</name> + </context> +<context> + <name>SignVerifyMessageDialog</name> + </context> +<context> + <name>SplashScreen</name> + </context> +<context> + <name>TrafficGraphWidget</name> + </context> +<context> + <name>TransactionDesc</name> + </context> +<context> + <name>TransactionDescDialog</name> + </context> +<context> + <name>TransactionTableModel</name> + <message> + <source>Label</source> + <translation>Etiket</translation> + </message> + </context> +<context> + <name>TransactionView</name> + <message> + <source>Exporting Failed</source> + <translation>Dışa Aktarma Başarısız Oldu</translation> + </message> + <message> + <source>Label</source> + <translation>Etiket</translation> + </message> + <message> + <source>Address</source> + <translation>Adres</translation> + </message> + </context> +<context> + <name>UnitDisplayStatusBarControl</name> + </context> +<context> + <name>WalletFrame</name> + </context> +<context> + <name>WalletModel</name> + </context> +<context> + <name>WalletView</name> + <message> + <source>&Export</source> + <translation>&Dışa Aktar</translation> + </message> + <message> + <source>Export the data in the current tab to a file</source> + <translation>Seçili sekmedeki veriyi dosya olarak dışa aktar</translation> + </message> + </context> +<context> + <name>bitcoin-core</name> + </context> +</TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index 21ab4ac191..ea783aa856 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -1,4 +1,4 @@ -<TS language="uk" version="2.0"> +<TS language="uk" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/Маска підмережі</translation> + </message> + <message> + <source>Banned Until</source> + <translation>Заблоковано До</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -871,6 +882,34 @@ <source>command-line options</source> <translation>параметри командного рядка</translation> </message> + <message> + <source>UI Options:</source> + <translation>Параметри інтерфейсу:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>Обирати каталог даних під час запуску (типово: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>Встановити мову (наприклад: "de_DE") (типово: системна)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>Запускати згорнутим</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>Вказати кореневі SSL-сертифікати для запиту платежу (типово: -системні-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>Показувати заставку під час запуску (типово: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>Скинути налаштування, які було змінено через графічний інтерфейс користувача</translation> + </message> </context> <context> <name>Intro</name> @@ -1069,6 +1108,34 @@ <translation>Порт проксі-сервера (наприклад 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>Приєднуватися до учасників через:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>Вказує на використання наявного типового проксі SOCKS5, що використувується задля встановлення зв'язку з пірами через мережу такого типу.</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>Підключатися до мережі Bitcoin через окремий SOCKS5 проксі для прихованих сервісів Tor.</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>Використовувати окремий SOCKS5-проксі для з'єднання з учасниками через приховані сервіси Tor:</translation> + </message> + <message> <source>&Window</source> <translation>&Вікно</translation> </message> @@ -1287,10 +1354,6 @@ <translation>Запит платежу %1 занадто великий (%2 байт, дозволено %3 байт).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>Оплата потребує захисту DoS</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>Помилка зв'язку з %1: %2</translation> </message> @@ -1443,6 +1506,18 @@ <translation>Поточне число блоків</translation> </message> <message> + <source>Memory Pool</source> + <translation>Пул пам'яті</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>Поточне число транзакцій</translation> + </message> + <message> + <source>Memory usage</source> + <translation>Використання пам'яті</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>Відкрити файл журналу налагодження Bitcoin Core з поточного каталогу даних. Це може зайняти кілька секунд для великих файлів журналів.</translation> </message> @@ -1459,10 +1534,18 @@ <translation>&Учасники</translation> </message> <message> + <source>Banned peers</source> + <translation>Заблоковані вузли</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>Виберіть учасника для перегляду детальнішої інформації</translation> </message> <message> + <source>Whitelisted</source> + <translation>В білому списку</translation> + </message> + <message> <source>Direction</source> <translation>Напрямок</translation> </message> @@ -1471,20 +1554,24 @@ <translation>Версія</translation> </message> <message> - <source>User Agent</source> - <translation>Клієнт користувача</translation> + <source>Starting Block</source> + <translation>Початковий Блок</translation> </message> <message> - <source>Services</source> - <translation>Сервіси</translation> + <source>Synced Headers</source> + <translation>Синхронізовані Заголовки</translation> </message> <message> - <source>Starting Height</source> - <translation>Початкова висота</translation> + <source>Synced Blocks</source> + <translation>Синхронізовані Блоки</translation> </message> <message> - <source>Sync Height</source> - <translation>Висота синхронізації</translation> + <source>User Agent</source> + <translation>Клієнт користувача</translation> + </message> + <message> + <source>Services</source> + <translation>Сервіси</translation> </message> <message> <source>Ban Score</source> @@ -1503,16 +1590,16 @@ <translation>Востаннє отримано</translation> </message> <message> - <source>Bytes Sent</source> - <translation>Байтів відправлено</translation> + <source>Ping Time</source> + <translation>Затримка</translation> </message> <message> - <source>Bytes Received</source> - <translation>Байтів отримано</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>Тривалість поточної затримки.</translation> </message> <message> - <source>Ping Time</source> - <translation>Затримка</translation> + <source>Ping Wait</source> + <translation>Поточна Затримка</translation> </message> <message> <source>Time Offset</source> @@ -1563,6 +1650,34 @@ <translation>Очистити консоль</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>&Від'єднати Вузол</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>Заблокувати Вузол на</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 &годину</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 &день</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 &тиждень</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 &рік</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>&Розблокувати Вузол</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>Вітаємо у RPC-консолі Bitcoin Core.</translation> </message> @@ -1591,6 +1706,10 @@ <translation>%1 ГБ</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(ІД вузла: %1)</translation> + </message> + <message> <source>via %1</source> <translation>через %1</translation> </message> @@ -1607,12 +1726,16 @@ <translation>Вихідний</translation> </message> <message> - <source>Unknown</source> - <translation>Невідома</translation> + <source>Yes</source> + <translation>Так</translation> </message> <message> - <source>Fetching...</source> - <translation>Отримання...</translation> + <source>No</source> + <translation>Ні</translation> + </message> + <message> + <source>Unknown</source> + <translation>Невідома</translation> </message> </context> <context> @@ -1979,8 +2102,8 @@ <translation>Копіювати решту</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>Всього %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>Всього %1</translation> </message> <message> <source>or</source> @@ -2014,15 +2137,15 @@ <source>Payment request expired.</source> <translation>Запит платежу прострочено.</translation> </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>Сплатіть лише мінімальну комісію у розмірі %1</translation> + </message> <message numerus="yes"> <source>Estimated to begin confirmation within %n block(s).</source> <translation><numerusform>Перше підтвердження очікується протягом %n блоку.</numerusform><numerusform>Перше підтвердження очікується протягом %n блоків.</numerusform><numerusform>Перше підтвердження очікується протягом %n блоків.</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>Платити тільки мінімальну комісію у розмірі %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>Адреса отримувача неправильна. Будь ласка, перевірте її.</translation> </message> @@ -2654,6 +2777,10 @@ <translation>Скопіювати ID транзакції </translation> </message> <message> + <source>Copy raw transaction</source> + <translation>Скопіювати RAW транзакцію</translation> + </message> + <message> <source>Edit label</source> <translation>Редагувати мітку</translation> </message> @@ -2801,12 +2928,52 @@ <translation>Приймати команди із командного рядка та команди JSON-RPC</translation> </message> <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>Якщо <category> не задано, або ж якщо <category> = 1, виводить всю налагоджувальну інформацію.</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>Максимальна загальна комісія (в %s) за одну транзакцію; занадто низьке значення може скасувати відправку великих транзакцій (типово: %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>Будь ласка, перевірте коректність дати і часу на своєму комп'ютері! За наявності значної похибки Bitcoin Core буде працювати неправильно.</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>Встановлений розмір ланцюжка блоків є замалим (меншим за %d МіБ). Будь ласка, виберіть більше число.</translation> + </message> + <message> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation>Операція відсікання: остання синхронізація вмісту гаманцю не обмежується діями над скороченими данними. Вам необхідно зробити переіндексацію -reindex (заново завантажити веcь ланцюжок блоків в разі появи скороченого ланцюга)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>Зменшити вимоги до наявного простору на носії даних за допомогою скорочення ланцюжка (видалення старих блоків). Цей режим несумісний з параметрами -txindex та -rescan. Увага: при поверненні до типового значення видалені частини ланцюжка буде повторно завантажено. (типово: 0 = вимкнути скорочення ланцюжка, >%u = очікуваний розмір файлів блоків в МіБ)</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>Неможливо провести повторне сканування зі скороченим ланцюжком. Вам необхідно використати -reindex для завантаження повного ланцюжка блоків.</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>Помилка: Сталася фатальна помилка (детальніший опис наведено в debug.log)</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>Комісія (в %s/КБ), що додаватиметься до вихідних транзакцій (типово: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>Скорочення кількості блоків...</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>Запустити в фоновому режимі (як демон) та приймати команди</translation> </message> <message> - <source>Use the test network</source> - <translation>Використовувати тестову мережу</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>Неможливо запустити HTTP-сервер. Детальніший опис наведено в журналі зневадження.</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2829,18 +2996,14 @@ <translation>Виконати команду, коли транзакція гаманця зміниться (замість %s в команді буде підставлено ідентифікатор транзакції)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>Максимальна загальна комісія за одну транзакцію; занадто низьке значення може скасувати відправку великих транзакцій (типово: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>Зменшити вимоги до наявного простору на носії даних за допомогою скорочення ланцюжка (видалення старих блоків). Цей режим вимикає підтримку гаманця та є несумісним з параметром -txindex. Увага: при поверненні до типового значення видалені частини ланцюжка буде повторно завантажено. (типово: 0 = вимкнути скорочення ланцюжка, >%u = очікуваний розмір файлів блоків в МіБ)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>Встановити кількість потоків скрипту перевірки (від %u до %d, 0 = автоматично, <0 = вказує кількість вільних ядер, типово: %d)</translation> </message> <message> + <source>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>Схоже, що база даних блоків містить блок з майбутнього. Це може статися із-за некоректно встановленої дати та/або часу. Перебудовуйте базу даних блоків лише тоді, коли ви переконані, що встановлено правильну дату і час</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> @@ -2849,6 +3012,10 @@ <translation>Неможливо прив'язатися до %s на цьому комп'ютері. Можливо, Bitcoin Core вже запущено.</translation> </message> <message> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>Використовувати UPnP для відображення порту, що прослуховується (типово: 1 при прослуховуванні та за відсутності -proxy)</translation> + </message> + <message> <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> <translation>УВАГА: аномально висока кількість згенерованих блоків, %d блок(ів) було отримано за останні %d годин(и) (має бути %d)</translation> </message> @@ -2857,10 +3024,6 @@ <translation>УВАГА: перевірте ваше мережеве з'єднання, %d блок(ів) було отримано за останні %d годин(и) (має бути %d)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>Увага: встановлено занадто велику комісію (-paytxfee). Комісія зніматиметься кожен раз коли ви проводитимете транзакції.</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>Увага: Частина мережі використовує інший головний ланцюжок! Деякі добувачі, можливо, зазнають проблем.</translation> </message> @@ -2869,10 +3032,6 @@ <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> - <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> </message> @@ -2881,18 +3040,14 @@ <translation>Додати учасників, що під'єднуються з заданої підмережі чи IP-адреси, в білий список. Можна вказувати декілька разів.</translation> </message> <message> - <source>(default: 1)</source> - <translation>(типово: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool має бути не менше %d МБ</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> - <message> <source>Block creation options:</source> <translation>Опції створення блоку:</translation> </message> @@ -2921,6 +3076,22 @@ <translation>Ви хочете перебудувати базу даних блоків зараз?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation>Дозволено введення хеш блоку в рядок <address></translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>Дозволено введення хеш транзакції в рядок <address></translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>Дозволено введення RAW блоку в рядок <address></translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation>Дозволено введення RAW транзакції в рядок <address></translation> + </message> + <message> <source>Error initializing block database</source> <translation>Помилка ініціалізації бази даних блоків</translation> </message> @@ -2937,10 +3108,6 @@ <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> @@ -2949,10 +3116,6 @@ <translation>Не вдалося слухати на жодному порту. Використовуйте -listen=0, якщо ви хочете цього.</translation> </message> <message> - <source>If <category> is not supplied, output all debugging information.</source> - <translation>Якщо <category> не задано, виводить всю налагоджувальну інформацію.</translation> - </message> - <message> <source>Importing...</source> <translation>Імпорт...</translation> </message> @@ -2965,6 +3128,10 @@ <translation>Помилка в адресі -onion: «%s»</translation> </message> <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>Утримувати розмір пам'яті для пулу транзакцій меншим за <n> мегабайтів (типово: %u)</translation> + </message> + <message> <source>Not enough file descriptors available.</source> <translation>Бракує доступних дескрипторів файлів.</translation> </message> @@ -2993,8 +3160,24 @@ <translation>Вкажіть файл гаманця (в межах каталогу даних)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>Параметр -benchmark не підтримується та буде проігноровано; використовуйте -debug=bench.</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>Параметр -debugnet не підтримується та буде проігноровано; використовуйте -debug=net.</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>Параметр -tor не підтримується; використовуйте -onion.</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: %u)</source> - <translation>Намагатись використовувати UPnP для відображення порту, що прослуховується, на роутері (типово: %u)</translation> + <translation>Використовувати UPnP для відображення порту, що прослуховується (типово: %u)</translation> + </message> + <message> + <source>User Agent comment (%s) contains unsafe characters.</source> + <translation>Коментар до Клієнта Користувача (%s) містить небезпечні символи.</translation> </message> <message> <source>Verifying blocks...</source> @@ -3021,18 +3204,10 @@ <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> @@ -3057,16 +3232,12 @@ <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> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>Комісії (в %s/kB), що менші за вказану, вважатимуться нульовими для зміни, аналізу та створення транзакцій (типово: %s)</translation> </message> <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> @@ -3081,10 +3252,6 @@ <translation>Максимальний розмір даних в транзакціях носіїв даних, що ми передаємо і добуваємо (за замовчуванням: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>Встановлений розмір ланцюжка блоків є замалим (менший за %d МБ). Будь ласка, виберіть більше число.</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>Дізнаватися адреси учасників через DNS при замалій кількості відомих адрес (типово: 1 за відсутності -connect)</translation> </message> @@ -3109,38 +3276,6 @@ <translation>Цей продукт включає в себе програмне забезпечення, розроблене в рамках проекту OpenSSL <https://www.openssl.org/>, криптографічне програмне забезпечення, написане Еріком Янгом, та функції для роботи з UPnP, написані Томасом Бернардом.</translation> </message> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>Для використання bitcoind, або bitcoin-qt з параметром -server, ви повинні встановити rpcpassword в файлі конфігурації: -%s -Рекомендується використати такий випадковий пароль: -rpcuser=bitcoinrpc -rpcpassword=%s -(вам не треба запам'ятовувати цей пароль) -Ім'я користувача та пароль ПОВИННІ бути різними. -Якщо файлу не існує, створіть його, обмеживши доступ правом читання для власника. -Також рекомендується використовувати alertnotify для того, щоб отримувати сповіщення про проблеми; -наприклад: alertnotify=echo %%s | mail -s "Сповіщення Bitcoin" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>Увага: установлено дуже велике значення -maxtxfee! Такі великі комісії можуть бути сплачені в окремій транзакції.</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> @@ -3161,16 +3296,20 @@ rpcpassword=%s <translation>Активація найкращого ланцюжка...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>Використання гаманця зі скороченим ланцюжком блоків неможливе.</translation> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>Завжди передавайте транзакції отримані від пірів з білого списку (типово: %d)</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>Не вдалося розпізнати адресу для -whitebind: «%s»</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>Спочатку спробуйте відновити приватні ключі в пошкодженому wallet.dat </translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Обрати каталог даних під час запуску (типово: 0)</translation> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>Автоматичне з'єднання з прихованим сервісом Tor (типово: %d)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>Не вдалося розпізнати адресу для -whitebind: «%s»</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3181,10 +3320,6 @@ rpcpassword=%s <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> @@ -3193,12 +3328,8 @@ rpcpassword=%s <translation>Помилка читання бази даних, припиняю роботу.</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> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>Спочатку імпортує блоки з зовнішнього файлу blk000??.dat </translation> </message> <message> <source>Information</source> @@ -3241,18 +3372,10 @@ rpcpassword=%s <translation>Параметри вузла ретрансляції:</translation> </message> <message> - <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>RPC support for HTTP persistent connections (default: %d)</source> - <translation>Підтримка RPC для постійних HTTP-з'єднань (типово: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>При запуску перебудувати індекс ланцюжка блоків з поточних файлів blk000??.dat</translation> </message> @@ -3261,30 +3384,26 @@ rpcpassword=%s <translation>Отримувати та відображати попередження з мережі (типово: %u)</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>Відсилати налагоджувальну інформацію на консоль, а не у файл debug.log</translation> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> + <translation>Зменшення значення -maxconnections з %d до %d із-за обмежень системи.</translation> </message> <message> - <source>Send transactions as zero-fee transactions if possible (default: %u)</source> - <translation>Не сплачувати комісію за надсилання транзакцій, якщо це можливо (типово: %u)</translation> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>Спочатку переглянте ланцюжок блоків на наявність втрачених транзакцій гаманця</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Вказати кореневі SSL-сертифікати для запиту платежу (типово: -системні-)</translation> + <source>Send trace/debug info to console instead of debug.log file</source> + <translation>Відсилати налагоджувальну інформацію на консоль, а не у файл debug.log</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>Встановлення мови, наприклад "de_DE" (типово: системна)</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> <translation>Показати всі налагоджувальні параметри (використання: --help -help-debug)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>Показувати заставку під час запуску (типово: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>Стискати файл debug.log під час старту клієнта (типово: 1 коли відсутній параметр -debug)</translation> </message> @@ -3293,10 +3412,6 @@ rpcpassword=%s <translation>Підписання транзакції не вдалося</translation> </message> <message> - <source>Start minimized</source> - <translation>Запускати згорнутим</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>Неможливо сплатити комісію із-за малої суми транзакції</translation> </message> @@ -3305,6 +3420,14 @@ rpcpassword=%s <translation>Це програмне забезпечення є експериментальним.</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>Пароль управління порт протоколом Tor (типово: empty)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>Скористайтесь управлінням порт протоколом Tor, в разі перехоплення обміну цибулевої маршрутизації (типово: %s)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>Сума транзакції занадто мала</translation> </message> @@ -3321,16 +3444,12 @@ rpcpassword=%s <translation>Транзакція занадто велика</translation> </message> <message> - <source>UI Options:</source> - <translation>Параметри інтерфейсу:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>Неможливо прив'язатися до %s на цьому комп'ютері (bind повернув помилку: %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>Намагатись використовувати UPnP для відображення порту, що прослуховується на роутері (типово: 1 коли прослуховується)</translation> + <source>Upgrade wallet to latest format on startup</source> + <translation>Спочатку оновіть гаманець до останньої версії</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3345,20 +3464,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> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>Чи слід працювати в режимі тільки блоки (типово: %u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> <translation>Видалення всіх транзакцій з гаманця...</translation> </message> <message> - <source>on startup</source> - <translation>під час запуску</translation> + <source>ZeroMQ notification options:</source> + <translation>Параметри сповіщень ZeroMQ:</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3373,18 +3488,6 @@ rpcpassword=%s <translation>Виконати команду, коли з'явиться новий блок (%s в команді змінюється на хеш блоку)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>Модернізувати гаманець до найновішого формату</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>Пересканувати ланцюжок блоків, в пошуку втрачених транзакцій</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>Використовувати OpenSSL (https) для JSON-RPC-з'єднань</translation> - </message> - <message> <source>This help message</source> <translation>Дана довідка</translation> </message> @@ -3405,6 +3508,26 @@ rpcpassword=%s <translation>(1 = утримувати метадані транзакцій (до яких відноситься інформація про власника рахунку та запити платежів), 2 - відкинути)</translation> </message> <message> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>Встановлено дуже велике значення -maxtxfee! Такі великі комісії можуть бути сплачені окремою транзакцією.</translation> + </message> + <message> + <source>-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>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>Не тримати транзакції в пам'яті довше <n> годин (типово: %u)</translation> + </message> + <message> + <source>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> + <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>Комісії (в %s/kB), що менші за вказану, вважатимуться нульовими для створення транзакцій (типово: %s)</translation> + </message> + <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>Рівень ретельності перевірки блоків (0-4, типово: %u)</translation> </message> @@ -3421,16 +3544,32 @@ rpcpassword=%s <translation>Виводити налагоджувальну інформацію (типово: %u, вказання <category> необов'язкове)</translation> </message> <message> + <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> + <translation>Фільтрація блоків та транзакцій з допомогою фільтрів Блума (типово: %u)</translation> + </message> + <message> + <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> + <translation>Загальна довжина рядку мережевої версії (%i) перевищує максимально допустиму (%i). Зменшіть число чи розмір коментарів клієнта користувача.</translation> + </message> + <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>Намагається зберегти вихідний трафік відповідно до зданого значення (в MIB за 24 години), 0 = без обмежень (типово: %d)</translation> + </message> + <message> + <source>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>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> + <source>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source> + <translation>Логін та хешований пароль для зв'язків JSON-RPC. Поле <userpw> має формат: <USERNAME>:<SALT>$<HASH>. Класичний Python script додано до share/rpcuser. Цей параметр може бути застосований декілька разів.</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>Допустимі шифри (типово: %s)</translation> + <source>(default: %s)</source> + <translation>(типово: %s)</translation> </message> <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> @@ -3493,14 +3632,6 @@ rpcpassword=%s <translation>Ретранслювати не-P2SH транзакції з мультипідписом (типово: %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> diff --git a/src/qt/locale/bitcoin_ur_PK.ts b/src/qt/locale/bitcoin_ur_PK.ts index d4242d5e3c..e37c87baa8 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.0"> +<TS language="ur_PK" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -109,6 +109,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Error</source> @@ -121,6 +124,10 @@ <context> <name>CoinControlDialog</name> <message> + <source>Amount:</source> + <translation>رقم:</translation> + </message> + <message> <source>Amount</source> <translation>رقم</translation> </message> @@ -135,6 +142,14 @@ </context> <context> <name>EditAddressDialog</name> + <message> + <source>&Label</source> + <translation>چٹ</translation> + </message> + <message> + <source>&Address</source> + <translation> پتہ</translation> + </message> </context> <context> <name>FreespaceChecker</name> @@ -183,6 +198,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>کاپی پتہ</translation> + </message> + <message> <source>Address</source> <translation> پتہ</translation> </message> @@ -217,6 +236,14 @@ <context> <name>SendCoinsDialog</name> <message> + <source>Insufficient funds!</source> + <translation>ناکافی فنڈز</translation> + </message> + <message> + <source>Amount:</source> + <translation>رقم:</translation> + </message> + <message> <source>Balance:</source> <translation>بیلنس:</translation> </message> diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts index cc0a4bba08..86724564ff 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.0"> +<TS language="uz@Cyrl" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -213,6 +213,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -790,6 +793,10 @@ <translation>Bitcoin Core ҳақида</translation> </message> <message> + <source>Command-line options</source> + <translation>Буйруқлар сатри мосламалари</translation> + </message> + <message> <source>Usage:</source> <translation>Фойдаланиш:</translation> </message> @@ -797,7 +804,7 @@ <source>command-line options</source> <translation>буйруқлар қатори орқали мослаш</translation> </message> -</context> + </context> <context> <name>Intro</name> <message> @@ -899,6 +906,14 @@ <translation>Бегона тараф ўтказмалари URL манзиллари</translation> </message> <message> + <source>&Network</source> + <translation>Тармоқ</translation> + </message> + <message> + <source>W&allet</source> + <translation>Ҳамён</translation> + </message> + <message> <source>Proxy &IP:</source> <translation>Прокси &IP рақами:</translation> </message> @@ -1033,13 +1048,45 @@ <source>Recent transactions</source> <translation>Сўнгги пул ўтказмалари</translation> </message> - </context> + <message> + <source>Unconfirmed transactions to watch-only addresses</source> + <translation>Тасдиқланмаган ўтказмалар-фақат манзилларини кўриш</translation> + </message> + <message> + <source>Current total balance in watch-only addresses</source> + <translation>Жорий умумий баланс фақат кўринадиган манзилларда</translation> + </message> +</context> <context> <name>PaymentServer</name> + <message> + <source>URI handling</source> + <translation>URI осилиб қолмоқда</translation> + </message> + <message> + <source>Invalid payment address %1</source> + <translation>Нотўғри тўлов манзили %1</translation> + </message> + <message> + <source>Payment request rejected</source> + <translation>Тўлов сўрови инкор этилди</translation> + </message> + <message> + <source>Payment request network doesn't match client network.</source> + <translation>Тўлов сўрови тармоғи мижоз тармоғига мос келмайди.</translation> + </message> + <message> + <source>Payment request error</source> + <translation>Тўлов сўрови хато</translation> + </message> </context> <context> <name>PeerTableModel</name> <message> + <source>User Agent</source> + <translation>Фойдаланувчи вакил</translation> + </message> + <message> <source>Ping Time</source> <translation>Ping вақти</translation> </message> @@ -1051,6 +1098,10 @@ <translation>Миқдори</translation> </message> <message> + <source>Enter a Bitcoin address (e.g. %1)</source> + <translation>Bitcoin манзилини киритинг (масалан. %1)</translation> + </message> + <message> <source>%1 m</source> <translation>%1 д</translation> </message> @@ -1145,12 +1196,20 @@ <translation>Батафсил маълумотларни кўриш учун уламни танланг.</translation> </message> <message> - <source>Starting Height</source> - <translation>Узунликнинг бошланиши</translation> + <source>Direction</source> + <translation>Йўналиш</translation> + </message> + <message> + <source>Version</source> + <translation>Версия</translation> + </message> + <message> + <source>User Agent</source> + <translation>Фойдаланувчи вакил</translation> </message> <message> - <source>Sync Height</source> - <translation>Узунликни синхронлаш</translation> + <source>Services</source> + <translation>Хизматлар</translation> </message> <message> <source>Ban Score</source> @@ -1169,14 +1228,6 @@ <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> @@ -1257,12 +1308,24 @@ <translation>ҳеч қачон</translation> </message> <message> - <source>Unknown</source> - <translation>Номаълум</translation> + <source>Inbound</source> + <translation>Ички йўналиш</translation> + </message> + <message> + <source>Outbound</source> + <translation>Ташқи йўналиш</translation> </message> <message> - <source>Fetching...</source> - <translation>Олинмоқда...</translation> + <source>Yes</source> + <translation>Ҳа</translation> + </message> + <message> + <source>No</source> + <translation>Йўқ</translation> + </message> + <message> + <source>Unknown</source> + <translation>Номаълум</translation> </message> </context> <context> @@ -1343,10 +1406,30 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>QR Code</source> + <translation>QR Коди</translation> + </message> + <message> + <source>Copy &Address</source> + <translation>Нусҳалаш & Манзил</translation> + </message> + <message> <source>&Save Image...</source> <translation>Расмни &сақлаш</translation> </message> <message> + <source>Request payment to %1</source> + <translation> %1 дан Тўловни сўраш</translation> + </message> + <message> + <source>Payment information</source> + <translation>Тўлов маълумоти</translation> + </message> + <message> + <source>URI</source> + <translation>URI</translation> + </message> + <message> <source>Address</source> <translation>Манзил</translation> </message> @@ -1358,6 +1441,10 @@ <source>Label</source> <translation>Ёрлик</translation> </message> + <message> + <source>Message</source> + <translation>Хабар</translation> + </message> </context> <context> <name>RecentRequestsTableModel</name> @@ -1370,6 +1457,10 @@ <translation>Ёрлик</translation> </message> <message> + <source>Message</source> + <translation>Хабар</translation> + </message> + <message> <source>Amount</source> <translation>Миқдори</translation> </message> @@ -1377,7 +1468,15 @@ <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> @@ -1385,6 +1484,18 @@ <translation>Тангаларни жунат</translation> </message> <message> + <source>Coin Control Features</source> + <translation>Танга бошқаруви ҳусусиятлари</translation> + </message> + <message> + <source>automatically selected</source> + <translation>автоматик тарзда танланган</translation> + </message> + <message> + <source>Insufficient funds!</source> + <translation>Кам миқдор</translation> + </message> + <message> <source>Quantity:</source> <translation>Сони:</translation> </message> @@ -1421,6 +1532,34 @@ <translation>Бошқа ўзгартирилган манзил</translation> </message> <message> + <source>Transaction Fee:</source> + <translation>Ўтказма тўлови</translation> + </message> + <message> + <source>Choose...</source> + <translation>Танлов</translation> + </message> + <message> + <source>per kilobyte</source> + <translation>Хар килобайтига</translation> + </message> + <message> + <source>Recommended:</source> + <translation>Тавсия этилган</translation> + </message> + <message> + <source>Confirmation time:</source> + <translation>Тасдиқ вақти</translation> + </message> + <message> + <source>normal</source> + <translation>Нормал</translation> + </message> + <message> + <source>fast</source> + <translation>Тезкор</translation> + </message> + <message> <source>Send to multiple recipients at once</source> <translation>Бирданига бир нечта қабул қилувчиларга жўнатиш</translation> </message> @@ -1433,6 +1572,10 @@ <translation>Ахлат қутиси:</translation> </message> <message> + <source>Clear &All</source> + <translation>Барчасини & Тозалаш</translation> + </message> + <message> <source>Balance:</source> <translation>Баланс</translation> </message> @@ -1441,10 +1584,18 @@ <translation>Жўнатиш амалини тасдиқлаш</translation> </message> <message> + <source>S&end</source> + <translation>Жў&натиш</translation> + </message> + <message> <source>Confirm send coins</source> <translation>Тангалар жўнаишни тасдиқлаш</translation> </message> <message> + <source>%1 to %2</source> + <translation>%1 дан %2</translation> + </message> + <message> <source>Copy quantity</source> <translation>Нусха сони</translation> </message> @@ -1473,6 +1624,10 @@ <translation>Нусха қайтими</translation> </message> <message> + <source>or</source> + <translation>ёки</translation> + </message> + <message> <source>The amount to pay must be larger than 0.</source> <translation>Тўлов миқдори 0. дан катта бўлиши керак. </translation> </message> @@ -1520,6 +1675,14 @@ <translation>&Ёрлиқ:</translation> </message> <message> + <source>Choose previously used address</source> + <translation>Олдин фойдаланилган манзилни танла</translation> + </message> + <message> + <source>This is a normal payment.</source> + <translation>Бу нормал тўлов.</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1531,6 +1694,14 @@ <source>Alt+P</source> <translation>Alt+P</translation> </message> + <message> + <source>Message:</source> + <translation>Хабар</translation> + </message> + <message> + <source>Pay To:</source> + <translation>Тўлов олувчи:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -1538,6 +1709,10 @@ <context> <name>SignVerifyMessageDialog</name> <message> + <source>Choose previously used address</source> + <translation>Олдин фойдаланилган манзилни танла</translation> + </message> + <message> <source>Alt+A</source> <translation>Alt+A</translation> </message> @@ -1553,7 +1728,15 @@ <source>Signature</source> <translation>Имзо</translation> </message> - </context> + <message> + <source>Clear &All</source> + <translation>Барчасини & Тозалаш</translation> + </message> + <message> + <source>Message verified.</source> + <translation>Хабар тасдиқланди.</translation> + </message> +</context> <context> <name>SplashScreen</name> <message> @@ -1591,14 +1774,78 @@ <translation>Сана</translation> </message> <message> + <source>Source</source> + <translation>Манба</translation> + </message> + <message> + <source>Generated</source> + <translation>Яратилган</translation> + </message> + <message> + <source>From</source> + <translation>Дан</translation> + </message> + <message> + <source>To</source> + <translation>Га</translation> + </message> + <message> + <source>own address</source> + <translation>ўз манзили</translation> + </message> + <message> + <source>label</source> + <translation>ёрлиқ</translation> + </message> + <message> + <source>Credit</source> + <translation>Кредит (қарз)</translation> + </message> + <message> + <source>not accepted</source> + <translation>қабул қилинмади</translation> + </message> + <message> + <source>Transaction fee</source> + <translation>Ўтказма тўлови</translation> + </message> + <message> + <source>Net amount</source> + <translation>Умумий миқдор</translation> + </message> + <message> + <source>Message</source> + <translation>Хабар</translation> + </message> + <message> + <source>Comment</source> + <translation>Шарҳ</translation> + </message> + <message> <source>Transaction ID</source> <translation>ID</translation> </message> <message> + <source>Merchant</source> + <translation>Савдо</translation> + </message> + <message> + <source>Transaction</source> + <translation>Ўтказма</translation> + </message> + <message> <source>Amount</source> <translation>Миқдори</translation> </message> <message> + <source>true</source> + <translation>рост</translation> + </message> + <message> + <source>false</source> + <translation>ёлғон</translation> + </message> + <message> <source>, has not been successfully broadcast yet</source> <translation>, ҳалигача трансляция қилингани йўқ</translation> </message> @@ -1645,14 +1892,26 @@ <translation>Яратилди, аммо қабул қилинмади</translation> </message> <message> + <source>Offline</source> + <translation>Оффлайн</translation> + </message> + <message> <source>Label</source> <translation>Ёрлиқ</translation> </message> <message> + <source>Unconfirmed</source> + <translation>Тасдиқланмаган</translation> + </message> + <message> <source>Received with</source> <translation>Ёрдамида қабул қилиш</translation> </message> <message> + <source>Received from</source> + <translation>Дан қабул қилиш</translation> + </message> + <message> <source>Sent to</source> <translation>Жўнатиш</translation> </message> @@ -1764,10 +2023,26 @@ <translation>Ёрликни тахрирлаш</translation> </message> <message> + <source>Show transaction details</source> + <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>The transaction history was successfully saved to %1.</source> + <translation>Ўтказмалар тарихи %1 га муваффаққиятли сақланди.</translation> + </message> + <message> <source>Comma separated file (*.csv)</source> <translation>Вергул билан ажратилган файл (*.csv)</translation> </message> @@ -1809,7 +2084,11 @@ </context> <context> <name>WalletFrame</name> - </context> + <message> + <source>No wallet has been loaded.</source> + <translation>Хали бирорта хамён юкланмади</translation> + </message> +</context> <context> <name>WalletModel</name> <message> @@ -1847,26 +2126,14 @@ <translation>Демон сифатида орқа фонда ишга туширинг ва буйруқларга рози бўлинг</translation> </message> <message> - <source>Use the test network</source> - <translation>Синов тармоғидан фойдаланинг</translation> - </message> - <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>Ишга тушиш вақтида маълумотлар директориясини танлаш (стандарт: 0)</translation> + <source>Connection options:</source> + <translation>Уланиш кўрсаткичлари:</translation> </message> <message> <source>Information</source> <translation>Маълумот</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>Тўлов сўровлари учун SSL асос сертификатларини ўрнатиш (стандарт: -system-)</translation> - </message> - <message> - <source>Start minimized</source> - <translation>Йиғилганларни бошлаш</translation> - </message> - <message> <source>Username for JSON-RPC connections</source> <translation>JSON-RPC уланишлари учун фойдаланувчи номи</translation> </message> @@ -1879,10 +2146,6 @@ <translation>JSON-RPC уланишлари учун парол</translation> </message> <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>JSON-RPC уланишлари учун OpenSSL (https)дан фойдаланиш</translation> - </message> - <message> <source>This help message</source> <translation>Бу ёрдам хабари</translation> </message> @@ -1891,6 +2154,10 @@ <translation>Манзиллар юкланмоқда...</translation> </message> <message> + <source>Insufficient funds</source> + <translation>Кам миқдор</translation> + </message> + <message> <source>Loading block index...</source> <translation>Тўсиқ индекси юкланмоқда...</translation> </message> diff --git a/src/qt/locale/bitcoin_vi.ts b/src/qt/locale/bitcoin_vi.ts index 64d11d4645..47745a3bc8 100644 --- a/src/qt/locale/bitcoin_vi.ts +++ b/src/qt/locale/bitcoin_vi.ts @@ -1,4 +1,4 @@ -<TS language="vi" version="2.0"> +<TS language="vi" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -49,6 +49,9 @@ <name>AskPassphraseDialog</name> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> </context> <context> @@ -57,6 +60,10 @@ <context> <name>CoinControlDialog</name> <message> + <source>Amount:</source> + <translation>Số lượng:</translation> + </message> + <message> <source>Amount</source> <translation>Số lượng</translation> </message> @@ -67,6 +74,14 @@ </context> <context> <name>EditAddressDialog</name> + <message> + <source>&Label</source> + <translation>Nhãn dữ liệu</translation> + </message> + <message> + <source>&Address</source> + <translation>Địa chỉ</translation> + </message> </context> <context> <name>FreespaceChecker</name> @@ -111,6 +126,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>Sao chép địa chỉ</translation> + </message> + <message> <source>Address</source> <translation>Địa chỉ</translation> </message> @@ -141,6 +160,10 @@ <context> <name>SendCoinsDialog</name> <message> + <source>Amount:</source> + <translation>Số lượng:</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 7bcded7448..d55fa61885 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.0"> +<TS language="vi_VN" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -137,6 +137,9 @@ </message> </context> <context> + <name>BanTableModel</name> + </context> +<context> <name>BitcoinGUI</name> <message> <source>&Overview</source> @@ -163,6 +166,10 @@ <translation>Xem thông tin về Qt</translation> </message> <message> + <source>&Receiving addresses...</source> + <translation>Địa chỉ nhận</translation> + </message> + <message> <source>Open &URI...</source> <translation>Mở &URI...</translation> </message> @@ -351,6 +358,14 @@ </context> <context> <name>EditAddressDialog</name> + <message> + <source>&Label</source> + <translation>Nhãn</translation> + </message> + <message> + <source>&Address</source> + <translation>Địa chỉ</translation> + </message> </context> <context> <name>FreespaceChecker</name> @@ -415,6 +430,10 @@ <translation>MB</translation> </message> <message> + <source>W&allet</source> + <translation>Ví</translation> + </message> + <message> <source>&Display</source> <translation>&Hiển thị</translation> </message> @@ -465,6 +484,10 @@ <context> <name>RPCConsole</name> <message> + <source>&Information</source> + <translation>Thông tin</translation> + </message> + <message> <source>General</source> <translation>Nhìn Chung</translation> </message> @@ -488,6 +511,10 @@ <context> <name>ReceiveCoinsDialog</name> <message> + <source>&Amount:</source> + <translation>Lượng:</translation> + </message> + <message> <source>Copy label</source> <translation>Copy nhãn</translation> </message> @@ -499,6 +526,10 @@ <context> <name>ReceiveRequestDialog</name> <message> + <source>Copy &Address</source> + <translation>&Copy Địa Chỉ</translation> + </message> + <message> <source>Address</source> <translation>Địa chỉ</translation> </message> @@ -533,6 +564,10 @@ <context> <name>SendCoinsDialog</name> <message> + <source>Insufficient funds!</source> + <translation>Không đủ tiền</translation> + </message> + <message> <source>Quantity:</source> <translation>Lượng:</translation> </message> @@ -567,6 +602,10 @@ </context> <context> <name>SendCoinsEntry</name> + <message> + <source>A&mount:</source> + <translation>Lượng:</translation> + </message> </context> <context> <name>ShutdownWindow</name> @@ -671,6 +710,14 @@ <context> <name>bitcoin-core</name> <message> + <source>Options:</source> + <translation>Lựa chọn:</translation> + </message> + <message> + <source>(default: %u)</source> + <translation>(mặc định: %u)</translation> + </message> + <message> <source>Information</source> <translation>Thông tin</translation> </message> @@ -683,10 +730,6 @@ <translation>Chú ý</translation> </message> <message> - <source>on startup</source> - <translation>khi khởi động</translation> - </message> - <message> <source>This help message</source> <translation>Thông điệp trợ giúp này</translation> </message> diff --git a/src/qt/locale/bitcoin_zh.ts b/src/qt/locale/bitcoin_zh.ts new file mode 100644 index 0000000000..aeb4faa712 --- /dev/null +++ b/src/qt/locale/bitcoin_zh.ts @@ -0,0 +1,221 @@ +<TS language="zh" version="2.1"> +<context> + <name>AddressBookPage</name> + </context> +<context> + <name>AddressTableModel</name> + </context> +<context> + <name>AskPassphraseDialog</name> + </context> +<context> + <name>BanTableModel</name> + </context> +<context> + <name>BitcoinGUI</name> + <message> + <source>Error</source> + <translation>错误</translation> + </message> + <message> + <source>Warning</source> + <translation>警告</translation> + </message> + </context> +<context> + <name>ClientModel</name> + </context> +<context> + <name>CoinControlDialog</name> + <message> + <source>Date</source> + <translation>日期</translation> + </message> + </context> +<context> + <name>EditAddressDialog</name> + </context> +<context> + <name>FreespaceChecker</name> + </context> +<context> + <name>HelpMessageDialog</name> + </context> +<context> + <name>Intro</name> + <message> + <source>Error</source> + <translation>错误</translation> + </message> + </context> +<context> + <name>OpenURIDialog</name> + </context> +<context> + <name>OptionsDialog</name> + </context> +<context> + <name>OverviewPage</name> + </context> +<context> + <name>PaymentServer</name> + </context> +<context> + <name>PeerTableModel</name> + </context> +<context> + <name>QObject</name> + </context> +<context> + <name>QRImageWidget</name> + </context> +<context> + <name>RPCConsole</name> + </context> +<context> + <name>ReceiveCoinsDialog</name> + </context> +<context> + <name>ReceiveRequestDialog</name> + </context> +<context> + <name>RecentRequestsTableModel</name> + <message> + <source>Date</source> + <translation>日期</translation> + </message> + </context> +<context> + <name>SendCoinsDialog</name> + <message> + <source>Insufficient funds!</source> + <translation>余额不足</translation> + </message> + <message> + <source>Choose...</source> + <translation>选择...</translation> + </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>仅支付全额的%1</translation> + </message> + <message> + <source>The recipient address is not valid. Please recheck.</source> + <translation>收款人地址无效,请再次确认。</translation> + </message> + <message> + <source>Warning: Invalid Bitcoin address</source> + <translation>警告:比特币地址无效</translation> + </message> + </context> +<context> + <name>SendCoinsEntry</name> + </context> +<context> + <name>ShutdownWindow</name> + </context> +<context> + <name>SignVerifyMessageDialog</name> + </context> +<context> + <name>SplashScreen</name> + </context> +<context> + <name>TrafficGraphWidget</name> + </context> +<context> + <name>TransactionDesc</name> + <message> + <source>Date</source> + <translation>日期</translation> + </message> + </context> +<context> + <name>TransactionDescDialog</name> + </context> +<context> + <name>TransactionTableModel</name> + <message> + <source>Date</source> + <translation>日期</translation> + </message> + </context> +<context> + <name>TransactionView</name> + <message> + <source>Date</source> + <translation>日期</translation> + </message> + </context> +<context> + <name>UnitDisplayStatusBarControl</name> + </context> +<context> + <name>WalletFrame</name> + </context> +<context> + <name>WalletModel</name> + </context> +<context> + <name>WalletView</name> + </context> +<context> + <name>bitcoin-core</name> + <message> + <source>Transaction amounts must be positive</source> + <translation>转账额度须为正数</translation> + </message> + <message> + <source>Transaction too large for fee policy</source> + <translation>根据费率标准,本次转账超额</translation> + </message> + <message> + <source>Transaction too large</source> + <translation>超额转账</translation> + </message> + <message> + <source>Warning</source> + <translation>警告</translation> + </message> + <message> + <source>wallet.dat corrupt, salvage failed</source> + <translation>wallet.dat文件受损,修复失败</translation> + </message> + <message> + <source>This help message</source> + <translation>此条帮助信息</translation> + </message> + <message> + <source>Loading addresses...</source> + <translation>正在载入地址...</translation> + </message> + <message> + <source>Error loading wallet.dat: Wallet corrupted</source> + <translation>wallet.dat文件加载错误:钱包受损</translation> + </message> + <message> + <source>Error loading wallet.dat</source> + <translation>wallet.dat文件加载错误</translation> + </message> + <message> + <source>Insufficient funds</source> + <translation>余额不足</translation> + </message> + <message> + <source>Loading wallet...</source> + <translation>正在载入钱包...</translation> + </message> + <message> + <source>Rescanning...</source> + <translation>再次扫描...</translation> + </message> + <message> + <source>Done loading</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_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index 4470b2601b..0ae2c95c62 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.0"> +<TS language="zh_CN" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -23,7 +23,7 @@ </message> <message> <source>C&lose</source> - <translation>关闭(&C)</translation> + <translation>关闭(&l)</translation> </message> <message> <source>&Copy Address</source> @@ -35,7 +35,7 @@ </message> <message> <source>Export the data in the current tab to a file</source> - <translation>导出当前数据到文件</translation> + <translation>导出当前分页里的数据到文件</translation> </message> <message> <source>&Export</source> @@ -47,11 +47,11 @@ </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> @@ -133,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> @@ -185,7 +185,7 @@ </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> + <translation>请输入新的钱包密码. <br/>密码须包含<b>10个以上随机字符</b>,或<b>8个以上单词</b>.</translation> </message> <message> <source>Enter the old passphrase and new passphrase to the wallet.</source> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>IP/网络掩码</translation> + </message> + <message> + <source>Banned Until</source> + <translation>在此之前禁止:</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -260,7 +271,7 @@ </message> <message> <source>About &Qt</source> - <translation>关于 &Qt</translation> + <translation>关于Qt(&Q)</translation> </message> <message> <source>Show information about Qt</source> @@ -296,7 +307,7 @@ </message> <message> <source>Bitcoin Core client</source> - <translation>比特币核心钱包</translation> + <translation>比特币核心钱包客户端</translation> </message> <message> <source>Importing blocks from disk...</source> @@ -304,7 +315,7 @@ </message> <message> <source>Reindexing blocks on disk...</source> - <translation>正在为数据块建立索引...</translation> + <translation>正在为数据块重建索引...</translation> </message> <message> <source>Send coins to a Bitcoin address</source> @@ -871,6 +882,34 @@ <source>command-line options</source> <translation>命令行选项</translation> </message> + <message> + <source>UI Options:</source> + <translation>界面选项:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>在启动时选择目录(默认%u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>设置语言, 例如“zh-CN”(默认:系统语言)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>启动时最小化</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>设置付款请求的SSL根证书(默认:-系统-)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>显示启动画面(默认:%u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>重置所有图形界面所做的更改</translation> + </message> </context> <context> <name>Intro</name> @@ -1034,7 +1073,7 @@ </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>如果禁用未确认的零钱,则零钱至少需要1个确认才能使用。同时账户余额显示会受到影响。</translation> + <translation>如果禁用未确认的零钱,则零钱至少需要1个确认才能使用。同时账户余额计算会受到影响。</translation> </message> <message> <source>&Spend unconfirmed change</source> @@ -1069,6 +1108,34 @@ <translation>代理端口(例如 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>连接到同伴的方式:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>如果默认的SOCKS5代理被用于在该网络下连接同伴,则显示</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>在Tor匿名网络下通过不同的SOCKS5代理连接比特币网络</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>通过Tor隐藏服务连接节点时 使用不同的SOCKS5代理</translation> + </message> + <message> <source>&Window</source> <translation>窗口(&W)</translation> </message> @@ -1287,10 +1354,6 @@ <translation>支付请求 %1 太大 (%2 字节。只允许 %3 字节)。</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>支付请求防滥用保护</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>%1: %2 通讯出错</translation> </message> @@ -1443,6 +1506,18 @@ <translation>当前数据块数量</translation> </message> <message> + <source>Memory Pool</source> + <translation>资金池</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>当前交易数量</translation> + </message> + <message> + <source>Memory usage</source> + <translation>内存使用</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>从当前的数据目录打开比特币核心调试日志文件。对于较大的日志文件,这可能需要几秒钟。</translation> </message> @@ -1459,10 +1534,18 @@ <translation>同伴(&P)</translation> </message> <message> + <source>Banned peers</source> + <translation>节点黑名单</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>选择节点查看详细信息。</translation> </message> <message> + <source>Whitelisted</source> + <translation>白名单</translation> + </message> + <message> <source>Direction</source> <translation>方向</translation> </message> @@ -1471,20 +1554,24 @@ <translation>版本</translation> </message> <message> - <source>User Agent</source> - <translation>用户代理</translation> + <source>Starting Block</source> + <translation>正在启动数据块</translation> </message> <message> - <source>Services</source> - <translation>服务</translation> + <source>Synced Headers</source> + <translation>同步区块头</translation> </message> <message> - <source>Starting Height</source> - <translation>开始高度</translation> + <source>Synced Blocks</source> + <translation>同步区块链</translation> </message> <message> - <source>Sync Height</source> - <translation>同步高度</translation> + <source>User Agent</source> + <translation>用户代理</translation> + </message> + <message> + <source>Services</source> + <translation>服务</translation> </message> <message> <source>Ban Score</source> @@ -1503,18 +1590,14 @@ <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>Ping Wait</source> + <translation>Ping等待</translation> + </message> + <message> <source>Time Offset</source> <translation>时间偏移</translation> </message> @@ -1563,6 +1646,34 @@ <translation>清空控制台</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>(&D)断开节点连接</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>禁止节点连接时长:</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 小时(&H)</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 天(&D)</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 周(&W)</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 年(&Y)</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>(&U)允许节点连接</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>欢迎使用 比特币核心 RPC 控制台。</translation> </message> @@ -1591,6 +1702,10 @@ <translation>%1 GB</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(节点ID: %1)</translation> + </message> + <message> <source>via %1</source> <translation>通过 %1</translation> </message> @@ -1607,12 +1722,16 @@ <translation>传出</translation> </message> <message> - <source>Unknown</source> - <translation>未知</translation> + <source>Yes</source> + <translation>是</translation> + </message> + <message> + <source>No</source> + <translation>否</translation> </message> <message> - <source>Fetching...</source> - <translation>获取中...</translation> + <source>Unknown</source> + <translation>未知</translation> </message> </context> <context> @@ -1872,7 +1991,7 @@ </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> + <translation>交易量小时只支付最小交易费是可以的。但是请注意,当交易量大到超出网络可处理时您的交易可能永远无法确认。</translation> </message> <message> <source>(read the tooltip)</source> @@ -1936,7 +2055,7 @@ </message> <message> <source>Confirm the send action</source> - <translation>确认并发送货币</translation> + <translation>确认发送货币</translation> </message> <message> <source>S&end</source> @@ -1979,8 +2098,8 @@ <translation>复制零钱</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>总额 %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>总金额 %1</translation> </message> <message> <source>or</source> @@ -2014,15 +2133,15 @@ <source>Payment request expired.</source> <translation>支付请求已过期。</translation> </message> + <message> + <source>Pay only the required fee of %1</source> + <translation>只支付必要费用 %1</translation> + </message> <message numerus="yes"> <source>Estimated to begin confirmation within %n block(s).</source> <translation><numerusform>预计 %n 个数据块后被确认。</numerusform></translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>只支付最小费用 %1</translation> - </message> - <message> <source>The recipient address is not valid. Please recheck.</source> <translation>接收人地址无效。请重新检查。</translation> </message> @@ -2654,6 +2773,10 @@ <translation>复制交易编号</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>复制原始交易</translation> + </message> + <message> <source>Edit label</source> <translation>编辑标签</translation> </message> @@ -2804,15 +2927,46 @@ </translation> </message> <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>如果<category>未提供或<category> = 1,输出所有调试信息。</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>最大单次转账费用(%s),设置太低可能导致大宗交易失败(默认:%s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>警请检查电脑的日期时间设置是否正确!时间错误可能会导致比特币客户端运行异常。</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>修剪值被设置为低于最小值%d MiB,请使用更大的数值。</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>无法在开启修剪的状态下重扫描,请使用 -reindex重新下载完整的区块链。</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>错误:发生了致命的内部错误,详情见 debug.log 文件</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>为付款交易添加交易费 (%s/kB) (默认: %s) </translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>正在修剪区块存储...</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>在后台运行并接受命令 </translation> </message> <message> - <source>Use the test network</source> - <translation>使用测试网络 -</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>无法启动HTTP服务,查看日志获取更多信息</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2835,18 +2989,14 @@ <translation>当最佳区块变化时执行命令 (命令行中的 %s 会被替换成区块哈希值)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>单次交易最多使用交易费;设置太低可能导致大宗交易中止 (默认: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>通过修剪(删除)旧数据块减少存储需求。此模式将禁用钱包支持,并与 -txindex 不兼容。警告:还原此设置需要重新下载整个数据链。(默认: 0 = 禁用修剪数据块, >%u = 数据块文件目标大小,单位 MiB)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>设置脚本验证的程序 (%u 到 %d, 0 = 自动, <0 = 保留自由的核心, 默认值: %d)</translation> </message> <message> + <source>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>区块数据库包含未来的交易,这可能是由本机错误的日期时间引起。若确认本机日期时间正确,请重新建立区块数据库。</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> @@ -2855,6 +3005,10 @@ <translation>无法 %s的绑定到电脑上,比特币核心钱包可能已经在运行。</translation> </message> <message> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>使用UPnP暴露本机监听端口(默认:1 当正在监听且不使用代理)</translation> + </message> + <message> <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> <translation>警告:数据块生成数量异常,最近 %d 小时收到了 %d 个数据块(预期为 %d 个)</translation> </message> @@ -2863,10 +3017,6 @@ <translation>警告:请检查您的网络连接,最近 %d 小时收到了 %d 个数据块(预期为 %d 个)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>警告:-paytxfee 交易费设置得太高了!每笔交易都将支付交易费。</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>警告:网络似乎并不完全同意!有些矿工似乎遇到了问题。</translation> </message> @@ -2875,10 +3025,6 @@ <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> - <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损坏! 原始的钱包文件已经备份到%s目录下并重命名为{timestamp}.bak 。如果您的账户余额或者交易记录不正确,请使用您的钱包备份文件恢复。</translation> </message> @@ -2887,18 +3033,14 @@ <translation>节点白名单,网络掩码或IP址。可多次指定。</translation> </message> <message> - <source>(default: 1)</source> - <translation>(默认值: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>-maxmempool 最小为%d MB</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> - <message> <source>Block creation options:</source> <translation>数据块创建选项:</translation> </message> @@ -2927,6 +3069,22 @@ <translation>你想现在就重建块数据库吗?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation>允许在<address>广播哈希区块</translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>允许在<address>广播哈希交易</translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>允许在<address>广播原始区块</translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation>允许在<address>广播原始交易</translation> + </message> + <message> <source>Error initializing block database</source> <translation>初始化数据块数据库出错</translation> </message> @@ -2943,10 +3101,6 @@ <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> @@ -2955,10 +3109,6 @@ <translation>监听端口失败。请使用 -listen=0 参数。</translation> </message> <message> - <source>If <category> is not supplied, output all debugging information.</source> - <translation>如果<category>未提供,将输出所有调试信息。</translation> - </message> - <message> <source>Importing...</source> <translation>导入中...</translation> </message> @@ -2971,6 +3121,10 @@ <translation>无效的 -onion 地址:“%s”</translation> </message> <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>保持交易内存池大小低于<n>MB(默认:%u)</translation> + </message> + <message> <source>Not enough file descriptors available.</source> <translation>没有足够的文件描述符可用。</translation> </message> @@ -2999,6 +3153,18 @@ <translation>指定钱包文件(数据目录内)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>忽略不支持的选项 -benchmark,使用 -debug=bench</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>忽略不支持的选项 -debugnet,使用 -debug=net。</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>忽略不支持的选项 -tor,使用 -oinon</translation> + </message> + <message> <source>Use UPnP to map the listening port (default: %u)</source> <translation>使用UPnp映射监听端口 (默认: %u) </translation> </message> @@ -3027,18 +3193,10 @@ <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), 网络/掩码 (如: 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> @@ -3063,18 +3221,10 @@ <translation>错误:监听外部连接失败 (监听返回错误 %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/kb)比这更小的交易在转发时将被视为零费交易 (默认: %s) </translation> - </message> - <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> <translation>如果未设置交易费用,自动添加足够的交易费以确保交易在平均n个数据块内被确认 (默认: %u) </translation> </message> @@ -3087,10 +3237,6 @@ <translation>Maximum size of data in data carrier transactions we relay and mine (default: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>修剪被配置为比最小值 %d MB 更低。请使用更大的数字。</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>通过DNS查询每个地址,如果短地址 (默认值: 1 除非 -连接)</translation> </message> @@ -3115,38 +3261,6 @@ <translation>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</translation> </message> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>要使用 bitcoind 或者 bitcoin-qt 中的 -server 选项,您必须在配置文件中设置一个密码: -%s -建议您使用下列随机密码: -rpcuser=bitcoinrpc -rpcpassword=%s -(您不需要记住这个密码) -用户名和密码不能相同。 -如果该文件不存在,创建一个文件并设置权限为仅创建者可读。 -此外,还建议您设置 alertnotify 以便您能注意到问题: -例如 alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>警告:-maxtxfee 设置的太高了!每进行一笔交易时您都要花费这么多费用。</translation> - </message> - <message> - <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> - <translation>警告:请检查电脑的日期时间设置是否正确!时间错误可能会导致比特币客户端运行异常。</translation> - </message> - <message> <source>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 banned ,且转发所有来自他们的交易(即便这些交易已经存在于mempool中),常用于网关 </translation> </message> @@ -3167,18 +3281,10 @@ rpcpassword=%s <translation>正在激活最佳数据链...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>不能在修剪模式下运行一个钱包。</translation> - </message> - <message> <source>Cannot resolve -whitebind address: '%s'</source> <translation>无法解析 -whitebind 地址: '%s'</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>在启动时选择数据目录(默认:0)</translation> - </message> - <message> <source>Connect through SOCKS5 proxy</source> <translation>通过 SOCKS5 代理连接</translation> </message> @@ -3187,10 +3293,6 @@ rpcpassword=%s <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错误:需要新版的比特币核心钱包</translation> </message> @@ -3199,14 +3301,6 @@ rpcpassword=%s <translation>读取数据库出错,关闭中。</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/kb) (默认: %s) </translation> - </message> - <message> <source>Information</source> <translation>信息</translation> </message> @@ -3235,6 +3329,10 @@ rpcpassword=%s <translation>-whitelist: '%s' 指定的网络掩码无效</translation> </message> <message> + <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> <translation>-whitebind: '%s' 需要指定一个端口</translation> </message> @@ -3243,18 +3341,10 @@ rpcpassword=%s <translation>节点中继选项:</translation> </message> <message> - <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>RPC support for HTTP persistent connections (default: %d)</source> - <translation>RPC 支持 HTTP 持久连接 (默认: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>启动时重新为当前的 blk000??.dat 文件建立索引</translation> </message> @@ -3263,6 +3353,10 @@ rpcpassword=%s <translation>收到并且显示P2P网络的告警(默认:%u)</translation> </message> <message> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>重新扫描区块链以查找遗漏的钱包交易</translation> + </message> + <message> <source>Send trace/debug info to console instead of debug.log file</source> <translation>跟踪/调试信息输出到控制台,不输出到 debug.log 文件</translation> </message> @@ -3271,22 +3365,10 @@ rpcpassword=%s <translation>发送时尽可能 不支付交易费用 (默认: %u) </translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>设置SSL根证书的付款请求(默认:-系统-)</translation> - </message> - <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>设置语言, 例如“zh-TW”(默认为系统语言)</translation> - </message> - <message> <source>Show all debugging options (usage: --help -help-debug)</source> <translation>显示所有调试选项 (用法: --帮助 -帮助调试)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>启动时显示版权页 (缺省: 1)</translation> - </message> - <message> <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source> <translation>客户端启动时压缩debug.log文件(缺省:no-debug模式时为1)</translation> </message> @@ -3295,11 +3377,6 @@ rpcpassword=%s <translation>签署交易失败</translation> </message> <message> - <source>Start minimized</source> - <translation>启动时最小化 -</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>交易金额太小,不足以支付交易费</translation> </message> @@ -3324,16 +3401,12 @@ rpcpassword=%s <translation>交易太大</translation> </message> <message> - <source>UI Options:</source> - <translation>界面选项:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>无法在此计算机上绑定 %s (绑定返回错误 %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>使用UPnp映射监听端口(缺省: 监听状态设为1)</translation> + <source>Upgrade wallet to latest format on startup</source> + <translation>程序启动时升级钱包到最新格式</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3348,20 +3421,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> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>是否用块方进行 (%u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> <translation>Zapping all transactions from wallet...</translation> </message> <message> - <source>on startup</source> - <translation>启动中</translation> + <source>ZeroMQ notification options:</source> + <translation>ZeroMQ 通知选项:</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3377,18 +3446,6 @@ rpcpassword=%s <translation>当最佳数据块变化时执行命令 (命令行中的 %s 会被替换成数据块哈希值)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>将钱包升级到最新的格式</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>重新扫描区块链以查找遗漏的钱包交易</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>为 JSON-RPC 连接使用 OpenSSL (https) 连接</translation> - </message> - <message> <source>This help message</source> <translation>本帮助信息 </translation> @@ -3426,6 +3483,10 @@ rpcpassword=%s <translation>输出调试信息 (默认: %u, 提供 <category> 是可选项)</translation> </message> <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>尝试保持上传带宽低于(MiB/24h),0=无限制(默认:%d)</translation> + </message> + <message> <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> <translation>通过Tor隐藏服务连接节点时 使用不同的SOCKS5代理 (默认: %s)</translation> </message> @@ -3434,8 +3495,8 @@ rpcpassword=%s <translation>(默认: %s) </translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>可接受的密码算法 (默认: %s) </translation> + <source>Always query for peer addresses via DNS lookup (default: %u)</source> + <translation>始终通过 DNS 查询节点地址 (默认: %u)</translation> </message> <message> <source>Error loading wallet.dat</source> @@ -3494,14 +3555,6 @@ rpcpassword=%s <translation>是否转发 非P2SH格式的多签名交易 (默认: %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> diff --git a/src/qt/locale/bitcoin_zh_HK.ts b/src/qt/locale/bitcoin_zh_HK.ts deleted file mode 100644 index 7062377f45..0000000000 --- a/src/qt/locale/bitcoin_zh_HK.ts +++ /dev/null @@ -1,110 +0,0 @@ -<TS language="zh_HK" version="2.0"> -<context> - <name>AddressBookPage</name> - </context> -<context> - <name>AddressTableModel</name> - </context> -<context> - <name>AskPassphraseDialog</name> - </context> -<context> - <name>BitcoinGUI</name> - </context> -<context> - <name>ClientModel</name> - </context> -<context> - <name>CoinControlDialog</name> - </context> -<context> - <name>EditAddressDialog</name> - </context> -<context> - <name>FreespaceChecker</name> - </context> -<context> - <name>HelpMessageDialog</name> - </context> -<context> - <name>Intro</name> - </context> -<context> - <name>OpenURIDialog</name> - </context> -<context> - <name>OptionsDialog</name> - </context> -<context> - <name>OverviewPage</name> - </context> -<context> - <name>PaymentServer</name> - </context> -<context> - <name>PeerTableModel</name> - </context> -<context> - <name>QObject</name> - </context> -<context> - <name>QRImageWidget</name> - </context> -<context> - <name>RPCConsole</name> - </context> -<context> - <name>ReceiveCoinsDialog</name> - </context> -<context> - <name>ReceiveRequestDialog</name> - </context> -<context> - <name>RecentRequestsTableModel</name> - </context> -<context> - <name>SendCoinsDialog</name> - </context> -<context> - <name>SendCoinsEntry</name> - </context> -<context> - <name>ShutdownWindow</name> - </context> -<context> - <name>SignVerifyMessageDialog</name> - </context> -<context> - <name>SplashScreen</name> - </context> -<context> - <name>TrafficGraphWidget</name> - </context> -<context> - <name>TransactionDesc</name> - </context> -<context> - <name>TransactionDescDialog</name> - </context> -<context> - <name>TransactionTableModel</name> - </context> -<context> - <name>TransactionView</name> - </context> -<context> - <name>UnitDisplayStatusBarControl</name> - </context> -<context> - <name>WalletFrame</name> - </context> -<context> - <name>WalletModel</name> - </context> -<context> - <name>WalletView</name> - </context> -<context> - <name>bitcoin-core</name> - </context> -</TS>
\ No newline at end of file diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index 9a93d896fe..4026095928 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.0"> +<TS language="zh_TW" version="2.1"> <context> <name>AddressBookPage</name> <message> @@ -221,6 +221,17 @@ </message> </context> <context> + <name>BanTableModel</name> + <message> + <source>IP/Netmask</source> + <translation>網路位址/遮罩</translation> + </message> + <message> + <source>Banned Until</source> + <translation>禁止期限</translation> + </message> +</context> +<context> <name>BitcoinGUI</name> <message> <source>Sign &message...</source> @@ -340,11 +351,11 @@ </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> @@ -392,7 +403,7 @@ </message> <message> <source>Request payments (generates QR codes and bitcoin: URIs)</source> - <translation>要求付款(產生 QR Code 和位元幣付款協議的 URI)</translation> + <translation>要求付款(產生 QR Code 和位元幣付款協議的資源識別碼: URI)</translation> </message> <message> <source>&About Bitcoin Core</source> @@ -412,7 +423,7 @@ </message> <message> <source>Open a bitcoin: URI or payment request</source> - <translation>開啓 bitcoin 協議的 URI 或付款要求</translation> + <translation>開啓 bitcoin 協議的資源識別碼(URI)或付款要求</translation> </message> <message> <source>&Command-line options</source> @@ -871,6 +882,34 @@ <source>command-line options</source> <translation>命令列選項</translation> </message> + <message> + <source>UI Options:</source> + <translation>使用介面選項:</translation> + </message> + <message> + <source>Choose data directory on startup (default: %u)</source> + <translation>啓動時選擇資料目錄(預設值: %u)</translation> + </message> + <message> + <source>Set language, for example "de_DE" (default: system locale)</source> + <translation>設定語言,比如說 de_DE (預設值: 系統語系)</translation> + </message> + <message> + <source>Start minimized</source> + <translation>啓動時縮到最小</translation> + </message> + <message> + <source>Set SSL root certificates for payment request (default: -system-)</source> + <translation>設定付款請求時所使用的 SSL 根憑證(預設值: 系統憑證庫)</translation> + </message> + <message> + <source>Show splash screen on startup (default: %u)</source> + <translation>顯示啓動畫面(預設值: %u)</translation> + </message> + <message> + <source>Reset all settings changes made over the GUI</source> + <translation>重置所有在使用界面更改的設定</translation> + </message> </context> <context> <name>Intro</name> @@ -896,7 +935,7 @@ </message> <message> <source>Use a custom data directory:</source> - <translation>使用自定的資料目錄:</translation> + <translation>使用自訂的資料目錄:</translation> </message> <message> <source>Bitcoin Core</source> @@ -986,7 +1025,7 @@ </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> + <translation>在交易頁籤的情境選單出現的第三方網址連結(URL),比如說區塊探索網站。網址中的 %s 會被取代為交易的雜湊值。可以用直線符號 | 來分隔多個連結。</translation> </message> <message> <source>Third party transaction URLs</source> @@ -1069,6 +1108,34 @@ <translation>代理伺服器的通訊埠(像是 9050)</translation> </message> <message> + <source>Used for reaching peers via:</source> + <translation>用來跟其他節點聯絡的中介:</translation> + </message> + <message> + <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> + <translation>如果對這種網路類型,有指定用來跟其他節點聯絡的 SOCKS5 代理伺服器的話,就會顯示在這裡。</translation> + </message> + <message> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> + <source>Tor</source> + <translation>Tor</translation> + </message> + <message> + <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source> + <translation>透過另外的 SOCKS5 代理伺服器來連線到位元幣網路中的 Tor 隱藏服務。</translation> + </message> + <message> + <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source> + <translation>用另外的 SOCKS5 代理伺服器,來透過 Tor 隱藏服務跟其他節點聯絡:</translation> + </message> + <message> <source>&Window</source> <translation>視窗</translation> </message> @@ -1252,11 +1319,11 @@ </message> <message> <source>Payment request fetch URL is invalid: %1</source> - <translation>取得付款要求的 URL 無效: %1</translation> + <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 位址!可能是因為位元幣位址無效,或是 URI 參數格式錯誤。</translation> + <translation>沒辦法解析資源識別碼(URI)!可能是因為位元幣位址無效,或是 URI 參數格式錯誤。</translation> </message> <message> <source>Payment request file handling</source> @@ -1287,10 +1354,6 @@ <translation>付款要求 %1 過大 (%2 位元組, 上限 %3 位元組).</translation> </message> <message> - <source>Payment request DoS protection</source> - <translation>支付請求的分佈式阻斷服務攻擊DoS保護</translation> - </message> - <message> <source>Error communicating with %1: %2</source> <translation>跟 %1 通訊時發生錯誤: %2</translation> </message> @@ -1443,26 +1506,46 @@ <translation>目前區塊數</translation> </message> <message> + <source>Memory Pool</source> + <translation>記憶體暫存池</translation> + </message> + <message> + <source>Current number of transactions</source> + <translation>目前交易數目</translation> + </message> + <message> + <source>Memory usage</source> + <translation>記憶體使用量</translation> + </message> + <message> <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source> <translation>從目前的資料目錄下開啓位元幣核心的除錯紀錄檔。當紀錄檔很大時,可能會花好幾秒的時間。</translation> </message> <message> <source>Received</source> - <translation>收款</translation> + <translation>收到</translation> </message> <message> <source>Sent</source> - <translation>付款</translation> + <translation>送出</translation> </message> <message> <source>&Peers</source> <translation>節點</translation> </message> <message> + <source>Banned peers</source> + <translation>被禁節點</translation> + </message> + <message> <source>Select a peer to view detailed information.</source> <translation>選一個節點來看詳細資訊</translation> </message> <message> + <source>Whitelisted</source> + <translation>列在白名單</translation> + </message> + <message> <source>Direction</source> <translation>方向</translation> </message> @@ -1471,20 +1554,24 @@ <translation>版本</translation> </message> <message> - <source>User Agent</source> - <translation>使用者代理</translation> + <source>Starting Block</source> + <translation>起始區塊</translation> </message> <message> - <source>Services</source> - <translation>服務</translation> + <source>Synced Headers</source> + <translation>已同步前導資料</translation> + </message> + <message> + <source>Synced Blocks</source> + <translation>已同步區塊</translation> </message> <message> - <source>Starting Height</source> - <translation>起始高度</translation> + <source>User Agent</source> + <translation>使用者代理</translation> </message> <message> - <source>Sync Height</source> - <translation>同步高度</translation> + <source>Services</source> + <translation>服務</translation> </message> <message> <source>Ban Score</source> @@ -1503,16 +1590,16 @@ <translation>最近收到</translation> </message> <message> - <source>Bytes Sent</source> - <translation>送出位元組</translation> + <source>Ping Time</source> + <translation>Ping 時間</translation> </message> <message> - <source>Bytes Received</source> - <translation>收到位元組</translation> + <source>The duration of a currently outstanding ping.</source> + <translation>目前這一次 ping 已經過去的時間。</translation> </message> <message> - <source>Ping Time</source> - <translation>Ping 時間</translation> + <source>Ping Wait</source> + <translation>Ping 等待時間</translation> </message> <message> <source>Time Offset</source> @@ -1544,11 +1631,11 @@ </message> <message> <source>In:</source> - <translation>輸入:</translation> + <translation>來:</translation> </message> <message> <source>Out:</source> - <translation>輸出:</translation> + <translation>去:</translation> </message> <message> <source>Build date</source> @@ -1563,6 +1650,34 @@ <translation>清主控台</translation> </message> <message> + <source>&Disconnect Node</source> + <translation>跟節點斷線</translation> + </message> + <message> + <source>Ban Node for</source> + <translation>禁止節點連線:</translation> + </message> + <message> + <source>1 &hour</source> + <translation>1 小時</translation> + </message> + <message> + <source>1 &day</source> + <translation>1 天</translation> + </message> + <message> + <source>1 &week</source> + <translation>1 星期</translation> + </message> + <message> + <source>1 &year</source> + <translation>1 年</translation> + </message> + <message> + <source>&Unban Node</source> + <translation>解禁解點連線</translation> + </message> + <message> <source>Welcome to the Bitcoin Core RPC console.</source> <translation>歡迎使用位元幣核心 RPC 主控台。</translation> </message> @@ -1591,6 +1706,10 @@ <translation>%1 GB (十億位元組)</translation> </message> <message> + <source>(node id: %1)</source> + <translation>(節點識別碼: %1)</translation> + </message> + <message> <source>via %1</source> <translation>經由 %1</translation> </message> @@ -1607,12 +1726,16 @@ <translation>出去</translation> </message> <message> - <source>Unknown</source> - <translation>不明</translation> + <source>Yes</source> + <translation>是</translation> + </message> + <message> + <source>No</source> + <translation>否</translation> </message> <message> - <source>Fetching...</source> - <translation>正在擷取中...</translation> + <source>Unknown</source> + <translation>不明</translation> </message> </context> <context> @@ -1840,7 +1963,7 @@ </message> <message> <source>Custom change address</source> - <translation>自定找零位址</translation> + <translation>自訂找零位址</translation> </message> <message> <source>Transaction Fee:</source> @@ -1979,8 +2102,8 @@ <translation>複製找零金額</translation> </message> <message> - <source>Total Amount %1 (= %2)</source> - <translation>總金額 %1 (= %2)</translation> + <source>Total Amount %1</source> + <translation>總金額 %1</translation> </message> <message> <source>or</source> @@ -2015,8 +2138,12 @@ <translation>付款的要求過期了。</translation> </message> <message> - <source>Pay only the minimum fee of %1</source> - <translation>只付最低手續費 %1</translation> + <source>Pay only the required fee of %1</source> + <translation>只付必要的手續費 %1</translation> + </message> + <message numerus="yes"> + <source>Estimated to begin confirmation within %n block(s).</source> + <translation><numerusform>預計可在 %n 個區塊內開始確認。</numerusform></translation> </message> <message> <source>The recipient address is not valid. Please recheck.</source> @@ -2111,11 +2238,11 @@ </message> <message> <source>This is an unauthenticated payment request.</source> - <translation>這是個沒驗證過的付款要求。</translation> + <translation>這是個沒有驗證過身份的付款要求。</translation> </message> <message> <source>This is an authenticated payment request.</source> - <translation>這是個已驗證的付款要求。</translation> + <translation>這是個已經驗證過身份的付款要求。</translation> </message> <message> <source>Enter a label for this address to add it to the list of used addresses</source> @@ -2123,7 +2250,7 @@ </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> + <translation>附加在位元幣付款協議的資源識別碼(URI)中的訊息,會和交易內容一起存起來,給你自己做參考。注意: 這個訊息不會送到位元幣網路上。</translation> </message> <message> <source>Pay To:</source> @@ -2138,7 +2265,7 @@ <name>ShutdownWindow</name> <message> <source>Bitcoin Core is shutting down...</source> - <translation>位元幣核心正在關閉中...</translation> + <translation>正在關閉位元幣核心中...</translation> </message> <message> <source>Do not shut down the computer until this window disappears.</source> @@ -2650,6 +2777,10 @@ <translation>複製交易識別碼</translation> </message> <message> + <source>Copy raw transaction</source> + <translation>複製交易原始資料</translation> + </message> + <message> <source>Edit label</source> <translation>編輯標記</translation> </message> @@ -2798,12 +2929,52 @@ </translation> </message> <message> + <source>If <category> is not supplied or if <category> = 1, output all debugging information.</source> + <translation>如果沒有提供 <category> 或是值為 1 就會輸出所有的除錯資訊。</translation> + </message> + <message> + <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> + <translation>一次錢包交易允許付出最高的總手續費(單位是 %s);設定太低的話,可能會無法進行資料量大的交易(預設值: %s)</translation> + </message> + <message> + <source>Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> + <translation>請檢查電腦日期和時間是否正確!位元幣核心沒辦法在時鐘不準的情況下正常運作。</translation> + </message> + <message> + <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source> + <translation>設定的修剪值小於最小需求的 %d 百萬位元組(MiB)。請指定大一點的數字。</translation> + </message> + <message> + <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> + <translation>修剪模式:錢包的最後同步狀態是在被修剪掉的區塊資料中。你需要用 -reindex 參數執行(會重新下載整個區塊鏈)</translation> + </message> + <message> + <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> + <translation>修剪(刪除)掉老舊區塊來減少需要的儲存空間。這種模式會關閉錢包功能,並且和 -txindex 及 -rescan 參數不相容。警告: 從這種模式還原會需要重新下載一整個區塊鏈。(預設值: 0 表示不修剪區塊,>%u 表示為區塊檔案的目標大小,單位是百萬位元組 MiB)</translation> + </message> + <message> + <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source> + <translation>在修剪模式下沒辦法重新掃描區塊鏈。你需要配合使用 -reindex 參數來重新下載整個區塊鏈。</translation> + </message> + <message> + <source>Error: A fatal internal error occurred, see debug.log for details</source> + <translation>錯誤: 發生了致命的內部錯誤,詳情請看 debug.log</translation> + </message> + <message> + <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source> + <translation>交易付款時每千位元組(kB)的交易手續費(單位是 %s,預設值: %s)</translation> + </message> + <message> + <source>Pruning blockstore...</source> + <translation>正在修剪區塊資料庫中...</translation> + </message> + <message> <source>Run in the background as a daemon and accept commands</source> <translation>用護靈模式在背後執行並接受指令</translation> </message> <message> - <source>Use the test network</source> - <translation>使用測試網路</translation> + <source>Unable to start HTTP server. See debug log for details.</source> + <translation>無法啟動 HTTP 伺服器。詳情請看除錯紀錄。</translation> </message> <message> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> @@ -2826,18 +2997,14 @@ <translation>當錢包有交易改變時要執行的指令(指令中的 %s 會被取代成交易識別碼)</translation> </message> <message> - <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source> - <translation>一次錢包交易允許付出最高的總手續費;設定太低的話,可能會無法進行資料量大的交易(預設值: %s)</translation> - </message> - <message> - <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)</source> - <translation>修剪(刪除)掉老舊區塊來減少儲存空間的需求。這種模式會關閉錢包功能,並且和 -txindex 參數不相容。警告: 從這種模式還原會需要重新下載一整個區塊鏈。(預設值: 0 表示不修剪區塊,>%u 表示為區塊檔案的目標大小,單位是百萬位元組 MiB)</translation> - </message> - <message> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation>設定指令碼驗證的執行緒數目 (%u 到 %d,0 表示程式自動決定,小於 0 表示保留處理器核心不用的數目,預設值: %d)</translation> </message> <message> + <source>The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> + <translation>區塊資料庫中有來自未來的區塊。可能是你電腦的日期時間不對。如果確定電腦日期時間沒錯的話,就重建區塊資料庫看看。</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> @@ -2846,6 +3013,10 @@ <translation>沒辦法繫結在這台電腦上的 %s 。位元幣核心可能已經在執行了。</translation> </message> <message> + <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source> + <translation>是否要使用「通用即插即用」協定(UPnP),來設定聽候連線的通訊埠的對應(預設值: 當有聽候連線且沒有指定 -proxy 參數時為 1)</translation> + </message> + <message> <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source> <translation>警告: 收到了不尋常地多的 %d 個區塊在過去 %d 小時內生產出來(預期是 %d 個)</translation> </message> @@ -2854,10 +3025,6 @@ <translation>警告: 請檢查你的網路連線狀況,收到了 %d 個區塊是在過去 %d 小時內生產出來(預期是 %d 個)</translation> </message> <message> - <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source> - <translation>警告: -paytxfee 設定了很高的金額!這可是你交易付款所要付的手續費。</translation> - </message> - <message> <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source> <translation>警告: 位元幣網路對於區塊鏈結的決定目前有分歧!看來有些礦工會有問題。</translation> </message> @@ -2866,10 +3033,6 @@ <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> - <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 會改儲存在 %s, 檔名是 wallet.{timestamp}.bak. 如果餘額或交易資料有誤,你應該要用備份資料復原回來。</translation> </message> @@ -2878,18 +3041,14 @@ <translation>把來自指定網域或位址的節點放進白名單。這個選項可以設定多次。</translation> </message> <message> - <source>(default: 1)</source> - <translation>(預設值: 1)</translation> + <source>-maxmempool must be at least %d MB</source> + <translation>參數 -maxmempool 至少要給 %d 百萬位元組(MB)</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> - <message> <source>Block creation options:</source> <translation>區塊製造選項:</translation> </message> @@ -2918,6 +3077,22 @@ <translation>你想要現在重建區塊資料庫嗎?</translation> </message> <message> + <source>Enable publish hash block in <address></source> + <translation>開啟傳送區塊雜湊值到目標 ZeroMQ 位址 <address> 去</translation> + </message> + <message> + <source>Enable publish hash transaction in <address></source> + <translation>開啟傳送交易雜湊值到目標 ZeroMQ 位址 <address> 去</translation> + </message> + <message> + <source>Enable publish raw block in <address></source> + <translation>開啟傳送區塊原始資料到目標 ZeroMQ 位址 <address> 去</translation> + </message> + <message> + <source>Enable publish raw transaction in <address></source> + <translation>開啟傳送交易原始資料到目標 ZeroMQ 位址 <address> 去</translation> + </message> + <message> <source>Error initializing block database</source> <translation>初始化區塊資料庫時發生錯誤</translation> </message> @@ -2934,10 +3109,6 @@ <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> @@ -2946,10 +3117,6 @@ <translation>在任意的通訊埠聽候失敗。如果你希望這樣的話,可以設定 -listen=0.</translation> </message> <message> - <source>If <category> is not supplied, output all debugging information.</source> - <translation>如果沒有提供 <category> 就會輸出所有的除錯資訊。</translation> - </message> - <message> <source>Importing...</source> <translation>正在匯入中...</translation> </message> @@ -2962,12 +3129,16 @@ <translation>無效的 -onion 位址: '%s'</translation> </message> <message> + <source>Keep the transaction memory pool below <n> megabytes (default: %u)</source> + <translation>在記憶體暫存池中保持最多 <n> 個百萬位元組的交易(預設值: %u)</translation> + </message> + <message> <source>Not enough file descriptors available.</source> <translation>檔案描述元不足。</translation> </message> <message> <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source> - <translation>只有連接到網絡節點 <net> (IPv4,IPv6或onion)</translation> + <translation>只和 <net> 網路上的節點連線(ipv4, ipv6, 或 onion)</translation> </message> <message> <source>Prune cannot be configured with a negative value.</source> @@ -2990,6 +3161,26 @@ <translation>指定錢包檔(會在資料目錄中)</translation> </message> <message> + <source>Unsupported argument -benchmark ignored, use -debug=bench.</source> + <translation>忽略了不再支援的 -benchmark 參數,請改用 -debug=bench</translation> + </message> + <message> + <source>Unsupported argument -debugnet ignored, use -debug=net.</source> + <translation>忽略了不再支援的 -debugnet 參數,請改用 -debug=net</translation> + </message> + <message> + <source>Unsupported argument -tor found, use -onion.</source> + <translation>找到不再支援的 -tor 參數,請改用 -onion 參數。</translation> + </message> + <message> + <source>Use UPnP to map the listening port (default: %u)</source> + <translation>使用通用隨插即用 (UPnP) 協定來設定對應的服務連接埠(預設值: %u)</translation> + </message> + <message> + <source>User Agent comment (%s) contains unsafe characters.</source> + <translation>使用者代理註解(%s)中含有不安全的字元。</translation> + </message> + <message> <source>Verifying blocks...</source> <translation>正在驗證區塊資料...</translation> </message> @@ -3014,18 +3205,10 @@ <translation>改變 -txindex 參數後,必須要用 -reindex 參數來重建資料庫</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> 的有效值可以是一個單獨位址(像是 1.2.3.4),一個網段/網段罩遮值(像是 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>設定在網路上以位址 %s 和通訊埠 %u 聽候 RPC 連線時發生錯誤: %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> @@ -3050,16 +3233,12 @@ <translation>錯誤: 聽候外來連線失敗(回傳錯誤 %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 參數。現在只支援 SOCKS5 協定的代理伺服器了,因為不再能夠指定 SOCKS 協定版本。</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>當處理轉發的交易時,如果每千位元組(Kb)的手續費比這個值低,就視為沒付手續費 (預設值: %s)</translation> + <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)</source> + <translation>當處理轉發的交易、挖礦、或製造交易時,如果每千位元組(kB)的手續費比這個值(單位是 %s)低,就視為沒付手續費(預設值: %s)</translation> </message> <message> <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source> @@ -3074,10 +3253,6 @@ <translation>轉發和開採時,對只帶資料的交易的大小上限(預設值: %u)</translation> </message> <message> - <source>Prune configured below the minimum of %d MB. Please use a higher number.</source> - <translation>設定的修剪值小於最小需求的 %d MB. 請指定大一點的數字。</translation> - </message> - <message> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation>是否允許在節點位址數目不足時,使用域名查詢來搜尋節點 (預設值: 當沒用 -connect 時為 1)</translation> </message> @@ -3102,40 +3277,8 @@ <translation>此產品也包含了由 OpenSSL Project 所開發的 OpenSSL Toolkit 軟體 <https://www.openssl.org/>, 和由 Eric Young 撰寫的加解密軟體,以及由 Thomas Bernard 所撰寫的 UPnP 軟體。</translation> </message> <message> - <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file: -%s -It is recommended you use the following random password: -rpcuser=bitcoinrpc -rpcpassword=%s -(you do not need to remember this password) -The username and password MUST NOT be the same. -If the file does not exist, create it with owner-readable-only file permissions. -It is also recommended to set alertnotify so you are notified of problems; -for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</source> - <translation>要使用 bitcoind, 或是對 bitcoin-qt 指定 -server 選項,你必須要在以下設定檔中設定 RPC 密碼(選項: rpcpassword): -%s -建議你使用以下隨機產生的密碼: -rpcuser=bitcoinrpc -rpcpassword=%s -(你不用記住這個密碼) -注意使用者名稱(rpcuser)和密碼(rpcpassword)不可以相同! -如果設定檔還不存在,請在新增時,設定檔案權限為"只有主人才能讀取"。 -也建議你設定警示通知,這樣發生問題時你才會被通知到; -比如說設定: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com -</translation> - </message> - <message> - <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> - <translation>警告: -maxtxfee 設定了很高的金額!這可是一次交易就有可能付出的最高手續費。</translation> - </message> - <message> - <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source> - <translation>警告: 請檢查電腦日期和時間是否正確!位元幣核心沒辦法在時鐘不準的情況下正常運作。</translation> - </message> - <message> <source>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> + <translation>在白名單中的節點不會因為偵測到阻斷服務攻擊(DoS)而被停用。來自這些節點的交易也一定會被轉發,即使說交易本來就在記憶池裡了也一樣。適用於像是閘道伺服器。</translation> </message> <message> <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> @@ -3154,16 +3297,20 @@ rpcpassword=%s <translation>啟用最佳鏈結...</translation> </message> <message> - <source>Can't run with a wallet in prune mode.</source> - <translation>不能在有錢包時執行修剪模式。</translation> + <source>Always relay transactions received from whitelisted peers (default: %d)</source> + <translation>無條件轉發從白名點節點收到的交易(預設值: %d)</translation> </message> <message> - <source>Cannot resolve -whitebind address: '%s'</source> - <translation>沒辦法解析 -whitebind 指定的位址: '%s'</translation> + <source>Attempt to recover private keys from a corrupt wallet.dat on startup</source> + <translation>啟動時嘗試從壞掉的錢包檔 wallet.dat 復原密鑰</translation> </message> <message> - <source>Choose data directory on startup (default: 0)</source> - <translation>啓動時選擇資料目錄(預設值: 0)</translation> + <source>Automatically create Tor hidden service (default: %d)</source> + <translation>自動產生 Tor 隱藏服務(預設值: %d)</translation> + </message> + <message> + <source>Cannot resolve -whitebind address: '%s'</source> + <translation>沒辦法解析 -whitebind 指定的位址: '%s'</translation> </message> <message> <source>Connect through SOCKS5 proxy</source> @@ -3174,10 +3321,6 @@ rpcpassword=%s <translation>版權為位元幣核心開發人員自西元 2009 至 %i 年起所有</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 檔案時發生錯誤: 這個錢包需要新版的位元幣核心</translation> </message> @@ -3186,12 +3329,8 @@ rpcpassword=%s <translation>讀取資料庫時發生錯誤,要關閉了。</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>交易付款時每千位元組(kB)的交易手續費 (預設值: %s)</translation> + <source>Imports blocks from external blk000??.dat file on startup</source> + <translation>啟動時從其它來源的 blk000??.dat 檔匯入區塊</translation> </message> <message> <source>Information</source> @@ -3234,44 +3373,36 @@ rpcpassword=%s <translation>節點轉發選項:</translation> </message> <message> - <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source> - <translation>RPC SSL 選項: (SSL 設定程序請見 Bitcoin Wiki)</translation> - </message> - <message> <source>RPC server options:</source> <translation>RPC 伺服器選項:</translation> </message> <message> - <source>RPC support for HTTP persistent connections (default: %d)</source> - <translation>RPC 是否支援 HTTP 持久連線(預設值: %d)</translation> - </message> - <message> <source>Rebuild block chain index from current blk000??.dat files on startup</source> <translation>啟動時從目前的區塊檔 blk000??.dat 重建區塊鏈的索引</translation> </message> <message> - <source>Send trace/debug info to console instead of debug.log file</source> - <translation>在終端機顯示追蹤或除錯資訊,而不是寫到檔案 debug.log 中</translation> + <source>Receive and display P2P network alerts (default: %u)</source> + <translation>接收並顯示對等網路(P2P)警示 (預設值: %u)</translation> </message> <message> - <source>Send transactions as zero-fee transactions if possible (default: %u)</source> - <translation>盡可能送出不用付手續費的交易(預設值: %u)</translation> + <source>Reducing -maxconnections from %d to %d, because of system limitations.</source> + <translation>因為系統的限制,將 -maxconnections 參數從 %d 降到了 %d</translation> </message> <message> - <source>Set SSL root certificates for payment request (default: -system-)</source> - <translation>設定付款請求時所使用的 SSL 根憑證 (預設值: 系統憑證庫)</translation> + <source>Rescan the block chain for missing wallet transactions on startup</source> + <translation>啟動時重新掃描區塊鏈,來尋找錢包可能漏掉的交易。</translation> </message> <message> - <source>Set language, for example "de_DE" (default: system locale)</source> - <translation>設定語言,比如說 de_DE (預設值: 系統語系)</translation> + <source>Send trace/debug info to console instead of debug.log file</source> + <translation>在終端機顯示追蹤或除錯資訊,而不是寫到檔案 debug.log 中</translation> </message> <message> - <source>Show all debugging options (usage: --help -help-debug)</source> - <translation>顯示所有的除錯選項 (用法: --help --help-debug)</translation> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation>盡可能送出不用付手續費的交易(預設值: %u)</translation> </message> <message> - <source>Show splash screen on startup (default: 1)</source> - <translation>顯示啓動畫面(預設值: 1)</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> @@ -3282,10 +3413,6 @@ rpcpassword=%s <translation>簽署交易失敗</translation> </message> <message> - <source>Start minimized</source> - <translation>啓動時縮到最小</translation> - </message> - <message> <source>The transaction amount is too small to pay the fee</source> <translation>交易金額太少而付不起手續費</translation> </message> @@ -3294,6 +3421,14 @@ rpcpassword=%s <translation>這套軟體屬於實驗性質。</translation> </message> <message> + <source>Tor control port password (default: empty)</source> + <translation>Tor 控制埠密碼(預設值: 空白)</translation> + </message> + <message> + <source>Tor control port to use if onion listening enabled (default: %s)</source> + <translation>開啟聽候 onion 連線時的 Tor 控制埠號碼(預設值: %s)</translation> + </message> + <message> <source>Transaction amount too small</source> <translation>交易金額太小</translation> </message> @@ -3310,16 +3445,12 @@ rpcpassword=%s <translation>交易位元量太大</translation> </message> <message> - <source>UI Options:</source> - <translation>使用介面選項:</translation> - </message> - <message> <source>Unable to bind to %s on this computer (bind returned error %s)</source> <translation>無法和這台電腦上的 %s 繫結(回傳錯誤 %s)</translation> </message> <message> - <source>Use UPnP to map the listening port (default: 1 when listening)</source> - <translation>是否要使用「通用即插即用」協定(UPnP),來設定聽候連線的通訊埠的對應(預設值: 當有聽候連線時為 1)</translation> + <source>Upgrade wallet to latest format on startup</source> + <translation>啟動時把錢包檔案升級成最新的格式</translation> </message> <message> <source>Username for JSON-RPC connections</source> @@ -3334,20 +3465,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> + <source>Whether to operate in a blocks only mode (default: %u)</source> + <translation>是否要用只要區塊模式運作(預設值: %u)</translation> </message> <message> <source>Zapping all transactions from wallet...</source> <translation>正在砍掉錢包中的所有交易...</translation> </message> <message> - <source>on startup</source> - <translation>當啟動時</translation> + <source>ZeroMQ notification options:</source> + <translation>ZeroMQ 通知選項:</translation> </message> <message> <source>wallet.dat corrupt, salvage failed</source> @@ -3362,18 +3489,6 @@ rpcpassword=%s <translation>當最新區塊改變時要執行的指令(指令中的 %s 會被取代成區塊雜湊值)</translation> </message> <message> - <source>Upgrade wallet to latest format</source> - <translation>把錢包檔案升級成最新的格式</translation> - </message> - <message> - <source>Rescan the block chain for missing wallet transactions</source> - <translation>重新掃描區塊鏈,來尋找錢包可能漏掉的交易。</translation> - </message> - <message> - <source>Use OpenSSL (https) for JSON-RPC connections</source> - <translation>在 JSON-RPC 連線使用 OpenSSL (https)</translation> - </message> - <message> <source>This help message</source> <translation>這些說明訊息</translation> </message> @@ -3394,6 +3509,26 @@ rpcpassword=%s <translation>(1 表示保留交易描述資料,像是帳戶使用者和付款請求資訊;2 表示丟掉交易描述資料)</translation> </message> <message> + <source>-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> + <translation>參數 -maxtxfee 設定了很高的金額!這可是你一次交易就有可能付出的最高手續費。</translation> + </message> + <message> + <source>-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>Do not keep transactions in the mempool longer than <n> hours (default: %u)</source> + <translation>不要讓交易留在記憶池中超過 <n> 個小時(預設值: %u)</translation> + </message> + <message> + <source>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> + <message> + <source>Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)</source> + <translation>當製造交易時,如果每千位元組(kB)的手續費比這個值(單位是 %s)低,就視為沒付手續費(預設值: %s)</translation> + </message> + <message> <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source> <translation>使用 -checkblocks 檢查區塊的仔細程度(0 到 4,預設值: %u)</translation> </message> @@ -3410,16 +3545,32 @@ rpcpassword=%s <translation>輸出除錯資訊(預設值: %u, 不一定要指定 <category>)</translation> </message> <message> + <source>Support filtering of blocks and transaction with bloom filters (default: %u)</source> + <translation>支援用布倫過濾器來過濾區塊和交易(預設值: %u)</translation> + </message> + <message> + <source>Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> + <translation>網路版本字串的總長度(%i)超過最大長度(%i)了。請減少 uacomment 參數的數目或長度。</translation> + </message> + <message> + <source>Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)</source> + <translation>試著保持輸出流量在目標值以下,單位是每 24 小時的百萬位元組(MiB)數,0 表示沒有限制(預設值: %d)</translation> + </message> + <message> + <source>Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source> + <translation>找到不再支援的 -socks 參數。現在只支援 SOCKS5 協定的代理伺服器,因此不可以指定 SOCKS 協定版本了。</translation> + </message> + <message> <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> - <translation>使用另外的 SOCK5 代理伺服器,來透過 Tor 隱藏服務跟節點聯繫(預設值: %s)</translation> + <translation>使用另外的 SOCK5 代理伺服器,來透過 Tor 隱藏服務跟其他節點聯絡(預設值: %s)</translation> </message> <message> - <source>(default: %s)</source> - <translation>(預設值: %s)</translation> + <source>Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times</source> + <translation>JSON-RPC 連線要用的使用者名稱和雜湊密碼。<userpw> 的格式是:<使用者名稱>:<調味值>$<雜湊值>。在 share/rpcuser 目錄下有一個示範的 python 程式。這個選項可以給很多次。</translation> </message> <message> - <source>Acceptable ciphers (default: %s)</source> - <translation>可以接受的加密演算法(預設值: %s)</translation> + <source>(default: %s)</source> + <translation>(預設值: %s)</translation> </message> <message> <source>Always query for peer addresses via DNS lookup (default: %u)</source> @@ -3482,14 +3633,6 @@ rpcpassword=%s <translation>允許轉發非 P2SH 的多簽章交易(預設值: %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> diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index 8bd867c103..1c28593d4a 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 4541c75886..5f31f49372 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/notificator.h b/src/qt/notificator.h index f2a15e9c34..f92b791d4a 100644 --- a/src/qt/notificator.h +++ b/src/qt/notificator.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/openuridialog.h b/src/qt/openuridialog.h index 28b8f56ca6..e94593d5bb 100644 --- a/src/qt/openuridialog.h +++ b/src/qt/openuridialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index f57c1203f6..ae1c05240e 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -18,7 +18,7 @@ #include "txdb.h" // for -dbcache defaults #ifdef ENABLE_WALLET -#include "wallet/wallet.h" // for CWallet::minTxFee +#include "wallet/wallet.h" // for CWallet::GetRequiredFee() #endif #include <boost/thread.hpp> @@ -34,8 +34,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : QDialog(parent), ui(new Ui::OptionsDialog), model(0), - mapper(0), - fProxyIpsValid(true) + mapper(0) { ui->setupUi(this); @@ -60,12 +59,11 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool))); connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool))); + connect(ui->connectSocks, SIGNAL(toggled(bool)), this, SLOT(updateProxyValidationState())); connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyIpTor, SLOT(setEnabled(bool))); connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyPortTor, SLOT(setEnabled(bool))); - - ui->proxyIp->installEventFilter(this); - ui->proxyIpTor->installEventFilter(this); + connect(ui->connectSocksTor, SIGNAL(toggled(bool)), this, SLOT(updateProxyValidationState())); /* Window elements init */ #ifdef Q_OS_MAC @@ -119,7 +117,12 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : mapper->setOrientation(Qt::Vertical); /* setup/change UI elements when proxy IPs are invalid/valid */ - connect(this, SIGNAL(proxyIpChecks(QValidatedLineEdit *, int)), this, SLOT(doProxyIpChecks(QValidatedLineEdit *, int))); + ui->proxyIp->setCheckValidator(new ProxyAddressValidator(parent)); + ui->proxyIpTor->setCheckValidator(new ProxyAddressValidator(parent)); + connect(ui->proxyIp, SIGNAL(validationDidChange(QValidatedLineEdit *)), this, SLOT(updateProxyValidationState())); + connect(ui->proxyIpTor, SIGNAL(validationDidChange(QValidatedLineEdit *)), this, SLOT(updateProxyValidationState())); + connect(ui->proxyPort, SIGNAL(textChanged(const QString&)), this, SLOT(updateProxyValidationState())); + connect(ui->proxyPortTor, SIGNAL(textChanged(const QString&)), this, SLOT(updateProxyValidationState())); } OptionsDialog::~OptionsDialog() @@ -200,18 +203,6 @@ void OptionsDialog::setMapper() mapper->addMapping(ui->thirdPartyTxUrls, OptionsModel::ThirdPartyTxUrls); } -void OptionsDialog::enableOkButton() -{ - /* prevent enabling of the OK button when data modified, if there is an invalid proxy address present */ - if(fProxyIpsValid) - setOkButtonState(true); -} - -void OptionsDialog::disableOkButton() -{ - setOkButtonState(false); -} - void OptionsDialog::setOkButtonState(bool fState) { ui->okButton->setEnabled(fState); @@ -269,24 +260,20 @@ void OptionsDialog::clearStatusLabel() ui->statusLabel->clear(); } -void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort) +void OptionsDialog::updateProxyValidationState() { - Q_UNUSED(nProxyPort); - - CService addrProxy; - - /* Check for a valid IPv4 / IPv6 address */ - if (!(fProxyIpsValid = LookupNumeric(pUiProxyIp->text().toStdString().c_str(), addrProxy))) + QValidatedLineEdit *pUiProxyIp = ui->proxyIp; + QValidatedLineEdit *otherProxyWidget = (pUiProxyIp == ui->proxyIpTor) ? ui->proxyIp : ui->proxyIpTor; + if (pUiProxyIp->isValid() && (!ui->proxyPort->isEnabled() || ui->proxyPort->text().toInt() > 0) && (!ui->proxyPortTor->isEnabled() || ui->proxyPortTor->text().toInt() > 0)) { - disableOkButton(); - pUiProxyIp->setValid(false); - ui->statusLabel->setStyleSheet("QLabel { color: red; }"); - ui->statusLabel->setText(tr("The supplied proxy address is invalid.")); + setOkButtonState(otherProxyWidget->isValid()); //only enable ok button if both proxys are valid + ui->statusLabel->clear(); } else { - enableOkButton(); - ui->statusLabel->clear(); + setOkButtonState(false); + ui->statusLabel->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel->setText(tr("The supplied proxy address is invalid.")); } } @@ -312,18 +299,18 @@ void OptionsDialog::updateDefaultProxyNets() (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachTor->setChecked(true) : ui->proxyReachTor->setChecked(false); } -bool OptionsDialog::eventFilter(QObject *object, QEvent *event) +ProxyAddressValidator::ProxyAddressValidator(QObject *parent) : +QValidator(parent) { - if(event->type() == QEvent::FocusOut) - { - if(object == ui->proxyIp) - { - Q_EMIT proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt()); - } - else if(object == ui->proxyIpTor) - { - Q_EMIT proxyIpChecks(ui->proxyIpTor, ui->proxyPortTor->text().toInt()); - } - } - return QDialog::eventFilter(object, event); +} + +QValidator::State ProxyAddressValidator::validate(QString &input, int &pos) const +{ + Q_UNUSED(pos); + // Validate the proxy + proxyType addrProxy = proxyType(CService(input.toStdString(), 9050), true); + if (addrProxy.IsValid()) + return QValidator::Acceptable; + + return QValidator::Invalid; } diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index 348489c599..e944fb9ee9 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -6,6 +6,7 @@ #define BITCOIN_QT_OPTIONSDIALOG_H #include <QDialog> +#include <QValidator> class OptionsModel; class QValidatedLineEdit; @@ -18,6 +19,18 @@ namespace Ui { class OptionsDialog; } +/** Proxy address widget validator, checks for a valid proxy address. + */ +class ProxyAddressValidator : public QValidator +{ + Q_OBJECT + +public: + explicit ProxyAddressValidator(QObject *parent); + + State validate(QString &input, int &pos) const; +}; + /** Preferences dialog. */ class OptionsDialog : public QDialog { @@ -30,14 +43,7 @@ public: void setModel(OptionsModel *model); void setMapper(); -protected: - bool eventFilter(QObject *object, QEvent *event); - private Q_SLOTS: - /* enable OK button */ - void enableOkButton(); - /* disable OK button */ - void disableOkButton(); /* set OK button state (enabled / disabled) */ void setOkButtonState(bool fState); void on_resetButton_clicked(); @@ -46,7 +52,7 @@ private Q_SLOTS: void showRestartWarning(bool fPersistent = false); void clearStatusLabel(); - void doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort); + void updateProxyValidationState(); /* query the networks, for which the default proxy is used */ void updateDefaultProxyNets(); @@ -57,7 +63,6 @@ private: Ui::OptionsDialog *ui; OptionsModel *model; QDataWidgetMapper *mapper; - bool fProxyIpsValid; }; #endif // BITCOIN_QT_OPTIONSDIALOG_H diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 65e490570e..d091bb9e61 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -26,10 +26,10 @@ #include <QSettings> #include <QStringList> -OptionsModel::OptionsModel(QObject *parent) : +OptionsModel::OptionsModel(QObject *parent, bool resetSettings) : QAbstractListModel(parent) { - Init(); + Init(resetSettings); } void OptionsModel::addOverriddenOption(const std::string &option) @@ -38,8 +38,11 @@ void OptionsModel::addOverriddenOption(const std::string &option) } // Writes all missing QSettings with their default values -void OptionsModel::Init() +void OptionsModel::Init(bool resetSettings) { + if (resetSettings) + Reset(); + QSettings settings; // Ensure restart flag is unset on client startup diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 8448cad8de..841711dd2d 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -24,7 +24,7 @@ class OptionsModel : public QAbstractListModel Q_OBJECT public: - explicit OptionsModel(QObject *parent = 0); + explicit OptionsModel(QObject *parent = 0, bool resetSettings = false); enum OptionID { StartAtStartup, // bool @@ -48,7 +48,7 @@ public: OptionIDRowCount, }; - void Init(); + void Init(bool resetSettings = false); void Reset(); int rowCount(const QModelIndex & parent = QModelIndex()) const; diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index a56c80ac63..d577345e49 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 4139eb35d3..911443c76a 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 78a783dea4..20e1f79ffa 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -145,7 +145,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c int error = X509_STORE_CTX_get_error(store_ctx); // For testing payment requests, we allow self signed root certs! // This option is just shown in the UI options, if -help-debug is enabled. - if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && GetBoolArg("-allowselfsignedrootcertificates", false))) { + if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && GetBoolArg("-allowselfsignedrootcertificates", DEFAULT_SELFSIGNED_ROOTCERTS))) { throw SSLVerifyError(X509_verify_cert_error_string(error)); } else { qDebug() << "PaymentRequestPlus::getMerchant: Allowing self signed root certificate, because -allowselfsignedrootcertificates is true."; @@ -201,7 +201,7 @@ QList<std::pair<CScript,CAmount> > PaymentRequestPlus::getPayTo() const const unsigned char* scriptStr = (const unsigned char*)details.outputs(i).script().data(); CScript s(scriptStr, scriptStr+details.outputs(i).script().size()); - result.append(make_pair(s, details.outputs(i).amount())); + result.append(std::make_pair(s, details.outputs(i).amount())); } return result; } diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h index 99a7186b85..a73fe5f29d 100644 --- a/src/qt/paymentrequestplus.h +++ b/src/qt/paymentrequestplus.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,6 +15,8 @@ #include <QList> #include <QString> +static const bool DEFAULT_SELFSIGNED_ROOTCERTS = false; + // // Wraps dumb protocol buffer paymentRequest // with extra methods diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 31a6d65a8d..c80aebb009 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index fa120a435c..2d27ed078b 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 770a860544..84ad0052fd 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -85,7 +85,7 @@ public: } if (sortColumn >= 0) - // sort cacheNodeStats (use stable sort to prevent rows jumping around unneceesarily) + // sort cacheNodeStats (use stable sort to prevent rows jumping around unnecessarily) qStableSort(cachedNodeStats.begin(), cachedNodeStats.end(), NodeLessThan(sortColumn, sortOrder)); // build index map @@ -147,7 +147,7 @@ int PeerTableModel::rowCount(const QModelIndex &parent) const int PeerTableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return columns.length();; + return columns.length(); } QVariant PeerTableModel::data(const QModelIndex &index, int role) const diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h index 5f149ea873..a2aaaa5d24 100644 --- a/src/qt/peertablemodel.h +++ b/src/qt/peertablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp index 346369392c..baa2eb67f7 100644 --- a/src/qt/qvalidatedlineedit.cpp +++ b/src/qt/qvalidatedlineedit.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -99,9 +99,25 @@ void QValidatedLineEdit::checkValidity() } else setValid(false); + + Q_EMIT validationDidChange(this); } void QValidatedLineEdit::setCheckValidator(const QValidator *v) { checkValidator = v; } + +bool QValidatedLineEdit::isValid() +{ + // use checkValidator in case the QValidatedLineEdit is disabled + if (checkValidator) + { + QString address = text(); + int pos = 0; + if (checkValidator->validate(address, pos) == QValidator::Acceptable) + return true; + } + + return valid; +} diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h index 8665acda5e..66734cc9d4 100644 --- a/src/qt/qvalidatedlineedit.h +++ b/src/qt/qvalidatedlineedit.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -18,6 +18,7 @@ public: explicit QValidatedLineEdit(QWidget *parent); void clear(); void setCheckValidator(const QValidator *v); + bool isValid(); protected: void focusInEvent(QFocusEvent *evt); @@ -31,6 +32,9 @@ public Q_SLOTS: void setValid(bool valid); void setEnabled(bool enabled); +Q_SIGNALS: + void validationDidChange(QValidatedLineEdit *validatedLineEdit); + private Q_SLOTS: void markValid(); void checkValidity(); diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp index 800436661f..146f3dd578 100644 --- a/src/qt/qvaluecombobox.cpp +++ b/src/qt/qvaluecombobox.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h index 5b20e6a5a4..f266302310 100644 --- a/src/qt/qvaluecombobox.h +++ b/src/qt/qvaluecombobox.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 7fb68cc32a..b1f82023bc 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index eaaf129a91..543854a2f4 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 0c4a20cf92..75108e0a10 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -144,7 +144,7 @@ void ReceiveRequestDialog::update() html += "<a href=\""+uri+"\">" + GUIUtil::HtmlEscape(uri) + "</a><br>"; html += "<b>"+tr("Address")+"</b>: " + GUIUtil::HtmlEscape(info.address) + "<br>"; if(info.amount) - html += "<b>"+tr("Amount")+"</b>: " + BitcoinUnits::formatWithUnit(model->getDisplayUnit(), info.amount) + "<br>"; + html += "<b>"+tr("Amount")+"</b>: " + BitcoinUnits::formatHtmlWithUnit(model->getDisplayUnit(), info.amount) + "<br>"; if(!info.label.isEmpty()) html += "<b>"+tr("Label")+"</b>: " + GUIUtil::HtmlEscape(info.label) + "<br>"; if(!info.message.isEmpty()) diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 69f84ebbd7..4cab4caff1 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 5692a7aaef..ef9422506a 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/recentrequeststablemodel.h b/src/qt/recentrequeststablemodel.h index 64faa72d45..f3cf03f4e3 100644 --- a/src/qt/recentrequeststablemodel.h +++ b/src/qt/recentrequeststablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index f387a3ec8c..7178bc00e6 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -263,7 +263,13 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : connect(ui->btnClearTrafficGraph, SIGNAL(clicked()), ui->trafficGraph, SLOT(clear())); // set library version labels + +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION)); +#else + ui->openSSLVersion->setText(OpenSSL_version(OPENSSL_VERSION)); +#endif + #ifdef ENABLE_WALLET ui->berkeleyDBVersion->setText(DbEnv::version(0, 0, 0)); #else @@ -272,7 +278,9 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : #endif // Register RPC timer interface rpcTimerInterface = new QtRPCTimerInterface(); - RPCRegisterTimerInterface(rpcTimerInterface); + // avoid accidentally overwriting an existing, non QTThread + // based timer interface + RPCSetTimerInterfaceIfUnset(rpcTimerInterface); startExecutor(); setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS); @@ -287,7 +295,7 @@ RPCConsole::~RPCConsole() { GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this); Q_EMIT stopExecutor(); - RPCUnregisterTimerInterface(rpcTimerInterface); + RPCUnsetTimerInterface(rpcTimerInterface); delete rpcTimerInterface; delete ui; } @@ -337,12 +345,14 @@ void RPCConsole::setClientModel(ClientModel *model) setNumConnections(model->getNumConnections()); connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); - setNumBlocks(model->getNumBlocks(), model->getLastBlockDate()); - connect(model, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime))); + setNumBlocks(model->getNumBlocks(), model->getLastBlockDate(), model->getVerificationProgress(NULL)); + connect(model, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(setNumBlocks(int,QDateTime,double))); updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent()); connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64))); + connect(model, SIGNAL(mempoolSizeChanged(long,size_t)), this, SLOT(setMempoolSize(long,size_t))); + // set up peer table ui->peerWidget->setModel(model->getPeerTableModel()); ui->peerWidget->verticalHeader()->hide(); @@ -462,13 +472,19 @@ void RPCConsole::clear() } // Set default style sheet + QFontInfo fixedFontInfo(GUIUtil::fixedPitchFont()); + // Try to make fixed font adequately large on different OS + QString ptSize = QString("%1pt").arg(QFontInfo(QFont()).pointSize() * 8.5 / 9); ui->messagesWidget->document()->setDefaultStyleSheet( + QString( "table { }" "td.time { color: #808080; padding-top: 3px; } " + "td.message { font-family: %1; font-size: %2; white-space:pre-wrap; } " "td.cmd-request { color: #006060; } " "td.cmd-error { color: red; } " "b { color: #006060; } " - ); + ).arg(fixedFontInfo.family(), ptSize) + ); 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>" + @@ -494,7 +510,7 @@ void RPCConsole::message(int category, const QString &message, bool html) if(html) out += message; else - out += GUIUtil::HtmlEscape(message, true); + out += GUIUtil::HtmlEscape(message, false); out += "</td></tr></table>"; ui->messagesWidget->append(out); } @@ -511,12 +527,22 @@ void RPCConsole::setNumConnections(int count) ui->numberOfConnections->setText(connections); } -void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate) +void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress) { ui->numberOfBlocks->setText(QString::number(count)); ui->lastBlockTime->setText(blockDate.toString()); } +void RPCConsole::setMempoolSize(long numberOfTxs, size_t dynUsage) +{ + ui->mempoolNumberTxs->setText(QString::number(numberOfTxs)); + + if (dynUsage < 1000000) + ui->mempoolSize->setText(QString::number(dynUsage/1000.0, 'f', 2) + " KB"); + else + ui->mempoolSize->setText(QString::number(dynUsage/1000000.0, 'f', 2) + " MB"); +} + void RPCConsole::on_lineEdit_returnPressed() { QString cmd = ui->lineEdit->text(); @@ -849,4 +875,9 @@ void RPCConsole::showOrHideBanTableIfRequired() bool visible = clientModel->getBanTableModel()->shouldShow(); ui->banlistWidget->setVisible(visible); ui->banHeading->setVisible(visible); -}
\ No newline at end of file +} + +void RPCConsole::setTabFocus(enum TabTypes tabType) +{ + ui->tabWidget->setCurrentIndex(tabType); +} diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index b86f776786..8a48179c57 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -44,6 +44,13 @@ public: CMD_ERROR }; + enum TabTypes { + TAB_INFO = 0, + TAB_CONSOLE = 1, + TAB_GRAPH = 2, + TAB_PEERS = 3 + }; + protected: virtual bool eventFilter(QObject* obj, QEvent *event); void keyPressEvent(QKeyEvent *); @@ -71,11 +78,14 @@ private Q_SLOTS: public Q_SLOTS: void clear(); + /** Append the message to the message widget */ void message(int category, const QString &message, bool html = false); /** Set number of connections shown in the UI */ void setNumConnections(int count); /** Set number of blocks and last block date shown in the UI */ - void setNumBlocks(int count, const QDateTime& blockDate); + void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress); + /** Set size (number of transactions and memory usage) of the mempool in the UI */ + void setMempoolSize(long numberOfTxs, size_t dynUsage); /** Go forward or back in history */ void browseHistory(int offset); /** Scroll console view to end */ @@ -90,6 +100,8 @@ public Q_SLOTS: void banSelectedNode(int bantime); /** Unban a selected node on the Bans tab */ void unbanSelectedNode(); + /** set which tab has the focus (is visible) */ + void setTabFocus(enum TabTypes tabType); Q_SIGNALS: // For RPC command executor diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index a083a6f80e..c834c3b564 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -124,7 +124,7 @@ void SendCoinsDialog::setClientModel(ClientModel *clientModel) this->clientModel = clientModel; if (clientModel) { - connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(updateSmartFeeLabel())); + connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(updateSmartFeeLabel())); } } @@ -172,7 +172,7 @@ void SendCoinsDialog::setModel(WalletModel *model) 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()); + ui->customFee->setSingleStep(CWallet::GetRequiredFee(1000)); updateFeeSectionControls(); updateMinFeeLabel(); updateSmartFeeLabel(); @@ -312,8 +312,9 @@ void SendCoinsDialog::on_sendButton_clicked() if(u != model->getOptionsModel()->getDisplayUnit()) alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount)); } - questionString.append(tr("Total Amount %1<span style='font-size:10pt;font-weight:normal;'><br />(=%2)</span>") - .arg(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), totalAmount)) + questionString.append(tr("Total Amount %1") + .arg(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), totalAmount))); + questionString.append(QString("<span style='font-size:10pt;font-weight:normal;'><br />(=%2)</span>") .arg(alternativeUnits.join(" " + tr("or") + "<br />"))); QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"), @@ -372,8 +373,6 @@ SendCoinsEntry *SendCoinsDialog::addEntry() connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels())); connect(entry, SIGNAL(subtractFeeFromAmountChanged()), this, SLOT(coinControlUpdateLabels())); - updateTabsAndLabels(); - // Focus the field, so that entry can start immediately entry->clear(); entry->setFocus(); @@ -382,6 +381,8 @@ SendCoinsEntry *SendCoinsDialog::addEntry() QScrollBar* bar = ui->scrollArea->verticalScrollBar(); if(bar) bar->setSliderPosition(bar->maximum()); + + updateTabsAndLabels(); return entry; } @@ -530,7 +531,7 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn msgParams.second = CClientUIInterface::MSG_ERROR; break; case WalletModel::AbsurdFee: - msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000)); + msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), maxTxFee)); break; case WalletModel::PaymentRequestExpired: msgParams.first = tr("Payment request expired."); @@ -569,7 +570,7 @@ void SendCoinsDialog::on_buttonMinimizeFee_clicked() void SendCoinsDialog::setMinimumFee() { ui->radioCustomPerKilobyte->setChecked(true); - ui->customFee->setValue(CWallet::minTxFee.GetFeePerK()); + ui->customFee->setValue(CWallet::GetRequiredFee(1000)); } void SendCoinsDialog::updateFeeSectionControls() @@ -584,7 +585,7 @@ void SendCoinsDialog::updateFeeSectionControls() 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->radioCustomAtLeast ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked() && CoinControlDialog::coinControl->HasSelected()); ui->customFee ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked()); } @@ -599,7 +600,10 @@ void SendCoinsDialog::updateGlobalFeeVariables() { nTxConfirmTarget = defaultConfirmTarget; payTxFee = CFeeRate(ui->customFee->value()); - fPayAtLeastCustomFee = ui->radioCustomAtLeast->isChecked(); + + // if user has selected to set a minimum absolute fee, pass the value to coincontrol + // set nMinimumTotalFee to 0 in case of user has selected that the fee is per KB + CoinControlDialog::coinControl->nMinimumTotalFee = ui->radioCustomAtLeast->isChecked() ? ui->customFee->value() : 0; } fSendFreeTransactions = ui->checkBoxFreeTx->isChecked(); @@ -621,8 +625,8 @@ void SendCoinsDialog::updateFeeMinimizedLabel() 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") + ui->checkBoxMinimumFee->setText(tr("Pay only the required fee of %1").arg( + BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), CWallet::GetRequiredFee(1000)) + "/kB") ); } @@ -632,18 +636,21 @@ void SendCoinsDialog::updateSmartFeeLabel() return; int nBlocksToConfirm = defaultConfirmTarget - ui->sliderSmartFee->value(); - CFeeRate feeRate = mempool.estimateFee(nBlocksToConfirm); + int estimateFoundAtBlocks = nBlocksToConfirm; + CFeeRate feeRate = mempool.estimateSmartFee(nBlocksToConfirm, &estimateFoundAtBlocks); if (feeRate <= CFeeRate(0)) // not enough data => minfee { - ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), CWallet::minTxFee.GetFeePerK()) + "/kB"); + ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), + std::max(CWallet::fallbackFee.GetFeePerK(), CWallet::GetRequiredFee(1000))) + "/kB"); ui->labelSmartFee2->show(); // (Smart fee not initialized yet. This usually takes a few blocks...) ui->labelFeeEstimation->setText(""); } else { - ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB"); + ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), + std::max(feeRate.GetFeePerK(), CWallet::GetRequiredFee(1000))) + "/kB"); ui->labelSmartFee2->hide(); - ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %n block(s).", "", nBlocksToConfirm)); + ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %n block(s).", "", estimateFoundAtBlocks)); } updateFeeMinimizedLabel(); @@ -705,8 +712,7 @@ void SendCoinsDialog::coinControlFeatureChanged(bool checked) if (!checked && model) // coin control features disabled CoinControlDialog::coinControl->SetNull(); - if (checked) - coinControlUpdateLabels(); + coinControlUpdateLabels(); } // Coin Control: button inputs -> show actual coin control dialog @@ -780,8 +786,23 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text) // Coin Control: update labels void SendCoinsDialog::coinControlUpdateLabels() { - if (!model || !model->getOptionsModel() || !model->getOptionsModel()->getCoinControlFeatures()) + if (!model || !model->getOptionsModel()) + return; + + if (model->getOptionsModel()->getCoinControlFeatures()) + { + // enable minium absolute fee UI controls + ui->radioCustomAtLeast->setVisible(true); + + // only enable the feature if inputs are selected + ui->radioCustomAtLeast->setEnabled(CoinControlDialog::coinControl->HasSelected()); + } + else + { + // in case coin control is disabled (=default), hide minimum absolute fee UI controls + ui->radioCustomAtLeast->setVisible(false); return; + } // set pay amounts CoinControlDialog::payAmounts.clear(); @@ -789,7 +810,7 @@ void SendCoinsDialog::coinControlUpdateLabels() for(int i = 0; i < ui->entries->count(); ++i) { SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget()); - if(entry) + if(entry && !entry->isHidden()) { SendCoinsRecipient rcp = entry->getValue(); CoinControlDialog::payAmounts.append(rcp.amount); diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 391905ffcd..ec171734fa 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 44aa8ad1af..d063f2c891 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -40,7 +40,7 @@ SendCoinsEntry::SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *pare // normal bitcoin address field GUIUtil::setupAddressWidget(ui->payTo, this); // just a label for displaying bitcoin address(es) - ui->payTo_is->setFont(GUIUtil::bitcoinAddressFont()); + ui->payTo_is->setFont(GUIUtil::fixedPitchFont()); // Connect signals connect(ui->payAmount, SIGNAL(valueChanged()), this, SIGNAL(payAmountChanged())); diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index 107ab70158..a8be670c2a 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 60e8e36ebe..8e2e8a5098 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -51,8 +51,8 @@ SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *platformSt ui->messageIn_VM->installEventFilter(this); ui->signatureIn_VM->installEventFilter(this); - ui->signatureOut_SM->setFont(GUIUtil::bitcoinAddressFont()); - ui->signatureIn_VM->setFont(GUIUtil::bitcoinAddressFont()); + ui->signatureOut_SM->setFont(GUIUtil::fixedPitchFont()); + ui->signatureIn_VM->setFont(GUIUtil::fixedPitchFont()); } SignVerifyMessageDialog::~SignVerifyMessageDialog() diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h index d651d5049b..d2e04cd4fe 100644 --- a/src/qt/signverifymessagedialog.h +++ b/src/qt/signverifymessagedialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index c15b64c327..9195b3b724 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h index 29d16d4eae..821f39db1c 100644 --- a/src/qt/splashscreen.h +++ b/src/qt/splashscreen.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h index c548ffe429..74a2db8ea2 100644 --- a/src/qt/test/paymentrequestdata.h +++ b/src/qt/test/paymentrequestdata.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index fa5696325d..84ccfea730 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/paymentservertests.h b/src/qt/test/paymentservertests.h index 71d61fcbe7..9ffcbb02ac 100644 --- a/src/qt/test/paymentservertests.h +++ b/src/qt/test/paymentservertests.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index f91de2008c..db193420bf 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/uritests.h b/src/qt/test/uritests.h index 434169dcde..4994842795 100644 --- a/src/qt/test/uritests.h +++ b/src/qt/test/uritests.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index 9b67445bc0..601d554c02 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/trafficgraphwidget.h b/src/qt/trafficgraphwidget.h index 6336a8d144..00660574af 100644 --- a/src/qt/trafficgraphwidget.h +++ b/src/qt/trafficgraphwidget.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 801c6c62d2..5cb4cd5af7 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -35,9 +35,11 @@ QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) { int nDepth = wtx.GetDepthInMainChain(); if (nDepth < 0) - return tr("conflicted"); + return tr("conflicted with a transaction with %1 confirmations").arg(-nDepth); else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) return tr("%1/offline").arg(nDepth); + else if (nDepth == 0) + return tr("0/unconfirmed, %1").arg((wtx.InMempool() ? tr("in memory pool") : tr("not in memory pool"))); else if (nDepth < 6) return tr("%1/unconfirmed").arg(nDepth); else diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index d8623daf5d..5b16b108e6 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 98ad1a44b6..1647b2a6fe 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -13,6 +13,7 @@ #include "transactionrecord.h" #include "walletmodel.h" +#include "core_io.h" #include "main.h" #include "sync.h" #include "uint256.h" @@ -220,6 +221,18 @@ public: } return QString(); } + + QString getTxHex(TransactionRecord *rec) + { + LOCK2(cs_main, wallet->cs_wallet); + std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash); + if(mi != wallet->mapWallet.end()) + { + std::string strHex = EncodeHexTx(static_cast<CTransaction>(mi->second)); + return QString::fromStdString(strHex); + } + return QString(); + } }; TransactionTableModel::TransactionTableModel(const PlatformStyle *platformStyle, CWallet* wallet, WalletModel *parent): @@ -594,6 +607,8 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const return rec->getTxID(); case TxHashRole: return QString::fromStdString(rec->hash.ToString()); + case TxHexRole: + return priv->getTxHex(rec); case ConfirmedRole: return rec->status.countsForBalance; case FormattedAmountRole: diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 2089f703a6..fe59a15f6a 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -60,6 +60,8 @@ public: TxIDRole, /** Transaction hash */ TxHashRole, + /** Transaction data, hex-encoded */ + TxHexRole, /** Is transaction confirmed? */ ConfirmedRole, /** Formatted amount, without brackets when unconfirmed */ diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 54e5a82720..4a9a198216 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -141,6 +141,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa QAction *copyLabelAction = new QAction(tr("Copy label"), this); QAction *copyAmountAction = new QAction(tr("Copy amount"), this); QAction *copyTxIDAction = new QAction(tr("Copy transaction ID"), this); + QAction *copyTxHexAction = new QAction(tr("Copy raw transaction"), this); QAction *editLabelAction = new QAction(tr("Edit label"), this); QAction *showDetailsAction = new QAction(tr("Show transaction details"), this); @@ -149,6 +150,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa contextMenu->addAction(copyLabelAction); contextMenu->addAction(copyAmountAction); contextMenu->addAction(copyTxIDAction); + contextMenu->addAction(copyTxHexAction); contextMenu->addAction(editLabelAction); contextMenu->addAction(showDetailsAction); @@ -170,6 +172,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); connect(copyTxIDAction, SIGNAL(triggered()), this, SLOT(copyTxID())); + connect(copyTxHexAction, SIGNAL(triggered()), this, SLOT(copyTxHex())); connect(editLabelAction, SIGNAL(triggered()), this, SLOT(editLabel())); connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails())); } @@ -264,7 +267,7 @@ void TransactionView::chooseDate(int idx) break; case LastMonth: transactionProxyModel->setDateRange( - QDateTime(QDate(current.year(), current.month()-1, 1)), + QDateTime(QDate(current.year(), current.month(), 1).addMonths(-1)), QDateTime(QDate(current.year(), current.month(), 1))); break; case ThisYear: @@ -380,6 +383,11 @@ void TransactionView::copyTxID() GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxIDRole); } +void TransactionView::copyTxHex() +{ + GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxHexRole); +} + void TransactionView::editLabel() { if(!transactionView->selectionModel() ||!model) diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index ac157fb98d..cf2b8fbcd4 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -93,6 +93,7 @@ private Q_SLOTS: void copyLabel(); void copyAmount(); void copyTxID(); + void copyTxHex(); void openThirdPartyTxUrl(QString url); void updateWatchOnlyColumn(bool fHaveWatchOnly); diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 5e26f3e01b..75ab9c4c3a 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -8,6 +8,9 @@ #include "bitcoingui.h" #include "clientmodel.h" +#include "guiconstants.h" +#include "intro.h" +#include "paymentrequestplus.h" #include "guiutil.h" #include "clientversion.h" @@ -70,7 +73,22 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : cursor.insertText(header); cursor.insertBlock(); - QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT)); + std::string strUsage = HelpMessage(HMM_BITCOIN_QT); + const bool showDebug = GetBoolArg("-help-debug", false); + strUsage += HelpMessageGroup(tr("UI Options:").toStdString()); + if (showDebug) { + strUsage += HelpMessageOpt("-allowselfsignedrootcertificates", strprintf("Allow self signed root certificates (default: %u)", DEFAULT_SELFSIGNED_ROOTCERTS)); + } + strUsage += HelpMessageOpt("-choosedatadir", strprintf(tr("Choose data directory on startup (default: %u)").toStdString(), DEFAULT_CHOOSE_DATADIR)); + strUsage += HelpMessageOpt("-lang=<lang>", tr("Set language, for example \"de_DE\" (default: system locale)").toStdString()); + strUsage += HelpMessageOpt("-min", tr("Start minimized").toStdString()); + strUsage += HelpMessageOpt("-rootcertificates=<file>", tr("Set SSL root certificates for payment request (default: -system-)").toStdString()); + strUsage += HelpMessageOpt("-splash", strprintf(tr("Show splash screen on startup (default: %u)").toStdString(), DEFAULT_SPLASHSCREEN)); + strUsage += HelpMessageOpt("-resetguisettings", tr("Reset all settings changed in the GUI").toStdString()); + if (showDebug) { + strUsage += HelpMessageOpt("-uiplatform", strprintf("Select platform to customize UI for (one of windows, macosx, other; default: %s)", BitcoinGUI::DEFAULT_UIPLATFORM)); + } + QString coreOptions = QString::fromStdString(strUsage); text = version + "\n" + header + "\n" + coreOptions; QTextTableFormat tf; diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index 47282ae2d0..843bd7f67b 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index ba8c28464d..e4ca5e1831 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index 9a56e97f9c..9a5bc273c2 100644 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 5c21db8bdf..cf38c64eb0 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -290,8 +290,10 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact return TransactionCreationFailed; } - // reject absurdly high fee > 0.1 bitcoin - if (nFeeRequired > 10000000) + // reject absurdly high fee. (This can never happen because the + // wallet caps the fee at maxTxFee. This merely serves as a + // belt-and-suspenders check) + if (nFeeRequired > maxTxFee) return AbsurdFee; } diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index a5e877d81f..7a47eda86f 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 6a9b2d5bd3..8c970ee8aa 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 77efdb5cdd..6ce98ef160 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletview.h b/src/qt/walletview.h index 2a6a6a2df2..dbb289f425 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/random.cpp b/src/random.cpp index 0ba0de908d..6155c0d8cf 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rest.cpp b/src/rest.cpp index c46d7a8bd2..ad884dac1c 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -1,9 +1,10 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "chain.h" +#include "chainparams.h" #include "primitives/block.h" #include "primitives/transaction.h" #include "main.h" @@ -223,7 +224,7 @@ static bool rest_block(HTTPRequest* req, if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); - if (!ReadBlockFromDisk(block, pblockindex)) + if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } @@ -360,7 +361,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) CTransaction tx; uint256 hashBlock = uint256(); - if (!GetTransaction(hash, tx, hashBlock, true)) + if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); @@ -493,7 +494,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS) return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); - // check spentness and form a bitmap (as well as a JSON capable human-readble string representation) + // check spentness and form a bitmap (as well as a JSON capable human-readable string representation) vector<unsigned char> bitmap; vector<CCoin> outs; std::string bitmapStringRepresentation; diff --git a/src/reverselock.h b/src/reverselock.h index 567636e16a..fac1ccb793 100644 --- a/src/reverselock.h +++ b/src/reverselock.h @@ -15,10 +15,12 @@ public: explicit reverse_lock(Lock& lock) : lock(lock) { lock.unlock(); + lock.swap(templock); } ~reverse_lock() { - lock.lock(); + templock.lock(); + templock.swap(lock); } private: @@ -26,6 +28,7 @@ private: reverse_lock& operator=(reverse_lock const&); Lock& lock; + Lock templock; }; #endif // BITCOIN_REVERSELOCK_H diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 545ac12890..b76b0ca403 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,6 +10,7 @@ #include "coins.h" #include "consensus/validation.h" #include "main.h" +#include "policy/policy.h" #include "primitives/transaction.h" #include "rpcserver.h" #include "streams.h" @@ -71,6 +72,7 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) result.push_back(Pair("version", blockindex->nVersion)); result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); result.push_back(Pair("time", (int64_t)blockindex->nTime)); + result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce)); result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits))); result.push_back(Pair("difficulty", GetDifficulty(blockindex))); @@ -111,6 +113,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx } result.push_back(Pair("tx", txs)); result.push_back(Pair("time", block.GetBlockTime())); + result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); result.push_back(Pair("nonce", (uint64_t)block.nNonce)); result.push_back(Pair("bits", strprintf("%08x", block.nBits))); result.push_back(Pair("difficulty", GetDifficulty(blockindex))); @@ -187,13 +190,14 @@ UniValue mempoolToJSON(bool fVerbose = false) UniValue info(UniValue::VOBJ); info.push_back(Pair("size", (int)e.GetTxSize())); info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); + info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee()))); info.push_back(Pair("time", e.GetTime())); info.push_back(Pair("height", (int)e.GetHeight())); info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); - info.push_back(Pair("descendantfees", e.GetFeesWithDescendants())); + info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants())); const CTransaction& tx = e.GetTx(); set<string> setDepends; BOOST_FOREACH(const CTxIn& txin, tx.vin) @@ -244,13 +248,14 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) " \"transactionid\" : { (json object)\n" " \"size\" : n, (numeric) transaction size in bytes\n" " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" + " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n" " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" " \"height\" : n, (numeric) block height when transaction entered pool\n" " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" " \"currentpriority\" : n, (numeric) transaction priority now\n" " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n" - " \"descendantfees\" : n, (numeric) fees of in-mempool descendants (including this one)\n" + " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" " \"transactionid\", (string) parent transaction id\n" " ... ]\n" @@ -313,6 +318,7 @@ UniValue getblockheader(const UniValue& params, bool fHelp) " \"version\" : n, (numeric) The block version\n" " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n" " \"nonce\" : n, (numeric) The nonce\n" " \"bits\" : \"1d00ffff\", (string) The bits\n" " \"difficulty\" : x.xxx, (numeric) The difficulty\n" @@ -374,6 +380,7 @@ UniValue getblock(const UniValue& params, bool fHelp) " ,...\n" " ],\n" " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" + " \"mediantime\" : ttt, (numeric) The median block time in seconds since epoch (Jan 1 1970 GMT)\n" " \"nonce\" : n, (numeric) The nonce\n" " \"bits\" : \"1d00ffff\", (string) The bits\n" " \"difficulty\" : x.xxx, (numeric) The difficulty\n" @@ -405,7 +412,7 @@ UniValue getblock(const UniValue& params, bool fHelp) if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); - if(!ReadBlockFromDisk(block, pblockindex)) + if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); if (!fVerbose) @@ -465,8 +472,8 @@ UniValue gettxout(const UniValue& params, bool fHelp) "\nReturns details about an unspent transaction output.\n" "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" - "2. n (numeric, required) vout value\n" - "3. includemempool (boolean, optional) Whether to included the mem pool\n" + "2. n (numeric, required) vout number\n" + "3. includemempool (boolean, optional) Whether to include the mem pool\n" "\nResult:\n" "{\n" " \"bestblock\" : \"hash\", (string) the block hash\n" @@ -539,13 +546,15 @@ UniValue gettxout(const UniValue& params, bool fHelp) UniValue verifychain(const UniValue& params, bool fHelp) { + int nCheckLevel = GetArg("-checklevel", DEFAULT_CHECKLEVEL); + int nCheckDepth = GetArg("-checkblocks", DEFAULT_CHECKBLOCKS); if (fHelp || params.size() > 2) throw runtime_error( "verifychain ( checklevel numblocks )\n" "\nVerifies blockchain database.\n" "\nArguments:\n" - "1. checklevel (numeric, optional, 0-4, default=3) How thorough the block verification is.\n" - "2. numblocks (numeric, optional, default=288, 0=all) The number of blocks to check.\n" + "1. checklevel (numeric, optional, 0-4, default=" + strprintf("%d", nCheckLevel) + ") How thorough the block verification is.\n" + "2. numblocks (numeric, optional, default=" + strprintf("%d", nCheckDepth) + ", 0=all) The number of blocks to check.\n" "\nResult:\n" "true|false (boolean) Verified or not\n" "\nExamples:\n" @@ -555,14 +564,12 @@ UniValue verifychain(const UniValue& params, bool fHelp) LOCK(cs_main); - int nCheckLevel = GetArg("-checklevel", 3); - int nCheckDepth = GetArg("-checkblocks", 288); if (params.size() > 0) nCheckLevel = params[0].get_int(); if (params.size() > 1) nCheckDepth = params[1].get_int(); - return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth); + return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth); } /** Implementation of IsSuperMajority with better feedback */ @@ -608,6 +615,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"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" + " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n" " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n" @@ -639,6 +647,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) 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("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast())); obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip()))); obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); obj.push_back(Pair("pruned", fPruneMode)); @@ -648,6 +657,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) UniValue softforks(UniValue::VARR); softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); + softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); obj.push_back(Pair("softforks", softforks)); if (fPruneMode) @@ -772,6 +782,9 @@ UniValue mempoolInfoToJSON() ret.push_back(Pair("size", (int64_t) mempool.size())); ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); + size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; + ret.push_back(Pair("maxmempool", (int64_t) maxmempool)); + ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK()))); return ret; } @@ -784,9 +797,11 @@ UniValue getmempoolinfo(const UniValue& params, bool fHelp) "\nReturns details on the active state of the TX memory pool.\n" "\nResult:\n" "{\n" - " \"size\": xxxxx (numeric) Current tx count\n" - " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n" - " \"usage\": xxxxx (numeric) Total memory usage for the mempool\n" + " \"size\": xxxxx, (numeric) Current tx count\n" + " \"bytes\": xxxxx, (numeric) Sum of all tx sizes\n" + " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n" + " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n" + " \"mempoolminfee\": xxxxx (numeric) Minimum fee for tx to be accepted\n" "}\n" "\nExamples:\n" + HelpExampleCli("getmempoolinfo", "") @@ -820,11 +835,11 @@ UniValue invalidateblock(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); CBlockIndex* pblockindex = mapBlockIndex[hash]; - InvalidateBlock(state, pblockindex); + InvalidateBlock(state, Params().GetConsensus(), pblockindex); } if (state.IsValid()) { - ActivateBestChain(state); + ActivateBestChain(state, Params()); } if (!state.IsValid()) { @@ -863,7 +878,7 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) } if (state.IsValid()) { - ActivateBestChain(state); + ActivateBestChain(state, Params()); } if (!state.IsValid()) { diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 4064c2fee3..0471580237 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -76,6 +76,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getrawtransaction", 1 }, { "createrawtransaction", 0 }, { "createrawtransaction", 1 }, + { "createrawtransaction", 2 }, { "signrawtransaction", 1 }, { "signrawtransaction", 2 }, { "sendrawtransaction", 1 }, @@ -95,6 +96,8 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getrawmempool", 0 }, { "estimatefee", 0 }, { "estimatepriority", 0 }, + { "estimatesmartfee", 0 }, + { "estimatesmartpriority", 0 }, { "prioritisetransaction", 1 }, { "prioritisetransaction", 2 }, { "setban", 2 }, diff --git a/src/rpcclient.h b/src/rpcclient.h index 8937a56f03..ae015860b6 100644 --- a/src/rpcclient.h +++ b/src/rpcclient.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index c49c3e5194..958c817d67 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -99,7 +99,7 @@ UniValue getgenerate(const UniValue& params, bool fHelp) throw runtime_error( "getgenerate\n" "\nReturn if the server is set to generate coins or not. The default is false.\n" - "It is set with the command line argument -gen (or bitcoin.conf setting gen)\n" + "It is set with the command line argument -gen (or " + std::string(BITCOIN_CONF_FILENAME) + " setting gen)\n" "It can also be set with the setgenerate call.\n" "\nResult\n" "true|false (boolean) If the server is set to generate coins or not\n" @@ -109,7 +109,7 @@ UniValue getgenerate(const UniValue& params, bool fHelp) ); LOCK(cs_main); - return GetBoolArg("-gen", false); + return GetBoolArg("-gen", DEFAULT_GENERATE); } UniValue generate(const UniValue& params, bool fHelp) @@ -157,7 +157,7 @@ UniValue generate(const UniValue& params, bool fHelp) UniValue blockHashes(UniValue::VARR); while (nHeight < nHeightEnd) { - auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(coinbaseScript->reserveScript)); + auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(Params(), coinbaseScript->reserveScript)); if (!pblocktemplate.get()) throw JSONRPCError(RPC_INTERNAL_ERROR, "Couldn't create new block"); CBlock *pblock = &pblocktemplate->block; @@ -171,7 +171,7 @@ UniValue generate(const UniValue& params, bool fHelp) ++pblock->nNonce; } CValidationState state; - if (!ProcessNewBlock(state, NULL, pblock, true, NULL)) + if (!ProcessNewBlock(state, Params(), NULL, pblock, true, NULL)) throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); ++nHeight; blockHashes.push_back(pblock->GetHash().GetHex()); @@ -211,7 +211,7 @@ UniValue setgenerate(const UniValue& params, bool fHelp) if (params.size() > 0) fGenerate = params[0].get_bool(); - int nGenProcLimit = -1; + int nGenProcLimit = GetArg("-genproclimit", DEFAULT_GENERATE_THREADS); if (params.size() > 1) { nGenProcLimit = params[1].get_int(); @@ -259,7 +259,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("errors", GetWarnings("statusbar"))); - obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); + obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", DEFAULT_GENERATE_THREADS))); obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC())); @@ -426,7 +426,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) if (block.hashPrevBlock != pindexPrev->GetBlockHash()) return "inconclusive-not-best-prevblk"; CValidationState state; - TestBlockValidity(state, block, pindexPrev, false, true); + TestBlockValidity(state, Params(), block, pindexPrev, false, true); return BIP22ValidationResult(state); } } @@ -510,7 +510,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) pblocktemplate = NULL; } CScript scriptDummy = CScript() << OP_TRUE; - pblocktemplate = CreateNewBlock(scriptDummy); + pblocktemplate = CreateNewBlock(Params(), scriptDummy); if (!pblocktemplate) throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); @@ -652,7 +652,7 @@ UniValue submitblock(const UniValue& params, bool fHelp) CValidationState state; submitblock_StateCatcher sc(block.GetHash()); RegisterValidationInterface(&sc); - bool fAccepted = ProcessNewBlock(state, NULL, &block, true, NULL); + bool fAccepted = ProcessNewBlock(state, Params(), NULL, &block, true, NULL); UnregisterValidationInterface(&sc); if (fBlockPresent) { @@ -726,3 +726,75 @@ UniValue estimatepriority(const UniValue& params, bool fHelp) return mempool.estimatePriority(nBlocks); } + +UniValue estimatesmartfee(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "estimatesmartfee nblocks\n" + "\nWARNING: This interface is unstable and may disappear or change!\n" + "\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n" + "confirmation within nblocks blocks if possible and return the number of blocks\n" + "for which the estimate is valid.\n" + "\nArguments:\n" + "1. nblocks (numeric)\n" + "\nResult:\n" + "{\n" + " \"feerate\" : x.x, (numeric) estimate fee-per-kilobyte (in BTC)\n" + " \"blocks\" : n (numeric) block number where estimate was found\n" + "}\n" + "\n" + "A negative value is returned if not enough transactions and blocks\n" + "have been observed to make an estimate for any number of blocks.\n" + "However it will not return a value below the mempool reject fee.\n" + "\nExample:\n" + + HelpExampleCli("estimatesmartfee", "6") + ); + + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); + + int nBlocks = params[0].get_int(); + + UniValue result(UniValue::VOBJ); + int answerFound; + CFeeRate feeRate = mempool.estimateSmartFee(nBlocks, &answerFound); + result.push_back(Pair("feerate", feeRate == CFeeRate(0) ? -1.0 : ValueFromAmount(feeRate.GetFeePerK()))); + result.push_back(Pair("blocks", answerFound)); + return result; +} + +UniValue estimatesmartpriority(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "estimatesmartpriority nblocks\n" + "\nWARNING: This interface is unstable and may disappear or change!\n" + "\nEstimates the approximate priority a zero-fee transaction needs to begin\n" + "confirmation within nblocks blocks if possible and return the number of blocks\n" + "for which the estimate is valid.\n" + "\nArguments:\n" + "1. nblocks (numeric)\n" + "\nResult:\n" + "{\n" + " \"priority\" : x.x, (numeric) estimated priority\n" + " \"blocks\" : n (numeric) block number where estimate was found\n" + "}\n" + "\n" + "A negative value is returned if not enough transactions and blocks\n" + "have been observed to make an estimate for any number of blocks.\n" + "However if the mempool reject fee is set it will return 1e9 * MAX_MONEY.\n" + "\nExample:\n" + + HelpExampleCli("estimatesmartpriority", "6") + ); + + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); + + int nBlocks = params[0].get_int(); + + UniValue result(UniValue::VOBJ); + int answerFound; + double priority = mempool.estimateSmartPriority(nBlocks, &answerFound); + result.push_back(Pair("priority", priority)); + result.push_back(Pair("blocks", answerFound)); + return result; +} diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 0f0457c5cf..9871c3fcc9 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -117,7 +117,7 @@ public: UniValue obj(UniValue::VOBJ); CPubKey vchPubKey; obj.push_back(Pair("isscript", false)); - if (pwalletMain->GetPubKey(keyID, vchPubKey)) { + if (pwalletMain && pwalletMain->GetPubKey(keyID, vchPubKey)) { obj.push_back(Pair("pubkey", HexStr(vchPubKey))); obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed())); } @@ -128,7 +128,7 @@ public: UniValue obj(UniValue::VOBJ); CScript subscript; obj.push_back(Pair("isscript", true)); - if (pwalletMain->GetCScript(scriptID, subscript)) { + if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) { std::vector<CTxDestination> addresses; txnouttype whichType; int nRequired; diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 7746be25f7..b61e7c5f13 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -29,7 +29,7 @@ UniValue getconnectioncount(const UniValue& params, bool fHelp) throw runtime_error( "getconnectioncount\n" "\nReturns the number of connections to other nodes.\n" - "\nbResult:\n" + "\nResult:\n" "n (numeric) The connection count\n" "\nExamples:\n" + HelpExampleCli("getconnectioncount", "") @@ -83,13 +83,14 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) throw runtime_error( "getpeerinfo\n" "\nReturns data about each connected network node as a json array of objects.\n" - "\nbResult:\n" + "\nResult:\n" "[\n" " {\n" " \"id\": n, (numeric) Peer index\n" " \"addr\":\"host:port\", (string) The ip address and port of the peer\n" " \"addrlocal\":\"ip:port\", (string) local address\n" " \"services\":\"xxxxxxxxxxxxxxxx\", (string) The services offered\n" + " \"relaytxes\":true|false, (boolean) Whether peer has asked us to relay transactions to it\n" " \"lastsend\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n" " \"lastrecv\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n" " \"bytessent\": n, (numeric) The total bytes sent\n" @@ -110,6 +111,14 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) " n, (numeric) The heights of blocks we're currently asking from this peer\n" " ...\n" " ]\n" + " \"bytessent_per_msg\": {\n" + " \"addr\": n, (numeric) The total bytes sent aggregated by message type\n" + " ...\n" + " }\n" + " \"bytesrecv_per_msg\": {\n" + " \"addr\": n, (numeric) The total bytes received aggregated by message type\n" + " ...\n" + " }\n" " }\n" " ,...\n" "]\n" @@ -134,6 +143,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) if (!(stats.addrLocal.empty())) obj.push_back(Pair("addrlocal", stats.addrLocal)); obj.push_back(Pair("services", strprintf("%016x", stats.nServices))); + obj.push_back(Pair("relaytxes", stats.fRelayTxes)); obj.push_back(Pair("lastsend", stats.nLastSend)); obj.push_back(Pair("lastrecv", stats.nLastRecv)); obj.push_back(Pair("bytessent", stats.nSendBytes)); @@ -163,6 +173,20 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) } obj.push_back(Pair("whitelisted", stats.fWhitelisted)); + UniValue sendPerMsgCmd(UniValue::VOBJ); + BOOST_FOREACH(const mapMsgCmdSize::value_type &i, stats.mapSendBytesPerMsgCmd) { + if (i.second > 0) + sendPerMsgCmd.push_back(Pair(i.first, i.second)); + } + obj.push_back(Pair("bytessent_per_msg", sendPerMsgCmd)); + + UniValue recvPerMsgCmd(UniValue::VOBJ); + BOOST_FOREACH(const mapMsgCmdSize::value_type &i, stats.mapRecvBytesPerMsgCmd) { + if (i.second > 0) + recvPerMsgCmd.push_back(Pair(i.first, i.second)); + } + obj.push_back(Pair("bytesrecv_per_msg", recvPerMsgCmd)); + ret.push_back(obj); } @@ -368,7 +392,16 @@ UniValue getnettotals(const UniValue& params, bool fHelp) "{\n" " \"totalbytesrecv\": n, (numeric) Total bytes received\n" " \"totalbytessent\": n, (numeric) Total bytes sent\n" - " \"timemillis\": t (numeric) Total cpu time\n" + " \"timemillis\": t, (numeric) Total cpu time\n" + " \"uploadtarget\":\n" + " {\n" + " \"timeframe\": n, (numeric) Length of the measuring timeframe in seconds\n" + " \"target\": n, (numeric) Target in bytes\n" + " \"target_reached\": true|false, (boolean) True if target is reached\n" + " \"serve_historical_blocks\": true|false, (boolean) True if serving historical blocks\n" + " \"bytes_left_in_cycle\": t, (numeric) Bytes left in current time cycle\n" + " \"time_left_in_cycle\": t (numeric) Seconds left in current time cycle\n" + " }\n" "}\n" "\nExamples:\n" + HelpExampleCli("getnettotals", "") @@ -379,6 +412,15 @@ UniValue getnettotals(const UniValue& params, bool fHelp) obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv())); obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent())); obj.push_back(Pair("timemillis", GetTimeMillis())); + + UniValue outboundLimit(UniValue::VOBJ); + outboundLimit.push_back(Pair("timeframe", CNode::GetMaxOutboundTimeframe())); + outboundLimit.push_back(Pair("target", CNode::GetMaxOutboundTarget())); + outboundLimit.push_back(Pair("target_reached", CNode::OutboundTargetReached(false))); + outboundLimit.push_back(Pair("serve_historical_blocks", !CNode::OutboundTargetReached(true))); + outboundLimit.push_back(Pair("bytes_left_in_cycle", CNode::GetOutboundTargetBytesLeft())); + outboundLimit.push_back(Pair("time_left_in_cycle", CNode::GetMaxOutboundTimeLeftInCycle())); + obj.push_back(Pair("uploadtarget", outboundLimit)); return obj; } diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index d83cd87f94..b7605545d8 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h index 9cf1ab6d99..55d0aac68b 100644 --- a/src/rpcprotocol.h +++ b/src/rpcprotocol.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 4dec53396d..64bf569bac 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -62,6 +62,7 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); + entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION))); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); UniValue vin(UniValue::VARR); @@ -133,6 +134,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) "{\n" " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n" " \"txid\" : \"id\", (string) The transaction id (same as provided)\n" + " \"size\" : n, (numeric) The transaction size\n" " \"version\" : n, (numeric) The version\n" " \"locktime\" : ttt, (numeric) The lock time\n" " \"vin\" : [ (array of json objects)\n" @@ -186,7 +188,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) CTransaction tx; uint256 hashBlock; - if (!GetTransaction(hash, tx, hashBlock, true)) + if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); string strHex = EncodeHexTx(tx); @@ -256,7 +258,7 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp) if (pblockindex == NULL) { CTransaction tx; - if (!GetTransaction(oneTxid, tx, hashBlock, false) || hashBlock.IsNull()) + if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block"); if (!mapBlockIndex.count(hashBlock)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt"); @@ -264,7 +266,7 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp) } CBlock block; - if(!ReadBlockFromDisk(block, pblockindex)) + if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); unsigned int ntxFound = 0; @@ -316,9 +318,9 @@ UniValue verifytxoutproof(const UniValue& params, bool fHelp) UniValue createrawtransaction(const UniValue& params, bool fHelp) { - if (fHelp || params.size() != 2) + if (fHelp || params.size() < 2 || params.size() > 3) throw runtime_error( - "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,\"data\":\"hex\",...}\n" + "createrawtransaction [{\"txid\":\"id\",\"vout\":n},...] {\"address\":amount,\"data\":\"hex\",...} ( locktime )\n" "\nCreate a transaction spending the given inputs and creating new outputs.\n" "Outputs can be addresses or data.\n" "Returns hex-encoded raw transaction.\n" @@ -336,10 +338,11 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) " ]\n" "2. \"outputs\" (string, required) a json object with outputs\n" " {\n" - " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the " + CURRENCY_UNIT + " amount\n" + " \"address\": x.xxx (numeric or string, required) The key is the bitcoin address, the numeric value (can be string) is the " + CURRENCY_UNIT + " amount\n" " \"data\": \"hex\", (string, required) The key is \"data\", the value is hex encoded data\n" " ...\n" " }\n" + "3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n" "\nResult:\n" "\"transaction\" (string) hex string of the transaction\n" @@ -350,14 +353,22 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"") ); - LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)(UniValue::VNUM), true); + if (params[0].isNull() || params[1].isNull()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null"); UniValue inputs = params[0].get_array(); UniValue sendTo = params[1].get_obj(); CMutableTransaction rawTx; + if (params.size() > 2 && !params[2].isNull()) { + int64_t nLockTime = params[2].get_int64(); + if (nLockTime < 0 || nLockTime > std::numeric_limits<uint32_t>::max()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, locktime out of range"); + rawTx.nLockTime = nLockTime; + } + for (unsigned int idx = 0; idx < inputs.size(); idx++) { const UniValue& input = inputs[idx]; const UniValue& o = input.get_obj(); @@ -371,7 +382,9 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) if (nOutput < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive"); - CTxIn in(COutPoint(txid, nOutput)); + uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t>::max() - 1 : std::numeric_limits<uint32_t>::max()); + CTxIn in(COutPoint(txid, nOutput), CScript(), nSequence); + rawTx.vin.push_back(in); } @@ -417,6 +430,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp) "\nResult:\n" "{\n" " \"txid\" : \"id\", (string) The transaction id\n" + " \"size\" : n, (numeric) The transaction size\n" " \"version\" : n, (numeric) The version\n" " \"locktime\" : ttt, (numeric) The lock time\n" " \"vin\" : [ (array of json objects)\n" @@ -494,7 +508,6 @@ UniValue decodescript(const UniValue& params, bool fHelp) + HelpExampleRpc("decodescript", "\"hexstring\"") ); - LOCK(cs_main); RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); UniValue r(UniValue::VOBJ); @@ -809,7 +822,7 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp) // push to local node and sync with wallets CValidationState state; bool fMissingInputs; - if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) { + if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, false, !fOverrideFees)) { if (state.IsInvalid()) { throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason())); } else { diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index fa60f8c833..53c368b271 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -33,7 +33,7 @@ static bool fRPCInWarmup = true; static std::string rpcWarmupStatus("RPC server started"); static CCriticalSection cs_rpcWarmup; /* Timer-creating functions */ -static std::vector<RPCTimerInterface*> timerInterfaces; +static RPCTimerInterface* timerInterface = NULL; /* Map of name to timer. * @note Can be changed to std::unique_ptr when C++11 */ static std::map<std::string, boost::shared_ptr<RPCTimerBase> > deadlineTimers; @@ -319,6 +319,8 @@ static const CRPCCommand vRPCCommands[] = { "util", "verifymessage", &verifymessage, true }, { "util", "estimatefee", &estimatefee, true }, { "util", "estimatepriority", &estimatepriority, true }, + { "util", "estimatesmartfee", &estimatesmartfee, true }, + { "util", "estimatesmartpriority", &estimatesmartpriority, true }, /* Not shown in help */ { "hidden", "invalidateblock", &invalidateblock, true }, @@ -344,6 +346,7 @@ static const CRPCCommand vRPCCommands[] = { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false }, { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false }, { "wallet", "gettransaction", &gettransaction, false }, + { "wallet", "abandontransaction", &abandontransaction, false }, { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false }, { "wallet", "getwalletinfo", &getwalletinfo, false }, { "wallet", "importprivkey", &importprivkey, true }, @@ -544,26 +547,30 @@ std::string HelpExampleRpc(const std::string& methodname, const std::string& arg "\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n"; } -void RPCRegisterTimerInterface(RPCTimerInterface *iface) +void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface) { - timerInterfaces.push_back(iface); + if (!timerInterface) + timerInterface = iface; } -void RPCUnregisterTimerInterface(RPCTimerInterface *iface) +void RPCSetTimerInterface(RPCTimerInterface *iface) { - std::vector<RPCTimerInterface*>::iterator i = std::find(timerInterfaces.begin(), timerInterfaces.end(), iface); - assert(i != timerInterfaces.end()); - timerInterfaces.erase(i); + timerInterface = iface; +} + +void RPCUnsetTimerInterface(RPCTimerInterface *iface) +{ + if (timerInterface == iface) + timerInterface = NULL; } void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds) { - if (timerInterfaces.empty()) + if (!timerInterface) throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC"); deadlineTimers.erase(name); - RPCTimerInterface* timerInterface = timerInterfaces[0]; LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name()); - deadlineTimers.insert(std::make_pair(name, timerInterface->NewTimer(func, nSeconds*1000))); + deadlineTimers.insert(std::make_pair(name, boost::shared_ptr<RPCTimerBase>(timerInterface->NewTimer(func, nSeconds*1000)))); } const CRPCTable tableRPC; diff --git a/src/rpcserver.h b/src/rpcserver.h index dde8dfdcc3..29f5036580 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -100,10 +100,12 @@ public: virtual RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis) = 0; }; -/** Register factory function for timers */ -void RPCRegisterTimerInterface(RPCTimerInterface *iface); -/** Unregister factory function for timers */ -void RPCUnregisterTimerInterface(RPCTimerInterface *iface); +/** Set the factory function for timers */ +void RPCSetTimerInterface(RPCTimerInterface *iface); +/** Set the factory function for timer, but only, if unset */ +void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface); +/** Unset factory function for timers */ +void RPCUnsetTimerInterface(RPCTimerInterface *iface); /** * Run func nSeconds from now. @@ -193,6 +195,8 @@ extern UniValue getblocktemplate(const UniValue& params, bool fHelp); extern UniValue submitblock(const UniValue& params, bool fHelp); extern UniValue estimatefee(const UniValue& params, bool fHelp); extern UniValue estimatepriority(const UniValue& params, bool fHelp); +extern UniValue estimatesmartfee(const UniValue& params, bool fHelp); +extern UniValue estimatesmartpriority(const UniValue& params, bool fHelp); extern UniValue getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp extern UniValue getaccountaddress(const UniValue& params, bool fHelp); @@ -219,6 +223,7 @@ extern UniValue listaddressgroupings(const UniValue& params, bool fHelp); extern UniValue listaccounts(const UniValue& params, bool fHelp); extern UniValue listsinceblock(const UniValue& params, bool fHelp); extern UniValue gettransaction(const UniValue& params, bool fHelp); +extern UniValue abandontransaction(const UniValue& params, bool fHelp); extern UniValue backupwallet(const UniValue& params, bool fHelp); extern UniValue keypoolrefill(const UniValue& params, bool fHelp); extern UniValue walletpassphrase(const UniValue& params, bool fHelp); diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index b0d5faaf77..47ad1d0807 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -1,11 +1,12 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "bitcoinconsensus.h" #include "primitives/transaction.h" +#include "pubkey.h" #include "script/interpreter.h" #include "version.h" @@ -60,7 +61,13 @@ inline int set_error(bitcoinconsensus_error* ret, bitcoinconsensus_error serror) return 0; } -} // anon namespace +struct ECCryptoClosure +{ + ECCVerifyHandle handle; +}; + +ECCryptoClosure instance_of_eccryptoclosure; +} int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, const unsigned char *txTo , unsigned int txToLen, diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index 0320577797..5b8c33c6bf 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -44,9 +44,10 @@ typedef enum bitcoinconsensus_error_t /** Script verification flags */ enum { - bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0, - bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts - bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0, + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65) }; /// Returns 1 if the input nIn of the serialized transaction pointed to by diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index d3aec26020..a928223268 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,7 +9,6 @@ #include "crypto/ripemd160.h" #include "crypto/sha1.h" #include "crypto/sha256.h" -#include "eccryptoverify.h" #include "pubkey.h" #include "script/script.h" #include "uint256.h" @@ -165,16 +164,8 @@ bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) { if (!IsValidSignatureEncoding(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; + std::vector<unsigned char> vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size() - 1); + return CPubKey::CheckLowS(vchSigCopy); } bool static IsDefinedHashtypeSignature(const valtype &vchSig) { @@ -273,7 +264,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un 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) + if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT) return set_error(serror, SCRIPT_ERR_OP_COUNT); if (opcode == OP_CAT || @@ -869,10 +860,10 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); int nKeysCount = CScriptNum(stacktop(-i), fRequireMinimal).getint(); - if (nKeysCount < 0 || nKeysCount > 20) + if (nKeysCount < 0 || nKeysCount > MAX_PUBKEYS_PER_MULTISIG) return set_error(serror, SCRIPT_ERR_PUBKEY_COUNT); nOpCount += nKeysCount; - if (nOpCount > 201) + if (nOpCount > MAX_OPS_PER_SCRIPT) return set_error(serror, SCRIPT_ERR_OP_COUNT); int ikey = ++i; i += nKeysCount; @@ -1032,7 +1023,7 @@ public: // Serialize the script if (nInput != nIn) // Blank out other inputs' signatures - ::Serialize(s, CScript(), nType, nVersion); + ::Serialize(s, CScriptBase(), nType, nVersion); else SerializeScriptCode(s, nType, nVersion); // Serialize the nSequence diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 213e8c7651..7b34547ffb 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/script.cpp b/src/script/script.cpp index 9a0c067a33..9f2809e593 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -131,7 +131,7 @@ const char* GetOpName(opcodetype opcode) // expanson case OP_NOP1 : return "OP_NOP1"; - case OP_NOP2 : return "OP_NOP2"; + case OP_CHECKLOCKTIMEVERIFY : return "OP_CHECKLOCKTIMEVERIFY"; case OP_NOP3 : return "OP_NOP3"; case OP_NOP4 : return "OP_NOP4"; case OP_NOP5 : return "OP_NOP5"; @@ -170,7 +170,7 @@ unsigned int CScript::GetSigOpCount(bool fAccurate) const if (fAccurate && lastOpcode >= OP_1 && lastOpcode <= OP_16) n += DecodeOP_N(lastOpcode); else - n += 20; + n += MAX_PUBKEYS_PER_MULTISIG; } lastOpcode = opcode; } @@ -205,9 +205,9 @@ bool CScript::IsPayToScriptHash() const { // Extra-fast test for pay-to-script-hash CScripts: return (this->size() == 23 && - this->at(0) == OP_HASH160 && - this->at(1) == 0x14 && - this->at(22) == OP_EQUAL); + (*this)[0] == OP_HASH160 && + (*this)[1] == 0x14 && + (*this)[22] == OP_EQUAL); } bool CScript::IsPushOnly(const_iterator pc) const diff --git a/src/script/script.h b/src/script/script.h index cdc9a71bb2..6551eea30d 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,6 +7,7 @@ #define BITCOIN_SCRIPT_SCRIPT_H #include "crypto/common.h" +#include "prevector.h" #include <assert.h> #include <climits> @@ -17,7 +18,14 @@ #include <string> #include <vector> -static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes +// Maximum number of bytes pushable to the stack +static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; + +// Maximum number of non-push operations per script +static const int MAX_OPS_PER_SCRIPT = 201; + +// Maximum number of public keys per multisig +static const int MAX_PUBKEYS_PER_MULTISIG = 20; // Threshold for nLockTime: below this value it is interpreted as block number, // otherwise as UNIX timestamp. @@ -154,8 +162,8 @@ enum opcodetype // expansion OP_NOP1 = 0xb0, - OP_NOP2 = 0xb1, - OP_CHECKLOCKTIMEVERIFY = OP_NOP2, + OP_CHECKLOCKTIMEVERIFY = 0xb1, + OP_NOP2 = OP_CHECKLOCKTIMEVERIFY, OP_NOP3 = 0xb2, OP_NOP4 = 0xb3, OP_NOP5 = 0xb4, @@ -347,8 +355,10 @@ private: int64_t m_value; }; +typedef prevector<28, unsigned char> CScriptBase; + /** Serialized script, used inside transaction inputs and outputs */ -class CScript : public std::vector<unsigned char> +class CScript : public CScriptBase { protected: CScript& push_int64(int64_t n) @@ -369,9 +379,10 @@ protected: } public: CScript() { } - CScript(const CScript& b) : std::vector<unsigned char>(b.begin(), b.end()) { } - CScript(const_iterator pbegin, const_iterator pend) : std::vector<unsigned char>(pbegin, pend) { } - CScript(const unsigned char* pbegin, const unsigned char* pend) : std::vector<unsigned char>(pbegin, pend) { } + CScript(const CScript& b) : CScriptBase(b.begin(), b.end()) { } + CScript(const_iterator pbegin, const_iterator pend) : CScriptBase(pbegin, pend) { } + CScript(std::vector<unsigned char>::const_iterator pbegin, std::vector<unsigned char>::const_iterator pend) : CScriptBase(pbegin, pend) { } + CScript(const unsigned char* pbegin, const unsigned char* pend) : CScriptBase(pbegin, pend) { } CScript& operator+=(const CScript& b) { @@ -604,7 +615,7 @@ public: void clear() { // The default std::vector::clear() does not release memory. - std::vector<unsigned char>().swap(*this); + CScriptBase().swap(*this); } }; diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 099b4ad0e3..bdc0bfdc1c 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -1,21 +1,34 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "sigcache.h" +#include "memusage.h" #include "pubkey.h" #include "random.h" #include "uint256.h" #include "util.h" #include <boost/thread.hpp> -#include <boost/tuple/tuple_comparison.hpp> +#include <boost/unordered_set.hpp> namespace { /** + * We're hashing a nonce into the entries themselves, so we don't need extra + * blinding in the set hash computation. + */ +class CSignatureCacheHasher +{ +public: + size_t operator()(const uint256& key) const { + return key.GetCheapHash(); + } +}; + +/** * 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) @@ -23,52 +36,54 @@ namespace { 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; + //! Entries are SHA256(nonce || signature hash || public key || signature): + uint256 nonce; + typedef boost::unordered_set<uint256, CSignatureCacheHasher> map_type; + map_type setValid; boost::shared_mutex cs_sigcache; + public: + CSignatureCache() + { + GetRandBytes(nonce.begin(), 32); + } + + void + ComputeEntry(uint256& entry, const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubkey) + { + CSHA256().Write(nonce.begin(), 32).Write(hash.begin(), 32).Write(&pubkey[0], pubkey.size()).Write(&vchSig[0], vchSig.size()).Finalize(entry.begin()); + } + bool - Get(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey) + Get(const uint256& entry) { boost::shared_lock<boost::shared_mutex> lock(cs_sigcache); + return setValid.count(entry); + } - sigdata_type k(hash, vchSig, pubKey); - std::set<sigdata_type>::iterator mi = setValid.find(k); - if (mi != setValid.end()) - return true; - return false; + void Erase(const uint256& entry) + { + boost::unique_lock<boost::shared_mutex> lock(cs_sigcache); + setValid.erase(entry); } - void Set(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey) + void Set(const uint256& entry) { - // 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); + size_t nMaxCacheSize = GetArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20); if (nMaxCacheSize <= 0) return; boost::unique_lock<boost::shared_mutex> lock(cs_sigcache); - - while (static_cast<int64_t>(setValid.size()) > nMaxCacheSize) + while (memusage::DynamicUsage(setValid) > 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); + map_type::size_type s = GetRand(setValid.bucket_count()); + map_type::local_iterator it = setValid.begin(s); + if (it != setValid.end(s)) { + setValid.erase(*it); + } } - sigdata_type k(hash, vchSig, pubKey); - setValid.insert(k); + setValid.insert(entry); } }; @@ -78,13 +93,21 @@ bool CachingTransactionSignatureChecker::VerifySignature(const std::vector<unsig { static CSignatureCache signatureCache; - if (signatureCache.Get(sighash, vchSig, pubkey)) + uint256 entry; + signatureCache.ComputeEntry(entry, sighash, vchSig, pubkey); + + if (signatureCache.Get(entry)) { + if (!store) { + signatureCache.Erase(entry); + } return true; + } if (!TransactionSignatureChecker::VerifySignature(vchSig, pubkey, sighash)) return false; - if (store) - signatureCache.Set(sighash, vchSig, pubkey); + if (store) { + signatureCache.Set(entry); + } return true; } diff --git a/src/script/sigcache.h b/src/script/sigcache.h index b299038daa..be1df09c2a 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,6 +10,10 @@ #include <vector> +// DoS prevention: limit cache size to less than 40MB (over 500000 +// entries on 64-bit systems). +static const unsigned int DEFAULT_MAX_SIG_CACHE_SIZE = 40; + class CPubKey; class CachingTransactionSignatureChecker : public TransactionSignatureChecker diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 8b43183b6d..2f4111f786 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -16,7 +16,7 @@ using namespace std; -typedef vector<unsigned char> valtype; +typedef std::vector<unsigned char> valtype; TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), checker(txTo, nIn) {} @@ -118,7 +118,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu bool fSolved = SignStep(creator, subscript, scriptSig, subType) && subType != TX_SCRIPTHASH; // Append serialized subscript whether or not it is completely signed: - scriptSig << static_cast<valtype>(subscript); + scriptSig << valtype(subscript.begin(), subscript.end()); if (!fSolved) return false; } diff --git a/src/script/sign.h b/src/script/sign.h index 13f45007dd..47a9cde7f4 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/standard.cpp b/src/script/standard.cpp index bfef8afa17..30935768ac 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -16,6 +16,7 @@ using namespace std; typedef vector<unsigned char> valtype; +bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER; unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY; CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {} diff --git a/src/script/standard.h b/src/script/standard.h index ae1bbecca0..6bac6e4097 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -13,6 +13,8 @@ #include <stdint.h> +static const bool DEFAULT_ACCEPT_DATACARRIER = true; + class CKeyID; class CScript; @@ -26,6 +28,7 @@ public: }; static const unsigned int MAX_OP_RETURN_RELAY = 83; //! bytes (+1 for OP_RETURN, +2 for the pushdata opcodes) +extern bool fAcceptDatacarrier; extern unsigned nMaxDatacarrierBytes; /** diff --git a/src/secp256k1/.gitignore b/src/secp256k1/.gitignore index 076ff1295f..e0b7b7a48a 100644 --- a/src/secp256k1/.gitignore +++ b/src/secp256k1/.gitignore @@ -1,9 +1,12 @@ bench_inv +bench_ecdh bench_sign bench_verify +bench_schnorr_verify bench_recover bench_internal tests +gen_context *.exe *.so *.a @@ -28,6 +31,7 @@ build-aux/ *~ src/libsecp256k1-config.h src/libsecp256k1-config.h.in +src/ecmult_static_context.h m4/libtool.m4 m4/ltoptions.m4 m4/ltsugar.m4 diff --git a/src/secp256k1/.travis.yml b/src/secp256k1/.travis.yml index 0d8089cfe4..4e1e73c39f 100644 --- a/src/secp256k1/.travis.yml +++ b/src/secp256k1/.travis.yml @@ -8,20 +8,24 @@ compiler: - gcc env: global: - - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no ASM=no BUILD=check EXTRAFLAGS= HOST= + - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no schnorr=no RECOVERY=no matrix: - - SCALAR=32bit + - SCALAR=32bit RECOVERY=yes + - SCALAR=32bit FIELD=32bit ECDH=yes - SCALAR=64bit - - FIELD=64bit + - FIELD=64bit RECOVERY=yes - FIELD=64bit ENDOMORPHISM=yes + - FIELD=64bit ENDOMORPHISM=yes ECDH=yes - FIELD=64bit ASM=x86_64 - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64 - - FIELD=32bit + - FIELD=32bit SCHNORR=yes - FIELD=32bit ENDOMORPHISM=yes - BIGNUM=no - - BIGNUM=no ENDOMORPHISM=yes + - BIGNUM=no ENDOMORPHISM=yes SCHNORR=yes RECOVERY=yes + - BIGNUM=no STATICPRECOMPUTATION=no - BUILD=distcheck - - EXTRAFLAGS=CFLAGS=-DDETERMINISTIC + - EXTRAFLAGS=CPPFLAGS=-DDETERMINISTIC + - EXTRAFLAGS=CFLAGS=-O0 matrix: fast_finish: true include: @@ -55,5 +59,5 @@ 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 + - ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-schnorr=$SCHNORR --enable-module-recovery=$RECOVERY $EXTRAFLAGS $USE_HOST && make -j2 $BUILD os: linux diff --git a/src/secp256k1/Makefile.am b/src/secp256k1/Makefile.am index cc15338b7e..7772a4e9d2 100644 --- a/src/secp256k1/Makefile.am +++ b/src/secp256k1/Makefile.am @@ -19,6 +19,8 @@ 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_const.h +noinst_HEADERS += src/ecmult_const_impl.h noinst_HEADERS += src/ecmult_gen.h noinst_HEADERS += src/ecmult_gen_impl.h noinst_HEADERS += src/num.h @@ -38,40 +40,72 @@ noinst_HEADERS += src/hash_impl.h noinst_HEADERS += src/field.h noinst_HEADERS += src/field_impl.h noinst_HEADERS += src/bench.h +noinst_HEADERS += contrib/lax_der_parsing.h +noinst_HEADERS += contrib/lax_der_parsing.c +noinst_HEADERS += contrib/lax_der_privatekey_parsing.h +noinst_HEADERS += contrib/lax_der_privatekey_parsing.c pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libsecp256k1.pc libsecp256k1_la_SOURCES = src/secp256k1.c -libsecp256k1_la_CPPFLAGS = -I$(top_srcdir)/include $(SECP_INCLUDES) +libsecp256k1_la_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) libsecp256k1_la_LIBADD = $(SECP_LIBS) noinst_PROGRAMS = if USE_BENCHMARK -noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_internal +noinst_PROGRAMS += bench_verify bench_sign bench_internal 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_internal_SOURCES = src/bench_internal.c bench_internal_LDADD = $(SECP_LIBS) -bench_internal_LDFLAGS = -static bench_internal_CPPFLAGS = $(SECP_INCLUDES) endif if USE_TESTS noinst_PROGRAMS += tests tests_SOURCES = src/tests.c -tests_CPPFLAGS = -DVERIFY $(SECP_INCLUDES) $(SECP_TEST_INCLUDES) +tests_CPPFLAGS = -DVERIFY -I$(top_srcdir)/src -I$(top_srcdir)/include $(SECP_INCLUDES) $(SECP_TEST_INCLUDES) tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) tests_LDFLAGS = -static TESTS = tests endif -EXTRA_DIST = autogen.sh +if USE_ECMULT_STATIC_PRECOMPUTATION +CPPFLAGS_FOR_BUILD +=-I$(top_srcdir) +CFLAGS_FOR_BUILD += -Wall -Wextra -Wno-unused-function + +gen_context_OBJECTS = gen_context.o +gen_context_BIN = gen_context$(BUILD_EXEEXT) +gen_%.o: src/gen_%.c + $(CC_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@ + +$(gen_context_BIN): $(gen_context_OBJECTS) + $(CC_FOR_BUILD) $^ -o $@ + +$(libsecp256k1_la_OBJECTS): src/ecmult_static_context.h +$(tests_OBJECTS): src/ecmult_static_context.h +$(bench_internal_OBJECTS): src/ecmult_static_context.h + +src/ecmult_static_context.h: $(gen_context_BIN) + ./$(gen_context_BIN) + +CLEANFILES = $(gen_context_BIN) src/ecmult_static_context.h +endif + +EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h + +if ENABLE_MODULE_ECDH +include src/modules/ecdh/Makefile.am.include +endif + +if ENABLE_MODULE_SCHNORR +include src/modules/schnorr/Makefile.am.include +endif + +if ENABLE_MODULE_RECOVERY +include src/modules/recovery/Makefile.am.include +endif diff --git a/src/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 b/src/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 new file mode 100644 index 0000000000..77fd346a79 --- /dev/null +++ b/src/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 @@ -0,0 +1,125 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PROG_CC_FOR_BUILD +# +# DESCRIPTION +# +# This macro searches for a C compiler that generates native executables, +# that is a C compiler that surely is not a cross-compiler. This can be +# useful if you have to generate source code at compile-time like for +# example GCC does. +# +# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything +# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD). +# The value of these variables can be overridden by the user by specifying +# a compiler with an environment variable (like you do for standard CC). +# +# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object +# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if +# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are +# substituted in the Makefile. +# +# LICENSE +# +# Copyright (c) 2008 Paolo Bonzini <bonzini@gnu.org> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 8 + +AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD]) +AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([AC_EXEEXT])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl + +dnl Use the standard macros, but make them use other variable names +dnl +pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl +pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl +pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl +pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl +pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl +pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl +pushdef([ac_cv_objext], ac_cv_build_objext)dnl +pushdef([ac_exeext], ac_build_exeext)dnl +pushdef([ac_objext], ac_build_objext)dnl +pushdef([CC], CC_FOR_BUILD)dnl +pushdef([CPP], CPP_FOR_BUILD)dnl +pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl +pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl +pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl +pushdef([host], build)dnl +pushdef([host_alias], build_alias)dnl +pushdef([host_cpu], build_cpu)dnl +pushdef([host_vendor], build_vendor)dnl +pushdef([host_os], build_os)dnl +pushdef([ac_cv_host], ac_cv_build)dnl +pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl +pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl +pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl +pushdef([ac_cv_host_os], ac_cv_build_os)dnl +pushdef([ac_cpp], ac_build_cpp)dnl +pushdef([ac_compile], ac_build_compile)dnl +pushdef([ac_link], ac_build_link)dnl + +save_cross_compiling=$cross_compiling +save_ac_tool_prefix=$ac_tool_prefix +cross_compiling=no +ac_tool_prefix= + +AC_PROG_CC +AC_PROG_CPP +AC_EXEEXT + +ac_tool_prefix=$save_ac_tool_prefix +cross_compiling=$save_cross_compiling + +dnl Restore the old definitions +dnl +popdef([ac_link])dnl +popdef([ac_compile])dnl +popdef([ac_cpp])dnl +popdef([ac_cv_host_os])dnl +popdef([ac_cv_host_vendor])dnl +popdef([ac_cv_host_cpu])dnl +popdef([ac_cv_host_alias])dnl +popdef([ac_cv_host])dnl +popdef([host_os])dnl +popdef([host_vendor])dnl +popdef([host_cpu])dnl +popdef([host_alias])dnl +popdef([host])dnl +popdef([LDFLAGS])dnl +popdef([CPPFLAGS])dnl +popdef([CFLAGS])dnl +popdef([CPP])dnl +popdef([CC])dnl +popdef([ac_objext])dnl +popdef([ac_exeext])dnl +popdef([ac_cv_objext])dnl +popdef([ac_cv_exeext])dnl +popdef([ac_cv_prog_cc_g])dnl +popdef([ac_cv_prog_cc_cross])dnl +popdef([ac_cv_prog_cc_works])dnl +popdef([ac_cv_prog_gcc])dnl +popdef([ac_cv_prog_CPP])dnl + +dnl Finally, set Makefile variables +dnl +BUILD_EXEEXT=$ac_build_exeext +BUILD_OBJEXT=$ac_build_objext +AC_SUBST(BUILD_EXEEXT)dnl +AC_SUBST(BUILD_OBJEXT)dnl +AC_SUBST([CFLAGS_FOR_BUILD])dnl +AC_SUBST([CPPFLAGS_FOR_BUILD])dnl +AC_SUBST([LDFLAGS_FOR_BUILD])dnl +]) diff --git a/src/secp256k1/build-aux/m4/bitcoin_secp.m4 b/src/secp256k1/build-aux/m4/bitcoin_secp.m4 index 4a398d6c93..d41bbb6487 100644 --- a/src/secp256k1/build-aux/m4/bitcoin_secp.m4 +++ b/src/secp256k1/build-aux/m4/bitcoin_secp.m4 @@ -16,8 +16,7 @@ AC_MSG_RESULT([$has_64bit_asm]) dnl AC_DEFUN([SECP_OPENSSL_CHECK],[ -if test x"$use_pkgconfig" = x"yes"; then - : #NOP + has_libcrypto=no m4_ifdef([PKG_CHECK_MODULES],[ PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes],[has_libcrypto=no]) if test x"$has_libcrypto" = x"yes"; then @@ -27,11 +26,16 @@ if test x"$use_pkgconfig" = x"yes"; then 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 = xno; then + 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([[ diff --git a/src/secp256k1/configure.ac b/src/secp256k1/configure.ac index 3dc1829516..786d8dcfb9 100644 --- a/src/secp256k1/configure.ac +++ b/src/secp256k1/configure.ac @@ -17,25 +17,19 @@ PKG_PROG_PKG_CONFIG AC_PATH_TOOL(AR, ar) AC_PATH_TOOL(RANLIB, ranlib) AC_PATH_TOOL(STRIP, strip) +AX_PROG_CC_FOR_BUILD if test "x$CFLAGS" = "x"; then CFLAGS="-O3 -g" fi +AM_PROG_CC_C_O + AC_PROG_CC_C89 if test x"$ac_cv_prog_cc_c89" = x"no"; then AC_MSG_ERROR([c89 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 @@ -80,6 +74,14 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], CFLAGS="$saved_CFLAGS" ]) +saved_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -fvisibility=hidden" +AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden]) +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 no)]), @@ -95,6 +97,26 @@ AC_ARG_ENABLE(endomorphism, AS_HELP_STRING([--enable-endomorphism],[enable endomorphism (default is no)]), [use_endomorphism=$enableval], [use_endomorphism=no]) + +AC_ARG_ENABLE(ecmult_static_precomputation, + AS_HELP_STRING([--enable-ecmult-static-precomputation],[enable precomputed ecmult table for signing (default is yes)]), + [use_ecmult_static_precomputation=$enableval], + [use_ecmult_static_precomputation=yes]) + +AC_ARG_ENABLE(module_ecdh, + AS_HELP_STRING([--enable-module-ecdh],[enable ECDH shared secret computation (default is no)]), + [enable_module_ecdh=$enableval], + [enable_module_ecdh=no]) + +AC_ARG_ENABLE(module_schnorr, + AS_HELP_STRING([--enable-module-schnorr],[enable Schnorr signature module (default is no)]), + [enable_module_schnorr=$enableval], + [enable_module_schnorr=no]) + +AC_ARG_ENABLE(module_recovery, + AS_HELP_STRING([--enable-module-recovery],[enable ECDSA pubkey recovery module (default is no)]), + [enable_module_recovery=$enableval], + [enable_module_recovery=no]) AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto], [Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto]) @@ -305,6 +327,22 @@ if test x"$use_endomorphism" = x"yes"; then AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization]) fi +if test x"$use_ecmult_static_precomputation" = x"yes"; then + AC_DEFINE(USE_ECMULT_STATIC_PRECOMPUTATION, 1, [Define this symbol to use a statically generated ecmult table]) +fi + +if test x"$enable_module_ecdh" = x"yes"; then + AC_DEFINE(ENABLE_MODULE_ECDH, 1, [Define this symbol to enable the ECDH module]) +fi + +if test x"$enable_module_schnorr" = x"yes"; then + AC_DEFINE(ENABLE_MODULE_SCHNORR, 1, [Define this symbol to enable the Schnorr signature module]) +fi + +if test x"$enable_module_recovery" = x"yes"; then + AC_DEFINE(ENABLE_MODULE_RECOVERY, 1, [Define this symbol to enable the ECDSA pubkey recovery module]) +fi + AC_C_BIGENDIAN() AC_MSG_NOTICE([Using assembly optimizations: $set_asm]) @@ -312,6 +350,10 @@ AC_MSG_NOTICE([Using field implementation: $set_field]) AC_MSG_NOTICE([Using bignum implementation: $set_bignum]) AC_MSG_NOTICE([Using scalar implementation: $set_scalar]) AC_MSG_NOTICE([Using endomorphism optimizations: $use_endomorphism]) +AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh]) + +AC_MSG_NOTICE([Building Schnorr signatures module: $enable_module_schnorr]) +AC_MSG_NOTICE([Building ECDSA pubkey recovery module: $enable_module_recovery]) AC_CONFIG_HEADERS([src/libsecp256k1-config.h]) AC_CONFIG_FILES([Makefile libsecp256k1.pc]) @@ -321,6 +363,10 @@ AC_SUBST(SECP_TEST_LIBS) AC_SUBST(SECP_TEST_INCLUDES) AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"]) AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"]) +AM_CONDITIONAL([USE_ECMULT_STATIC_PRECOMPUTATION], [test x"$use_ecmult_static_precomputation" = x"yes"]) +AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"]) +AM_CONDITIONAL([ENABLE_MODULE_SCHNORR], [test x"$enable_module_schnorr" = x"yes"]) +AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"yes"]) dnl make sure nothing new is exported so that we don't break the cache PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH" diff --git a/src/secp256k1/contrib/lax_der_parsing.c b/src/secp256k1/contrib/lax_der_parsing.c new file mode 100644 index 0000000000..5b141a9948 --- /dev/null +++ b/src/secp256k1/contrib/lax_der_parsing.c @@ -0,0 +1,150 @@ +/********************************************************************** + * Copyright (c) 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#include <string.h> +#include <secp256k1.h> + +#include "lax_der_parsing.h" + +int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { + size_t rpos, rlen, spos, slen; + size_t pos = 0; + size_t lenbyte; + unsigned char tmpsig[64] = {0}; + int overflow = 0; + + /* Hack to initialize sig with a correctly-parsed but invalid signature. */ + secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); + + /* Sequence tag byte */ + if (pos == inputlen || input[pos] != 0x30) { + return 0; + } + pos++; + + /* Sequence length bytes */ + if (pos == inputlen) { + return 0; + } + lenbyte = input[pos++]; + if (lenbyte & 0x80) { + lenbyte -= 0x80; + if (pos + lenbyte > inputlen) { + return 0; + } + pos += lenbyte; + } + + /* Integer tag byte for R */ + if (pos == inputlen || input[pos] != 0x02) { + return 0; + } + pos++; + + /* Integer length for R */ + if (pos == inputlen) { + return 0; + } + lenbyte = input[pos++]; + if (lenbyte & 0x80) { + lenbyte -= 0x80; + if (pos + lenbyte > inputlen) { + return 0; + } + while (lenbyte > 0 && input[pos] == 0) { + pos++; + lenbyte--; + } + if (lenbyte >= sizeof(size_t)) { + return 0; + } + rlen = 0; + while (lenbyte > 0) { + rlen = (rlen << 8) + input[pos]; + pos++; + lenbyte--; + } + } else { + rlen = lenbyte; + } + if (rlen > inputlen - pos) { + return 0; + } + rpos = pos; + pos += rlen; + + /* Integer tag byte for S */ + if (pos == inputlen || input[pos] != 0x02) { + return 0; + } + pos++; + + /* Integer length for S */ + if (pos == inputlen) { + return 0; + } + lenbyte = input[pos++]; + if (lenbyte & 0x80) { + lenbyte -= 0x80; + if (pos + lenbyte > inputlen) { + return 0; + } + while (lenbyte > 0 && input[pos] == 0) { + pos++; + lenbyte--; + } + if (lenbyte >= sizeof(size_t)) { + return 0; + } + slen = 0; + while (lenbyte > 0) { + slen = (slen << 8) + input[pos]; + pos++; + lenbyte--; + } + } else { + slen = lenbyte; + } + if (slen > inputlen - pos) { + return 0; + } + spos = pos; + pos += slen; + + /* Ignore leading zeroes in R */ + while (rlen > 0 && input[rpos] == 0) { + rlen--; + rpos++; + } + /* Copy R value */ + if (rlen > 32) { + overflow = 1; + } else { + memcpy(tmpsig + 32 - rlen, input + rpos, rlen); + } + + /* Ignore leading zeroes in S */ + while (slen > 0 && input[spos] == 0) { + slen--; + spos++; + } + /* Copy S value */ + if (slen > 32) { + overflow = 1; + } else { + memcpy(tmpsig + 64 - slen, input + spos, slen); + } + + if (!overflow) { + overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); + } + if (overflow) { + memset(tmpsig, 0, 64); + secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); + } + return 1; +} + diff --git a/src/secp256k1/contrib/lax_der_parsing.h b/src/secp256k1/contrib/lax_der_parsing.h new file mode 100644 index 0000000000..6d27871a7c --- /dev/null +++ b/src/secp256k1/contrib/lax_der_parsing.h @@ -0,0 +1,91 @@ +/********************************************************************** + * Copyright (c) 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +/**** + * Please do not link this file directly. It is not part of the libsecp256k1 + * project and does not promise any stability in its API, functionality or + * presence. Projects which use this code should instead copy this header + * and its accompanying .c file directly into their codebase. + ****/ + +/* This file defines a function that parses DER with various errors and + * violations. This is not a part of the library itself, because the allowed + * violations are chosen arbitrarily and do not follow or establish any + * standard. + * + * In many places it matters that different implementations do not only accept + * the same set of valid signatures, but also reject the same set of signatures. + * The only means to accomplish that is by strictly obeying a standard, and not + * accepting anything else. + * + * Nonetheless, sometimes there is a need for compatibility with systems that + * use signatures which do not strictly obey DER. The snippet below shows how + * certain violations are easily supported. You may need to adapt it. + * + * Do not use this for new systems. Use well-defined DER or compact signatures + * instead if you have the choice (see secp256k1_ecdsa_signature_parse_der and + * secp256k1_ecdsa_signature_parse_compact). + * + * The supported violations are: + * - All numbers are parsed as nonnegative integers, even though X.609-0207 + * section 8.3.3 specifies that integers are always encoded as two's + * complement. + * - Integers can have length 0, even though section 8.3.1 says they can't. + * - Integers with overly long padding are accepted, violation section + * 8.3.2. + * - 127-byte long length descriptors are accepted, even though section + * 8.1.3.5.c says that they are not. + * - Trailing garbage data inside or after the signature is ignored. + * - The length descriptor of the sequence is ignored. + * + * Compared to for example OpenSSL, many violations are NOT supported: + * - Using overly long tag descriptors for the sequence or integers inside, + * violating section 8.1.2.2. + * - Encoding primitive integers as constructed values, violating section + * 8.3.1. + */ + +#ifndef _SECP256K1_CONTRIB_LAX_DER_PARSING_H_ +#define _SECP256K1_CONTRIB_LAX_DER_PARSING_H_ + +#include <secp256k1.h> + +# ifdef __cplusplus +extern "C" { +# endif + +/** Parse a signature in "lax DER" format + * + * Returns: 1 when the signature could be parsed, 0 otherwise. + * Args: ctx: a secp256k1 context object + * Out: sig: a pointer to a signature object + * In: input: a pointer to the signature to be parsed + * inputlen: the length of the array pointed to be input + * + * This function will accept any valid DER encoded signature, even if the + * encoded numbers are out of range. In addition, it will accept signatures + * which violate the DER spec in various ways. Its purpose is to allow + * validation of the Bitcoin blockchain, which includes non-DER signatures + * from before the network rules were updated to enforce DER. Note that + * the set of supported violations is a strict subset of what OpenSSL will + * accept. + * + * After the call, sig will always be initialized. If parsing failed or the + * encoded numbers are out of range, signature validation with it is + * guaranteed to fail for every message and public key. + */ +int ecdsa_signature_parse_der_lax( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature* sig, + const unsigned char *input, + size_t inputlen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/secp256k1/contrib/lax_der_privatekey_parsing.c b/src/secp256k1/contrib/lax_der_privatekey_parsing.c new file mode 100644 index 0000000000..c2e63b4b8d --- /dev/null +++ b/src/secp256k1/contrib/lax_der_privatekey_parsing.c @@ -0,0 +1,113 @@ +/********************************************************************** + * Copyright (c) 2014, 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#include <string.h> +#include <secp256k1.h> + +#include "lax_der_privatekey_parsing.h" + +int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *out32, const unsigned char *privkey, size_t privkeylen) { + const unsigned char *end = privkey + privkeylen; + int lenb = 0; + int len = 0; + memset(out32, 0, 32); + /* sequence header */ + if (end < privkey+1 || *privkey != 0x30) { + return 0; + } + privkey++; + /* sequence length constructor */ + 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 */ + 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; + } + memcpy(out32 + 32 - privkey[1], privkey + 2, privkey[1]); + if (!secp256k1_ec_seckey_verify(ctx, out32)) { + memset(out32, 0, 32); + return 0; + } + return 1; +} + +int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) { + secp256k1_pubkey pubkey; + size_t pubkeylen = 0; + if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) { + *privkeylen = 0; + return 0; + } + 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); + memcpy(ptr, key32, 32); ptr += 32; + memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); + pubkeylen = 33; + secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED); + 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); + memcpy(ptr, key32, 32); ptr += 32; + memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); + pubkeylen = 65; + secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED); + ptr += pubkeylen; + *privkeylen = ptr - privkey; + } + return 1; +} diff --git a/src/secp256k1/contrib/lax_der_privatekey_parsing.h b/src/secp256k1/contrib/lax_der_privatekey_parsing.h new file mode 100644 index 0000000000..2fd088f8ab --- /dev/null +++ b/src/secp256k1/contrib/lax_der_privatekey_parsing.h @@ -0,0 +1,90 @@ +/********************************************************************** + * Copyright (c) 2014, 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +/**** + * Please do not link this file directly. It is not part of the libsecp256k1 + * project and does not promise any stability in its API, functionality or + * presence. Projects which use this code should instead copy this header + * and its accompanying .c file directly into their codebase. + ****/ + +/* This file contains code snippets that parse DER private keys with + * various errors and violations. This is not a part of the library + * itself, because the allowed violations are chosen arbitrarily and + * do not follow or establish any standard. + * + * It also contains code to serialize private keys in a compatible + * manner. + * + * These functions are meant for compatibility with applications + * that require BER encoded keys. When working with secp256k1-specific + * code, the simple 32-byte private keys normally used by the + * library are sufficient. + */ + +#ifndef _SECP256K1_CONTRIB_BER_PRIVATEKEY_H_ +#define _SECP256K1_CONTRIB_BER_PRIVATEKEY_H_ + +#include <secp256k1.h> + +# ifdef __cplusplus +extern "C" { +# endif + +/** Export a private key in DER format. + * + * Returns: 1 if the private key was valid. + * Args: ctx: pointer to a context object, initialized for signing (cannot + * be NULL) + * Out: privkey: pointer to an array for storing the private key in BER. + * Should have space for 279 bytes, and cannot be NULL. + * privkeylen: Pointer to an int where the length of the private key in + * privkey will be stored. + * In: seckey: pointer to a 32-byte secret key to export. + * compressed: 1 if the key should be exported in + * compressed format, 0 otherwise + * + * This function is purely meant for compatibility with applications that + * require BER encoded keys. When working with secp256k1-specific code, the + * simple 32-byte private keys are sufficient. + * + * Note that this function does not guarantee correct DER output. It is + * guaranteed to be parsable by secp256k1_ec_privkey_import_der + */ +SECP256K1_WARN_UNUSED_RESULT int ec_privkey_export_der( + const secp256k1_context* ctx, + unsigned char *privkey, + size_t *privkeylen, + const unsigned char *seckey, + int compressed +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Import a private key in DER format. + * Returns: 1 if a private key was extracted. + * Args: ctx: pointer to a context object (cannot be NULL). + * Out: seckey: pointer to a 32-byte array for storing the private key. + * (cannot be NULL). + * In: privkey: pointer to a private key in DER format (cannot be NULL). + * privkeylen: length of the DER private key pointed to be privkey. + * + * This function will accept more than just strict DER, and even allow some BER + * violations. The public key stored inside the DER-encoded private key is not + * verified for correctness, nor are the curve parameters. Use this function + * only if you know in advance it is supposed to contain a secp256k1 private + * key. + */ +SECP256K1_WARN_UNUSED_RESULT int ec_privkey_import_der( + const secp256k1_context* ctx, + unsigned char *seckey, + const unsigned char *privkey, + size_t privkeylen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/secp256k1/include/secp256k1.h b/src/secp256k1/include/secp256k1.h index 06afd4c65b..7145dbcc54 100644 --- a/src/secp256k1/include/secp256k1.h +++ b/src/secp256k1/include/secp256k1.h @@ -5,6 +5,99 @@ extern "C" { # endif +#include <stddef.h> + +/* These rules specify the order of arguments in API calls: + * + * 1. Context pointers go first, followed by output arguments, combined + * output/input arguments, and finally input-only arguments. + * 2. Array lengths always immediately the follow the argument whose length + * they describe, even if this violates rule 1. + * 3. Within the OUT/OUTIN/IN groups, pointers to data that is typically generated + * later go first. This means: signatures, public nonces, private nonces, + * messages, public keys, secret keys, tweaks. + * 4. Arguments that are not data pointers go last, from more complex to less + * complex: function pointers, algorithm names, messages, void pointers, + * counts, flags, booleans. + * 5. Opaque data pointers follow the function pointer they are to be passed to. + */ + +/** Opaque data structure that holds context information (precomputed tables etc.). + * + * The purpose of context structures is to cache large precomputed data tables + * that are expensive to construct, and also to maintain the randomization data + * for blinding. + * + * Do not create a new context object for each operation, as construction is + * far slower than all other API calls (~100 times slower than an ECDSA + * verification). + * + * A constructed context can safely be used from multiple threads + * simultaneously, but API call that take a non-const pointer to a context + * need exclusive access to it. In particular this is the case for + * secp256k1_context_destroy and secp256k1_context_randomize. + * + * Regarding randomization, either do it once at creation time (in which case + * you do not need any locking for the other calls), or use a read-write lock. + */ +typedef struct secp256k1_context_struct secp256k1_context; + +/** Opaque data structure that holds a parsed and valid public key. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 64 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage or transmission, use + * secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. + * + * Furthermore, it is guaranteed that identical public keys (ignoring + * compression) will have identical representation, so they can be memcmp'ed. + */ +typedef struct { + unsigned char data[64]; +} secp256k1_pubkey; + +/** Opaque data structured that holds a parsed ECDSA signature. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 64 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage or transmission, use + * the secp256k1_ecdsa_signature_serialize_* and + * secp256k1_ecdsa_signature_serialize_* functions. + * + * Furthermore, it is guaranteed to identical signatures will have identical + * representation, so they can be memcmp'ed. + */ +typedef struct { + unsigned char data[64]; +} secp256k1_ecdsa_signature; + +/** A pointer to a function to deterministically generate a nonce. + * + * Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail. + * Out: nonce32: pointer to a 32-byte array to be filled by the function. + * In: msg32: the 32-byte message hash being verified (will not be NULL) + * key32: pointer to a 32-byte secret key (will not be NULL) + * algo16: pointer to a 16-byte array describing the signature + * algorithm (will be NULL for ECDSA for compatibility). + * data: Arbitrary data pointer that is passed through. + * attempt: how many iterations we have tried to find a nonce. + * This will almost always be 0, but different attempt values + * are required to result in a different nonce. + * + * Except for test cases, this function should compute some cryptographic hash of + * the message, the algorithm, the key and the attempt. + */ +typedef int (*secp256k1_nonce_function)( + unsigned char *nonce32, + const unsigned char *msg32, + const unsigned char *key32, + const unsigned char *algo16, + void *data, + unsigned int attempt +); + # if !defined(SECP256K1_GNUC_PREREQ) # if defined(__GNUC__)&&defined(__GNUC_MINOR__) # define SECP256K1_GNUC_PREREQ(_maj,_min) \ @@ -26,6 +119,20 @@ extern "C" { # define SECP256K1_INLINE inline # endif +#ifndef SECP256K1_API +# if defined(_WIN32) +# ifdef SECP256K1_BUILD +# define SECP256K1_API __declspec(dllexport) +# else +# define SECP256K1_API +# endif +# elif defined(__GNUC__) && defined(SECP256K1_BUILD) +# define SECP256K1_API __attribute__ ((visibility ("default"))) +# else +# define SECP256K1_API +# endif +#endif + /**Warning attributes * NONNULL is not used if SECP256K1_BUILD is set to avoid the compiler optimizing out * some paranoid null checks. */ @@ -40,305 +147,434 @@ extern "C" { # define SECP256K1_ARG_NONNULL(_x) # endif -/** Opaque data structure that holds context information (precomputed tables etc.). - * Only functions that take a pointer to a non-const context require exclusive - * access to it. Multiple functions that take a pointer to a const context may - * run simultaneously. - */ -typedef struct secp256k1_context_struct secp256k1_context_t; +/** All flags' lower 8 bits indicate what they're for. Do not use directly. */ +#define SECP256K1_FLAGS_TYPE_MASK ((1 << 8) - 1) +#define SECP256K1_FLAGS_TYPE_CONTEXT (1 << 0) +#define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1) +/** The higher bits contain the actual data. Do not use directly. */ +#define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY (1 << 8) +#define SECP256K1_FLAGS_BIT_CONTEXT_SIGN (1 << 9) +#define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8) /** Flags to pass to secp256k1_context_create. */ -# define SECP256K1_CONTEXT_VERIFY (1 << 0) -# define SECP256K1_CONTEXT_SIGN (1 << 1) +#define SECP256K1_CONTEXT_VERIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) +#define SECP256K1_CONTEXT_SIGN (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN) +#define SECP256K1_CONTEXT_NONE (SECP256K1_FLAGS_TYPE_CONTEXT) + +/** Flag to pass to secp256k1_ec_pubkey_serialize and secp256k1_ec_privkey_export. */ +#define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION) +#define SECP256K1_EC_UNCOMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION) /** Create a secp256k1 context object. + * * Returns: a newly created context object. * In: flags: which parts of the context to initialize. */ -secp256k1_context_t* secp256k1_context_create( - int flags +SECP256K1_API secp256k1_context* secp256k1_context_create( + unsigned int flags ) SECP256K1_WARN_UNUSED_RESULT; /** Copies a secp256k1 context object. + * * Returns: a newly created context object. - * In: ctx: an existing context to copy + * Args: ctx: an existing context to copy (cannot be NULL) */ -secp256k1_context_t* secp256k1_context_clone( - const secp256k1_context_t* ctx -) SECP256K1_WARN_UNUSED_RESULT; +SECP256K1_API secp256k1_context* secp256k1_context_clone( + const secp256k1_context* ctx +) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; /** Destroy a secp256k1 context object. + * * The context pointer may not be used afterwards. + * Args: ctx: an existing context to destroy (cannot be NULL) + */ +SECP256K1_API void secp256k1_context_destroy( + secp256k1_context* ctx +); + +/** Set a callback function to be called when an illegal argument is passed to + * an API call. It will only trigger for violations that are mentioned + * explicitly in the header. + * + * The philosophy is that these shouldn't be dealt with through a + * specific return value, as calling code should not have branches to deal with + * the case that this code itself is broken. + * + * On the other hand, during debug stage, one would want to be informed about + * such mistakes, and the default (crashing) may be inadvisable. + * When this callback is triggered, the API function called is guaranteed not + * to cause a crash, though its return value and output arguments are + * undefined. + * + * Args: ctx: an existing context object (cannot be NULL) + * In: fun: a pointer to a function to call when an illegal argument is + * passed to the API, taking a message and an opaque pointer + * (NULL restores a default handler that calls abort). + * data: the opaque pointer to pass to fun above. */ -void secp256k1_context_destroy( - secp256k1_context_t* ctx +SECP256K1_API void secp256k1_context_set_illegal_callback( + secp256k1_context* ctx, + void (*fun)(const char* message, void* data), + const void* data ) SECP256K1_ARG_NONNULL(1); +/** Set a callback function to be called when an internal consistency check + * fails. The default is crashing. + * + * This can only trigger in case of a hardware failure, miscompilation, + * memory corruption, serious bug in the library, or other error would can + * otherwise result in undefined behaviour. It will not trigger due to mere + * incorrect usage of the API (see secp256k1_context_set_illegal_callback + * for that). After this callback returns, anything may happen, including + * crashing. + * + * Args: ctx: an existing context object (cannot be NULL) + * In: fun: a pointer to a function to call when an internal error occurs, + * taking a message and an opaque pointer (NULL restores a default + * handler that calls abort). + * data: the opaque pointer to pass to fun above. + */ +SECP256K1_API void secp256k1_context_set_error_callback( + secp256k1_context* ctx, + void (*fun)(const char* message, void* data), + const void* data +) SECP256K1_ARG_NONNULL(1); + +/** Parse a variable-length public key into the pubkey object. + * + * Returns: 1 if the public key was fully valid. + * 0 if the public key could not be parsed or is invalid. + * Args: ctx: a secp256k1 context object. + * Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a + * parsed version of input. If not, its value is undefined. + * In: input: pointer to a serialized public key + * inputlen: length of the array pointed to by input + * + * This function supports parsing compressed (33 bytes, header byte 0x02 or + * 0x03), uncompressed (65 bytes, header byte 0x04), or hybrid (65 bytes, header + * byte 0x06 or 0x07) format public keys. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse( + const secp256k1_context* ctx, + secp256k1_pubkey* pubkey, + const unsigned char *input, + size_t inputlen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize a pubkey object into a serialized byte sequence. + * + * Returns: 1 always. + * Args: ctx: a secp256k1 context object. + * Out: output: a pointer to a 65-byte (if compressed==0) or 33-byte (if + * compressed==1) byte array to place the serialized key + * in. + * In/Out: outputlen: a pointer to an integer which is initially set to the + * size of output, and is overwritten with the written + * size. + * In: pubkey: a pointer to a secp256k1_pubkey containing an + * initialized public key. + * flags: SECP256K1_EC_COMPRESSED if serialization should be in + * compressed format, otherwise SECP256K1_EC_UNCOMPRESSED. + */ +SECP256K1_API int secp256k1_ec_pubkey_serialize( + const secp256k1_context* ctx, + unsigned char *output, + size_t *outputlen, + const secp256k1_pubkey* pubkey, + unsigned int flags +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Parse an ECDSA signature in compact (64 bytes) format. + * + * Returns: 1 when the signature could be parsed, 0 otherwise. + * Args: ctx: a secp256k1 context object + * Out: sig: a pointer to a signature object + * In: input64: a pointer to the 64-byte array to parse + * + * The signature must consist of a 32-byte big endian R value, followed by a + * 32-byte big endian S value. If R or S fall outside of [0..order-1], the + * encoding is invalid. R and S with value 0 are allowed in the encoding. + * + * After the call, sig will always be initialized. If parsing failed or R or + * S are zero, the resulting sig value is guaranteed to fail validation for any + * message and public key. + */ +SECP256K1_API int secp256k1_ecdsa_signature_parse_compact( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature* sig, + const unsigned char *input64 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Parse a DER ECDSA signature. + * + * Returns: 1 when the signature could be parsed, 0 otherwise. + * Args: ctx: a secp256k1 context object + * Out: sig: a pointer to a signature object + * In: input: a pointer to the signature to be parsed + * inputlen: the length of the array pointed to be input + * + * This function will accept any valid DER encoded signature, even if the + * encoded numbers are out of range. + * + * After the call, sig will always be initialized. If parsing failed or the + * encoded numbers are out of range, signature validation with it is + * guaranteed to fail for every message and public key. + */ +SECP256K1_API int secp256k1_ecdsa_signature_parse_der( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature* sig, + const unsigned char *input, + size_t inputlen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize an ECDSA signature in DER format. + * + * Returns: 1 if enough space was available to serialize, 0 otherwise + * Args: ctx: a secp256k1 context object + * Out: output: a pointer to an array to store the DER serialization + * In/Out: outputlen: a pointer to a length integer. Initially, this integer + * should be set to the length of output. After the call + * it will be set to the length of the serialization (even + * if 0 was returned). + * In: sig: a pointer to an initialized signature object + */ +SECP256K1_API int secp256k1_ecdsa_signature_serialize_der( + const secp256k1_context* ctx, + unsigned char *output, + size_t *outputlen, + const secp256k1_ecdsa_signature* sig +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Serialize an ECDSA signature in compact (64 byte) format. + * + * Returns: 1 + * Args: ctx: a secp256k1 context object + * Out: output64: a pointer to a 64-byte array to store the compact serialization + * In: sig: a pointer to an initialized signature object + * + * See secp256k1_ecdsa_signature_parse_compact for details about the encoding. + */ +SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact( + const secp256k1_context* ctx, + unsigned char *output64, + const secp256k1_ecdsa_signature* sig +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + /** Verify an ECDSA signature. + * * Returns: 1: correct signature - * 0: incorrect signature - * -1: invalid public key - * -2: invalid signature - * In: ctx: a secp256k1 context object, initialized for verification. + * 0: incorrect or unparseable signature + * Args: ctx: a secp256k1 context object, initialized for verification. + * In: sig: the signature being verified (cannot be NULL) * 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 + * pubkey: pointer to an initialized public key to verify with (cannot be NULL) + * + * To avoid accepting malleable signatures, only ECDSA signatures in lower-S + * form are accepted. + * + * If you need to accept ECDSA signatures from sources that do not obey this + * rule, apply secp256k1_ecdsa_signature_normalize to the signature prior to + * validation, but be aware that doing so results in malleable signatures. + * + * For details, see the comments for that function. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( - const secp256k1_context_t* ctx, - const unsigned char *msg32, - const unsigned char *sig, - int siglen, - const unsigned char *pubkey, - int pubkeylen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( + const secp256k1_context* ctx, + const secp256k1_ecdsa_signature *sig, + const unsigned char *msg32, + const secp256k1_pubkey *pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); -/** A pointer to a function to deterministically generate a nonce. - * Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail. - * In: msg32: the 32-byte message hash being verified (will not be NULL) - * key32: pointer to a 32-byte secret key (will not be NULL) - * attempt: how many iterations we have tried to find a nonce. - * This will almost always be 0, but different attempt values - * are required to result in a different nonce. - * data: Arbitrary data pointer that is passed through. - * Out: nonce32: pointer to a 32-byte array to be filled by the function. - * Except for test cases, this function should compute some cryptographic hash of - * the message, the key and the attempt. +/** Convert a signature to a normalized lower-S form. + * + * Returns: 1 if sigin was not normalized, 0 if it already was. + * Args: ctx: a secp256k1 context object + * Out: sigout: a pointer to a signature to fill with the normalized form, + * or copy if the input was already normalized. (can be NULL if + * you're only interested in whether the input was already + * normalized). + * In: sigin: a pointer to a signature to check/normalize (cannot be NULL, + * can be identical to sigout) + * + * With ECDSA a third-party can forge a second distinct signature of the same + * message, given a single initial signature, but without knowing the key. This + * is done by negating the S value modulo the order of the curve, 'flipping' + * the sign of the random point R which is not included in the signature. + * + * Forgery of the same message isn't universally problematic, but in systems + * where message malleability or uniqueness of signatures is important this can + * cause issues. This forgery can be blocked by all verifiers forcing signers + * to use a normalized form. + * + * The lower-S form reduces the size of signatures slightly on average when + * variable length encodings (such as DER) are used and is cheap to verify, + * making it a good choice. Security of always using lower-S is assured because + * anyone can trivially modify a signature after the fact to enforce this + * property anyway. + * + * The lower S value is always between 0x1 and + * 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, + * inclusive. + * + * No other forms of ECDSA malleability are known and none seem likely, but + * there is no formal proof that ECDSA, even with this additional restriction, + * is free of other malleability. Commonly used serialization schemes will also + * accept various non-unique encodings, so care should be taken when this + * property is required for an application. + * + * The secp256k1_ecdsa_sign function will by default create signatures in the + * lower-S form, and secp256k1_ecdsa_verify will not accept others. In case + * signatures come from a system that cannot enforce this property, + * secp256k1_ecdsa_signature_normalize must be called before verification. */ -typedef int (*secp256k1_nonce_function_t)( - unsigned char *nonce32, - const unsigned char *msg32, - const unsigned char *key32, - unsigned int attempt, - const void *data -); +SECP256K1_API int secp256k1_ecdsa_signature_normalize( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature *sigout, + const secp256k1_ecdsa_signature *sigin +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3); /** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function. * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of * extra entropy. */ -extern const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979; +SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; /** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */ -extern const secp256k1_nonce_function_t secp256k1_nonce_function_default; - +SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_default; /** Create an ECDSA signature. + * * Returns: 1: signature created - * 0: the nonce generation function failed, the private key was invalid, or there is not - * enough space in the signature (as indicated by siglen). - * In: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) + * 0: the nonce generation function failed, or the private key was invalid. + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) * Out: 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). - * - * The sig always has an s value in the lower half of the range (From 0x1 - * to 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, - * inclusive), unlike many other implementations. - * With ECDSA a third-party can can forge a second distinct signature - * of the same message given a single initial signature without knowing - * the key by setting s to its additive inverse mod-order, 'flipping' the - * sign of the random point R which is not included in the signature. - * Since the forgery is of the same message this isn't universally - * problematic, but in systems where message malleability or uniqueness - * of signatures is important this can cause issues. This forgery can be - * blocked by all verifiers forcing signers to use a canonical form. The - * lower-S form reduces the size of signatures slightly on average when - * variable length encodings (such as DER) are used and is cheap to - * verify, making it a good choice. Security of always using lower-S is - * assured because anyone can trivially modify a signature after the - * fact to enforce this property. Adjusting it inside the signing - * function avoids the need to re-serialize or have curve specific - * constants outside of the library. By always using a canonical form - * even in applications where it isn't needed it becomes possible to - * impose a requirement later if a need is discovered. - * No other forms of ECDSA malleability are known and none seem likely, - * but there is no formal proof that ECDSA, even with this additional - * restriction, is free of other malleability. Commonly used serialization - * schemes will also accept various non-unique encodings, so care should - * be taken when this property is required for an application. - */ -int secp256k1_ecdsa_sign( - const secp256k1_context_t* ctx, - const unsigned char *msg32, - unsigned char *sig, - int *siglen, - const unsigned char *seckey, - secp256k1_nonce_function_t noncefp, - const void *ndata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); - -/** Create a compact ECDSA signature (64 byte + recovery id). - * Returns: 1: signature created - * 0: the nonce generation function failed, or the secret key was invalid. - * In: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * msg32: the 32-byte message hash being signed (cannot be NULL) + * In: msg32: the 32-byte message hash being signed (cannot be NULL) * seckey: pointer to a 32-byte secret key (cannot be NULL) * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) - * Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL) - * In case 0 is returned, the returned signature length will be zero. - * recid: pointer to an int, which will be updated to contain the recovery id (can be NULL) + * + * The created signature is always in lower-S form. See + * secp256k1_ecdsa_signature_normalize for more details. */ -int secp256k1_ecdsa_sign_compact( - const secp256k1_context_t* ctx, - const unsigned char *msg32, - unsigned char *sig64, - const unsigned char *seckey, - secp256k1_nonce_function_t noncefp, - const void *ndata, - int *recid +SECP256K1_API int secp256k1_ecdsa_sign( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature *sig, + const unsigned char *msg32, + const unsigned char *seckey, + secp256k1_nonce_function noncefp, + const void *ndata ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); -/** Recover an ECDSA public key from a compact signature. - * Returns: 1: public key successfully recovered (which guarantees a correct signature). - * 0: otherwise. - * In: ctx: pointer to a context object, initialized for verification (cannot be NULL) - * msg32: the 32-byte message hash assumed to be signed (cannot be NULL) - * sig64: signature as 64 byte array (cannot be NULL) - * compressed: whether to recover a compressed or uncompressed pubkey - * recid: the recovery id (0-3, as returned by ecdsa_sign_compact) - * Out: pubkey: pointer to a 33 or 65 byte array to put the pubkey (cannot be NULL) - * pubkeylen: pointer to an int that will contain the pubkey length (cannot be NULL) - */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover_compact( - const secp256k1_context_t* ctx, - const unsigned char *msg32, - const unsigned char *sig64, - unsigned char *pubkey, - int *pubkeylen, - int compressed, - int recid -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); - /** Verify an ECDSA secret key. + * * Returns: 1: secret key is valid * 0: secret key is invalid - * In: ctx: pointer to a context object (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) + * Args: ctx: pointer to a context object (cannot be NULL) + * In: seckey: pointer to a 32-byte secret key (cannot be NULL) */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify( - const secp256k1_context_t* ctx, - const unsigned char *seckey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); - -/** Just validate a public key. - * Returns: 1: public key is valid - * 0: public key is invalid - * In: ctx: pointer to a context object (cannot be NULL) - * pubkey: pointer to a 33-byte or 65-byte public key (cannot be NULL). - * pubkeylen: length of pubkey - */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify( - const secp256k1_context_t* ctx, - const unsigned char *pubkey, - int pubkeylen +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify( + const secp256k1_context* ctx, + const unsigned char *seckey ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); /** Compute the public key for a secret key. - * In: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * compressed: whether the computed public key should be compressed - * seckey: pointer to a 32-byte private key (cannot be NULL) - * Out: pubkey: pointer to a 33-byte (if compressed) or 65-byte (if uncompressed) - * area to store the public key (cannot be NULL) - * pubkeylen: pointer to int that will be updated to contains the pubkey's - * length (cannot be NULL) + * * Returns: 1: secret was valid, public key stores * 0: secret was invalid, try again + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * Out: pubkey: pointer to the created public key (cannot be NULL) + * In: seckey: pointer to a 32-byte private key (cannot be NULL) */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( - const secp256k1_context_t* ctx, - unsigned char *pubkey, - int *pubkeylen, - const unsigned char *seckey, - int compressed -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Decompress a public key. - * In: ctx: pointer to a context object (cannot be NULL) - * In/Out: pubkey: pointer to a 65-byte array to put the decompressed public key. - * It must contain a 33-byte or 65-byte public key already (cannot be NULL) - * 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: pubkey was invalid - * 1: pubkey was valid, and was replaced with its decompressed version - */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_decompress( - const secp256k1_context_t* ctx, - unsigned char *pubkey, - int *pubkeylen +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const unsigned char *seckey ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); -/** Export a private key in DER format. - * In: ctx: pointer to a context object, initialized for signing (cannot be NULL) +/** Tweak a private key by adding tweak to it. + * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for + * uniformly random 32-byte arrays, or if the resulting private key + * would be invalid (only when the tweak is the complement of the + * private key). 1 otherwise. + * Args: ctx: pointer to a context object (cannot be NULL). + * In/Out: seckey: pointer to a 32-byte private key. + * In: tweak: pointer to a 32-byte tweak. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_export( - const secp256k1_context_t* ctx, - const unsigned char *seckey, - unsigned char *privkey, - int *privkeylen, - int compressed -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Import a private key in DER format. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_import( - const secp256k1_context_t* ctx, - unsigned char *seckey, - const unsigned char *privkey, - int privkeylen +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( + const secp256k1_context* ctx, + unsigned char *seckey, + const unsigned char *tweak ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); -/** Tweak a private key by adding tweak to it. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( - const secp256k1_context_t* ctx, - unsigned char *seckey, - const unsigned char *tweak +/** Tweak a public key by adding tweak times the generator to it. + * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for + * uniformly random 32-byte arrays, or if the resulting public key + * would be invalid (only when the tweak is the complement of the + * corresponding private key). 1 otherwise. + * Args: ctx: pointer to a context object initialized for validation + * (cannot be NULL). + * In/Out: pubkey: pointer to a public key object. + * In: tweak: pointer to a 32-byte tweak. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const unsigned char *tweak ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); -/** Tweak a public key by adding tweak times the generator to it. - * In: ctx: pointer to a context object, initialized for verification (cannot be NULL) +/** Tweak a private key by multiplying it by a tweak. + * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for + * uniformly random 32-byte arrays, or equal to zero. 1 otherwise. + * Args: ctx: pointer to a context object (cannot be NULL). + * In/Out: seckey: pointer to a 32-byte private key. + * In: tweak: pointer to a 32-byte tweak. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( - const secp256k1_context_t* ctx, - unsigned char *pubkey, - int pubkeylen, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); - -/** Tweak a private key by multiplying it with tweak. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( - const secp256k1_context_t* ctx, - unsigned char *seckey, - const unsigned char *tweak +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( + const secp256k1_context* ctx, + unsigned char *seckey, + const unsigned char *tweak ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); -/** Tweak a public key by multiplying it with tweak. - * In: ctx: pointer to a context object, initialized for verification (cannot be NULL) +/** Tweak a public key by multiplying it by a tweak value. + * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for + * uniformly random 32-byte arrays, or equal to zero. 1 otherwise. + * Args: ctx: pointer to a context object initialized for validation + * (cannot be NULL). + * In/Out: pubkey: pointer to a public key obkect. + * In: tweak: pointer to a 32-byte tweak. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul( - const secp256k1_context_t* ctx, - unsigned char *pubkey, - int pubkeylen, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const unsigned char *tweak +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Updates the context randomization. * Returns: 1: randomization successfully updated * 0: error - * In: ctx: pointer to a context object (cannot be NULL) - * seed32: pointer to a 32-byte random seed (NULL resets to initial state) + * Args: ctx: pointer to a context object (cannot be NULL) + * In: seed32: pointer to a 32-byte random seed (NULL resets to initial state) */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize( - secp256k1_context_t* ctx, - const unsigned char *seed32 +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize( + secp256k1_context* ctx, + const unsigned char *seed32 ) SECP256K1_ARG_NONNULL(1); +/** Add a number of public keys together. + * Returns: 1: the sum of the public keys is valid. + * 0: the sum of the public keys is not valid. + * Args: ctx: pointer to a context object + * Out: out: pointer to a public key object for placing the resulting public key + * (cannot be NULL) + * In: ins: pointer to array of pointers to public keys (cannot be NULL) + * n: the number of public keys to add together (must be at least 1) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine( + const secp256k1_context* ctx, + secp256k1_pubkey *out, + const secp256k1_pubkey * const * ins, + size_t n +) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); # ifdef __cplusplus } diff --git a/src/secp256k1/include/secp256k1_ecdh.h b/src/secp256k1/include/secp256k1_ecdh.h new file mode 100644 index 0000000000..4b84d7a963 --- /dev/null +++ b/src/secp256k1/include/secp256k1_ecdh.h @@ -0,0 +1,31 @@ +#ifndef _SECP256K1_ECDH_ +# define _SECP256K1_ECDH_ + +# include "secp256k1.h" + +# ifdef __cplusplus +extern "C" { +# endif + +/** Compute an EC Diffie-Hellman secret in constant time + * Returns: 1: exponentiation was successful + * 0: scalar was invalid (zero or overflow) + * Args: ctx: pointer to a context object (cannot be NULL) + * Out: result: a 32-byte array which will be populated by an ECDH + * secret computed from the point and scalar + * In: pubkey: a pointer to a secp256k1_pubkey containing an + * initialized public key + * privkey: a 32-byte scalar with which to multiply the point + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh( + const secp256k1_context* ctx, + unsigned char *result, + const secp256k1_pubkey *pubkey, + const unsigned char *privkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/src/secp256k1/include/secp256k1_recovery.h b/src/secp256k1/include/secp256k1_recovery.h new file mode 100644 index 0000000000..0553797253 --- /dev/null +++ b/src/secp256k1/include/secp256k1_recovery.h @@ -0,0 +1,110 @@ +#ifndef _SECP256K1_RECOVERY_ +# define _SECP256K1_RECOVERY_ + +# include "secp256k1.h" + +# ifdef __cplusplus +extern "C" { +# endif + +/** Opaque data structured that holds a parsed ECDSA signature, + * supporting pubkey recovery. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 65 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage or transmission, use + * the secp256k1_ecdsa_signature_serialize_* and + * secp256k1_ecdsa_signature_parse_* functions. + * + * Furthermore, it is guaranteed that identical signatures (including their + * recoverability) will have identical representation, so they can be + * memcmp'ed. + */ +typedef struct { + unsigned char data[65]; +} secp256k1_ecdsa_recoverable_signature; + +/** Parse a compact ECDSA signature (64 bytes + recovery id). + * + * Returns: 1 when the signature could be parsed, 0 otherwise + * Args: ctx: a secp256k1 context object + * Out: sig: a pointer to a signature object + * In: input64: a pointer to a 64-byte compact signature + * recid: the recovery id (0, 1, 2 or 3) + */ +SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact( + const secp256k1_context* ctx, + secp256k1_ecdsa_recoverable_signature* sig, + const unsigned char *input64, + int recid +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Convert a recoverable signature into a normal signature. + * + * Returns: 1 + * Out: sig: a pointer to a normal signature (cannot be NULL). + * In: sigin: a pointer to a recoverable signature (cannot be NULL). + */ +SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature* sig, + const secp256k1_ecdsa_recoverable_signature* sigin +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize an ECDSA signature in compact format (64 bytes + recovery id). + * + * Returns: 1 + * Args: ctx: a secp256k1 context object + * Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL) + * recid: a pointer to an integer to hold the recovery id (can be NULL). + * In: sig: a pointer to an initialized signature object (cannot be NULL) + */ +SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact( + const secp256k1_context* ctx, + unsigned char *output64, + int *recid, + const secp256k1_ecdsa_recoverable_signature* sig +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Create a recoverable ECDSA signature. + * + * Returns: 1: signature created + * 0: the nonce generation function failed, or the private key was invalid. + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) + * In: msg32: the 32-byte message hash being signed (cannot be NULL) + * seckey: pointer to a 32-byte secret key (cannot be NULL) + * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used + * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) + */ +SECP256K1_API int secp256k1_ecdsa_sign_recoverable( + const secp256k1_context* ctx, + secp256k1_ecdsa_recoverable_signature *sig, + const unsigned char *msg32, + const unsigned char *seckey, + secp256k1_nonce_function noncefp, + const void *ndata +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Recover an ECDSA public key from a signature. + * + * Returns: 1: public key successfully recovered (which guarantees a correct signature). + * 0: otherwise. + * Args: ctx: pointer to a context object, initialized for verification (cannot be NULL) + * Out: pubkey: pointer to the recovered public key (cannot be NULL) + * In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL) + * msg32: the 32-byte message hash assumed to be signed (cannot be NULL) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const secp256k1_ecdsa_recoverable_signature *sig, + const unsigned char *msg32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/src/secp256k1/include/secp256k1_schnorr.h b/src/secp256k1/include/secp256k1_schnorr.h new file mode 100644 index 0000000000..dc32fec1ea --- /dev/null +++ b/src/secp256k1/include/secp256k1_schnorr.h @@ -0,0 +1,173 @@ +#ifndef _SECP256K1_SCHNORR_ +# define _SECP256K1_SCHNORR_ + +# include "secp256k1.h" + +# ifdef __cplusplus +extern "C" { +# endif + +/** Create a signature using a custom EC-Schnorr-SHA256 construction. It + * produces non-malleable 64-byte signatures which support public key recovery + * batch validation, and multiparty signing. + * Returns: 1: signature created + * 0: the nonce generation function failed, or the private key was + * invalid. + * Args: ctx: pointer to a context object, initialized for signing + * (cannot be NULL) + * Out: sig64: pointer to a 64-byte array where the signature will be + * placed (cannot be NULL) + * In: msg32: the 32-byte message hash being signed (cannot be NULL) + * seckey: pointer to a 32-byte secret key (cannot be NULL) + * noncefp:pointer to a nonce generation function. If NULL, + * secp256k1_nonce_function_default is used + * ndata: pointer to arbitrary data used by the nonce generation + * function (can be NULL) + */ +SECP256K1_API int secp256k1_schnorr_sign( + const secp256k1_context* ctx, + unsigned char *sig64, + const unsigned char *msg32, + const unsigned char *seckey, + secp256k1_nonce_function noncefp, + const void *ndata +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Verify a signature created by secp256k1_schnorr_sign. + * Returns: 1: correct signature + * 0: incorrect signature + * Args: ctx: a secp256k1 context object, initialized for verification. + * In: sig64: the 64-byte signature being verified (cannot be NULL) + * msg32: the 32-byte message hash being verified (cannot be NULL) + * pubkey: the public key to verify with (cannot be NULL) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_verify( + const secp256k1_context* ctx, + const unsigned char *sig64, + const unsigned char *msg32, + const secp256k1_pubkey *pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Recover an EC public key from a Schnorr signature created using + * secp256k1_schnorr_sign. + * Returns: 1: public key successfully recovered (which guarantees a correct + * signature). + * 0: otherwise. + * Args: ctx: pointer to a context object, initialized for + * verification (cannot be NULL) + * Out: pubkey: pointer to a pubkey to set to the recovered public key + * (cannot be NULL). + * In: sig64: signature as 64 byte array (cannot be NULL) + * msg32: the 32-byte message hash assumed to be signed (cannot + * be NULL) + */ +SECP256K1_API int secp256k1_schnorr_recover( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const unsigned char *sig64, + const unsigned char *msg32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Generate a nonce pair deterministically for use with + * secp256k1_schnorr_partial_sign. + * Returns: 1: valid nonce pair was generated. + * 0: otherwise (nonce generation function failed) + * Args: ctx: pointer to a context object, initialized for signing + * (cannot be NULL) + * Out: pubnonce: public side of the nonce (cannot be NULL) + * privnonce32: private side of the nonce (32 byte) (cannot be NULL) + * In: msg32: the 32-byte message hash assumed to be signed (cannot + * be NULL) + * sec32: the 32-byte private key (cannot be NULL) + * noncefp: pointer to a nonce generation function. If NULL, + * secp256k1_nonce_function_default is used + * noncedata: pointer to arbitrary data used by the nonce generation + * function (can be NULL) + * + * Do not use the output as a private/public key pair for signing/validation. + */ +SECP256K1_API int secp256k1_schnorr_generate_nonce_pair( + const secp256k1_context* ctx, + secp256k1_pubkey *pubnonce, + unsigned char *privnonce32, + const unsigned char *msg32, + const unsigned char *sec32, + secp256k1_nonce_function noncefp, + const void* noncedata +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Produce a partial Schnorr signature, which can be combined using + * secp256k1_schnorr_partial_combine, to end up with a full signature that is + * verifiable using secp256k1_schnorr_verify. + * Returns: 1: signature created successfully. + * 0: no valid signature exists with this combination of keys, nonces + * and message (chance around 1 in 2^128) + * -1: invalid private key, nonce, or public nonces. + * Args: ctx: pointer to context object, initialized for signing (cannot + * be NULL) + * Out: sig64: pointer to 64-byte array to put partial signature in + * In: msg32: pointer to 32-byte message to sign + * sec32: pointer to 32-byte private key + * pubnonce_others: pointer to pubkey containing the sum of the other's + * nonces (see secp256k1_ec_pubkey_combine) + * secnonce32: pointer to 32-byte array containing our nonce + * + * The intended procedure for creating a multiparty signature is: + * - Each signer S[i] with private key x[i] and public key Q[i] runs + * secp256k1_schnorr_generate_nonce_pair to produce a pair (k[i],R[i]) of + * private/public nonces. + * - All signers communicate their public nonces to each other (revealing your + * private nonce can lead to discovery of your private key, so it should be + * considered secret). + * - All signers combine all the public nonces they received (excluding their + * own) using secp256k1_ec_pubkey_combine to obtain an + * Rall[i] = sum(R[0..i-1,i+1..n]). + * - All signers produce a partial signature using + * secp256k1_schnorr_partial_sign, passing in their own private key x[i], + * their own private nonce k[i], and the sum of the others' public nonces + * Rall[i]. + * - All signers communicate their partial signatures to each other. + * - Someone combines all partial signatures using + * secp256k1_schnorr_partial_combine, to obtain a full signature. + * - The resulting signature is validatable using secp256k1_schnorr_verify, with + * public key equal to the result of secp256k1_ec_pubkey_combine of the + * signers' public keys (sum(Q[0..n])). + * + * Note that secp256k1_schnorr_partial_combine and secp256k1_ec_pubkey_combine + * function take their arguments in any order, and it is possible to + * pre-combine several inputs already with one call, and add more inputs later + * by calling the function again (they are commutative and associative). + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_sign( + const secp256k1_context* ctx, + unsigned char *sig64, + const unsigned char *msg32, + const unsigned char *sec32, + const secp256k1_pubkey *pubnonce_others, + const unsigned char *secnonce32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6); + +/** Combine multiple Schnorr partial signatures. + * Returns: 1: the passed signatures were successfully combined. + * 0: the resulting signature is not valid (chance of 1 in 2^256) + * -1: some inputs were invalid, or the signatures were not created + * using the same set of nonces + * Args: ctx: pointer to a context object + * Out: sig64: pointer to a 64-byte array to place the combined signature + * (cannot be NULL) + * In: sig64sin: pointer to an array of n pointers to 64-byte input + * signatures + * n: the number of signatures to combine (at least 1) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_combine( + const secp256k1_context* ctx, + unsigned char *sig64, + const unsigned char * const * sig64sin, + size_t n +) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/src/secp256k1/src/basic-config.h b/src/secp256k1/src/basic-config.h new file mode 100644 index 0000000000..c4c16eb7ca --- /dev/null +++ b/src/secp256k1/src/basic-config.h @@ -0,0 +1,32 @@ +/********************************************************************** + * 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_BASIC_CONFIG_ +#define _SECP256K1_BASIC_CONFIG_ + +#ifdef USE_BASIC_CONFIG + +#undef USE_ASM_X86_64 +#undef USE_ENDOMORPHISM +#undef USE_FIELD_10X26 +#undef USE_FIELD_5X52 +#undef USE_FIELD_INV_BUILTIN +#undef USE_FIELD_INV_NUM +#undef USE_NUM_GMP +#undef USE_NUM_NONE +#undef USE_SCALAR_4X64 +#undef USE_SCALAR_8X32 +#undef USE_SCALAR_INV_BUILTIN +#undef USE_SCALAR_INV_NUM + +#define USE_NUM_NONE 1 +#define USE_FIELD_INV_BUILTIN 1 +#define USE_SCALAR_INV_BUILTIN 1 +#define USE_FIELD_10X26 1 +#define USE_SCALAR_8X32 1 + +#endif // USE_BASIC_CONFIG +#endif // _SECP256K1_BASIC_CONFIG_ diff --git a/src/secp256k1/src/bench.h b/src/secp256k1/src/bench.h index db5f68cee1..3a71b4aafa 100644 --- a/src/secp256k1/src/bench.h +++ b/src/secp256k1/src/bench.h @@ -20,7 +20,9 @@ static double gettimedouble(void) { void print_number(double x) { double y = x; int c = 0; - if (y < 0.0) y = -y; + if (y < 0.0) { + y = -y; + } while (y < 100.0) { y *= 10.0; c++; @@ -35,13 +37,21 @@ void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), v double max = 0.0; for (i = 0; i < count; i++) { double begin, total; - if (setup) setup(data); + if (setup != NULL) { + setup(data); + } begin = gettimedouble(); benchmark(data); total = gettimedouble() - begin; - if (teardown) teardown(data); - if (total < min) min = total; - if (total > max) max = total; + if (teardown != NULL) { + teardown(data); + } + if (total < min) { + min = total; + } + if (total > max) { + max = total; + } sum += total; } printf("%s: min ", name); diff --git a/src/secp256k1/src/bench_ecdh.c b/src/secp256k1/src/bench_ecdh.c new file mode 100644 index 0000000000..5a7c6376e0 --- /dev/null +++ b/src/secp256k1/src/bench_ecdh.c @@ -0,0 +1,53 @@ +/********************************************************************** + * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#include <string.h> + +#include "include/secp256k1.h" +#include "include/secp256k1_ecdh.h" +#include "util.h" +#include "bench.h" + +typedef struct { + secp256k1_context *ctx; + secp256k1_pubkey point; + unsigned char scalar[32]; +} bench_ecdh_t; + +static void bench_ecdh_setup(void* arg) { + int i; + bench_ecdh_t *data = (bench_ecdh_t*)arg; + const unsigned char point[] = { + 0x03, + 0x54, 0x94, 0xc1, 0x5d, 0x32, 0x09, 0x97, 0x06, + 0xc2, 0x39, 0x5f, 0x94, 0x34, 0x87, 0x45, 0xfd, + 0x75, 0x7c, 0xe3, 0x0e, 0x4e, 0x8c, 0x90, 0xfb, + 0xa2, 0xba, 0xd1, 0x84, 0xf8, 0x83, 0xc6, 0x9f + }; + + data->ctx = secp256k1_context_create(0); + for (i = 0; i < 32; i++) { + data->scalar[i] = i + 1; + } + CHECK(secp256k1_ec_pubkey_parse(data->ctx, &data->point, point, sizeof(point)) == 1); +} + +static void bench_ecdh(void* arg) { + int i; + unsigned char res[32]; + bench_ecdh_t *data = (bench_ecdh_t*)arg; + + for (i = 0; i < 20000; i++) { + CHECK(secp256k1_ecdh(data->ctx, res, &data->point, data->scalar) == 1); + } +} + +int main(void) { + bench_ecdh_t data; + + run_benchmark("ecdh", bench_ecdh, bench_ecdh_setup, NULL, &data, 10, 20000); + return 0; +} diff --git a/src/secp256k1/src/bench_internal.c b/src/secp256k1/src/bench_internal.c index a960549b94..7809f5f8cf 100644 --- a/src/secp256k1/src/bench_internal.c +++ b/src/secp256k1/src/bench_internal.c @@ -13,15 +13,17 @@ #include "field_impl.h" #include "group_impl.h" #include "scalar_impl.h" +#include "ecmult_const_impl.h" #include "ecmult_impl.h" #include "bench.h" +#include "secp256k1.c" typedef struct { - secp256k1_scalar_t scalar_x, scalar_y; - secp256k1_fe_t fe_x, fe_y; - secp256k1_ge_t ge_x, ge_y; - secp256k1_gej_t gej_x, gej_y; - unsigned char data[32]; + secp256k1_scalar scalar_x, scalar_y; + secp256k1_fe fe_x, fe_y; + secp256k1_ge ge_x, ge_y; + secp256k1_gej gej_x, gej_y; + unsigned char data[64]; int wnaf[256]; } bench_inv_t; @@ -51,6 +53,7 @@ void bench_setup(void* arg) { secp256k1_gej_set_ge(&data->gej_x, &data->ge_x); secp256k1_gej_set_ge(&data->gej_y, &data->ge_y); memcpy(data->data, init_x, 32); + memcpy(data->data + 32, init_y, 32); } void bench_scalar_add(void* arg) { @@ -95,8 +98,8 @@ void bench_scalar_split(void* arg) { bench_inv_t *data = (bench_inv_t*)arg; for (i = 0; i < 20000; i++) { - secp256k1_scalar_t l, r; - secp256k1_scalar_split_lambda_var(&l, &r, &data->scalar_x); + secp256k1_scalar l, r; + secp256k1_scalar_split_lambda(&l, &r, &data->scalar_x); secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); } } @@ -193,7 +196,7 @@ void bench_group_double_var(void* arg) { bench_inv_t *data = (bench_inv_t*)arg; for (i = 0; i < 200000; i++) { - secp256k1_gej_double_var(&data->gej_x, &data->gej_x); + secp256k1_gej_double_var(&data->gej_x, &data->gej_x, NULL); } } @@ -202,7 +205,7 @@ void bench_group_add_var(void* arg) { bench_inv_t *data = (bench_inv_t*)arg; for (i = 0; i < 200000; i++) { - secp256k1_gej_add_var(&data->gej_x, &data->gej_x, &data->gej_y); + secp256k1_gej_add_var(&data->gej_x, &data->gej_x, &data->gej_y, NULL); } } @@ -220,7 +223,7 @@ void bench_group_add_affine_var(void* arg) { bench_inv_t *data = (bench_inv_t*)arg; for (i = 0; i < 200000; i++) { - secp256k1_gej_add_ge_var(&data->gej_x, &data->gej_x, &data->ge_y); + secp256k1_gej_add_ge_var(&data->gej_x, &data->gej_x, &data->ge_y, NULL); } } @@ -229,7 +232,17 @@ void bench_ecmult_wnaf(void* arg) { bench_inv_t *data = (bench_inv_t*)arg; for (i = 0; i < 20000; i++) { - secp256k1_ecmult_wnaf(data->wnaf, &data->scalar_x, WINDOW_A); + secp256k1_ecmult_wnaf(data->wnaf, 256, &data->scalar_x, WINDOW_A); + secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); + } +} + +void bench_wnaf_const(void* arg) { + int i; + bench_inv_t *data = (bench_inv_t*)arg; + + for (i = 0; i < 20000; i++) { + secp256k1_wnaf_const(data->wnaf, data->scalar_x, WINDOW_A); secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); } } @@ -265,11 +278,27 @@ void bench_rfc6979_hmac_sha256(void* arg) { secp256k1_rfc6979_hmac_sha256_t rng; for (i = 0; i < 20000; i++) { - secp256k1_rfc6979_hmac_sha256_initialize(&rng, data->data, 32, data->data, 32, NULL, 0); + secp256k1_rfc6979_hmac_sha256_initialize(&rng, data->data, 64); secp256k1_rfc6979_hmac_sha256_generate(&rng, data->data, 32); } } +void bench_context_verify(void* arg) { + int i; + (void)arg; + for (i = 0; i < 20; i++) { + secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_VERIFY)); + } +} + +void bench_context_sign(void* arg) { + int i; + (void)arg; + for (i = 0; i < 200; i++) { + secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_SIGN)); + } +} + int have_flag(int argc, char** argv, char *flag) { char** argm = argv + argc; @@ -278,7 +307,9 @@ int have_flag(int argc, char** argv, char *flag) { return 1; } while (argv != NULL && argv != argm) { - if (strcmp(*argv, flag) == 0) return 1; + if (strcmp(*argv, flag) == 0) { + return 1; + } argv++; } return 0; @@ -309,10 +340,15 @@ int main(int argc, char **argv) { if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, 200000); + if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("wnaf_const", bench_wnaf_const, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "rng6979")) run_benchmark("hash_rfc6979_hmac_sha256", bench_rfc6979_hmac_sha256, bench_setup, NULL, &data, 10, 20000); + + if (have_flag(argc, argv, "context") || have_flag(argc, argv, "verify")) run_benchmark("context_verify", bench_context_verify, bench_setup, NULL, &data, 10, 20); + if (have_flag(argc, argv, "context") || have_flag(argc, argv, "sign")) run_benchmark("context_sign", bench_context_sign, bench_setup, NULL, &data, 10, 200); + return 0; } diff --git a/src/secp256k1/src/bench_recover.c b/src/secp256k1/src/bench_recover.c index 56faed11a0..6489378cc6 100644 --- a/src/secp256k1/src/bench_recover.c +++ b/src/secp256k1/src/bench_recover.c @@ -1,15 +1,16 @@ /********************************************************************** - * Copyright (c) 2014 Pieter Wuille * + * Copyright (c) 2014-2015 Pieter Wuille * * Distributed under the MIT software license, see the accompanying * * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ #include "include/secp256k1.h" +#include "include/secp256k1_recovery.h" #include "util.h" #include "bench.h" typedef struct { - secp256k1_context_t *ctx; + secp256k1_context *ctx; unsigned char msg[32]; unsigned char sig[64]; } bench_recover_t; @@ -17,16 +18,20 @@ typedef struct { void bench_recover(void* arg) { int i; bench_recover_t *data = (bench_recover_t*)arg; - unsigned char pubkey[33]; + secp256k1_pubkey pubkey; + unsigned char pubkeyc[33]; for (i = 0; i < 20000; i++) { int j; - int pubkeylen = 33; - CHECK(secp256k1_ecdsa_recover_compact(data->ctx, data->msg, data->sig, pubkey, &pubkeylen, 1, i % 2)); + size_t pubkeylen = 33; + secp256k1_ecdsa_recoverable_signature sig; + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(data->ctx, &sig, data->sig, i % 2)); + CHECK(secp256k1_ecdsa_recover(data->ctx, &pubkey, &sig, data->msg)); + CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED)); for (j = 0; j < 32; j++) { data->sig[j + 32] = data->msg[j]; /* Move former message to S. */ data->msg[j] = data->sig[j]; /* Move former R to message. */ - data->sig[j] = pubkey[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */ + data->sig[j] = pubkeyc[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */ } } } @@ -35,8 +40,12 @@ void bench_recover_setup(void* arg) { int i; bench_recover_t *data = (bench_recover_t*)arg; - for (i = 0; i < 32; i++) data->msg[i] = 1 + i; - for (i = 0; i < 64; i++) data->sig[i] = 65 + i; + for (i = 0; i < 32; i++) { + data->msg[i] = 1 + i; + } + for (i = 0; i < 64; i++) { + data->sig[i] = 65 + i; + } } int main(void) { diff --git a/src/secp256k1/src/bench_schnorr_verify.c b/src/secp256k1/src/bench_schnorr_verify.c new file mode 100644 index 0000000000..5f137dda23 --- /dev/null +++ b/src/secp256k1/src/bench_schnorr_verify.c @@ -0,0 +1,73 @@ +/********************************************************************** + * 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 "include/secp256k1_schnorr.h" +#include "util.h" +#include "bench.h" + +typedef struct { + unsigned char key[32]; + unsigned char sig[64]; + unsigned char pubkey[33]; + size_t pubkeylen; +} benchmark_schnorr_sig_t; + +typedef struct { + secp256k1_context *ctx; + unsigned char msg[32]; + benchmark_schnorr_sig_t sigs[64]; + int numsigs; +} benchmark_schnorr_verify_t; + +static void benchmark_schnorr_init(void* arg) { + int i, k; + benchmark_schnorr_verify_t* data = (benchmark_schnorr_verify_t*)arg; + + for (i = 0; i < 32; i++) { + data->msg[i] = 1 + i; + } + for (k = 0; k < data->numsigs; k++) { + secp256k1_pubkey pubkey; + for (i = 0; i < 32; i++) { + data->sigs[k].key[i] = 33 + i + k; + } + secp256k1_schnorr_sign(data->ctx, data->sigs[k].sig, data->msg, data->sigs[k].key, NULL, NULL); + data->sigs[k].pubkeylen = 33; + CHECK(secp256k1_ec_pubkey_create(data->ctx, &pubkey, data->sigs[k].key)); + CHECK(secp256k1_ec_pubkey_serialize(data->ctx, data->sigs[k].pubkey, &data->sigs[k].pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED)); + } +} + +static void benchmark_schnorr_verify(void* arg) { + int i; + benchmark_schnorr_verify_t* data = (benchmark_schnorr_verify_t*)arg; + + for (i = 0; i < 20000 / data->numsigs; i++) { + secp256k1_pubkey pubkey; + data->sigs[0].sig[(i >> 8) % 64] ^= (i & 0xFF); + CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->sigs[0].pubkey, data->sigs[0].pubkeylen)); + CHECK(secp256k1_schnorr_verify(data->ctx, data->sigs[0].sig, data->msg, &pubkey) == ((i & 0xFF) == 0)); + data->sigs[0].sig[(i >> 8) % 64] ^= (i & 0xFF); + } +} + + + +int main(void) { + benchmark_schnorr_verify_t data; + + data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + + data.numsigs = 1; + run_benchmark("schnorr_verify", benchmark_schnorr_verify, benchmark_schnorr_init, NULL, &data, 10, 20000); + + secp256k1_context_destroy(data.ctx); + return 0; +} diff --git a/src/secp256k1/src/bench_sign.c b/src/secp256k1/src/bench_sign.c index 072a37af51..ed7224d757 100644 --- a/src/secp256k1/src/bench_sign.c +++ b/src/secp256k1/src/bench_sign.c @@ -9,7 +9,7 @@ #include "bench.h" typedef struct { - secp256k1_context_t* ctx; + secp256k1_context* ctx; unsigned char msg[32]; unsigned char key[32]; } bench_sign_t; @@ -18,22 +18,28 @@ static void bench_sign_setup(void* arg) { int i; bench_sign_t *data = (bench_sign_t*)arg; - for (i = 0; i < 32; i++) data->msg[i] = i + 1; - for (i = 0; i < 32; i++) data->key[i] = i + 65; + for (i = 0; i < 32; i++) { + data->msg[i] = i + 1; + } + for (i = 0; i < 32; i++) { + data->key[i] = i + 65; + } } static void bench_sign(void* arg) { int i; bench_sign_t *data = (bench_sign_t*)arg; - unsigned char sig[64]; + unsigned char sig[74]; for (i = 0; i < 20000; i++) { + size_t siglen = 74; int j; - int recid = 0; - CHECK(secp256k1_ecdsa_sign_compact(data->ctx, data->msg, sig, data->key, NULL, NULL, &recid)); + secp256k1_ecdsa_signature signature; + CHECK(secp256k1_ecdsa_sign(data->ctx, &signature, data->msg, data->key, NULL, NULL)); + CHECK(secp256k1_ecdsa_signature_serialize_der(data->ctx, sig, &siglen, &signature)); for (j = 0; j < 32; j++) { - data->msg[j] = sig[j]; /* Move former R to message. */ - data->key[j] = sig[j + 32]; /* Move former S to key. */ + data->msg[j] = sig[j]; + data->key[j] = sig[j + 32]; } } } diff --git a/src/secp256k1/src/bench_verify.c b/src/secp256k1/src/bench_verify.c index c8c82752ce..5718320cda 100644 --- a/src/secp256k1/src/bench_verify.c +++ b/src/secp256k1/src/bench_verify.c @@ -12,13 +12,13 @@ #include "bench.h" typedef struct { - secp256k1_context_t *ctx; + secp256k1_context *ctx; unsigned char msg[32]; unsigned char key[32]; unsigned char sig[72]; - int siglen; + size_t siglen; unsigned char pubkey[33]; - int pubkeylen; + size_t pubkeylen; } benchmark_verify_t; static void benchmark_verify(void* arg) { @@ -26,10 +26,14 @@ static void benchmark_verify(void* arg) { benchmark_verify_t* data = (benchmark_verify_t*)arg; for (i = 0; i < 20000; i++) { + secp256k1_pubkey pubkey; + secp256k1_ecdsa_signature sig; 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->ctx, data->msg, data->sig, data->siglen, data->pubkey, data->pubkeylen) == (i == 0)); + CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1); + CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1); + CHECK(secp256k1_ecdsa_verify(data->ctx, &sig, data->msg, &pubkey) == (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); @@ -38,16 +42,24 @@ static void benchmark_verify(void* arg) { int main(void) { int i; + secp256k1_pubkey pubkey; + secp256k1_ecdsa_signature sig; benchmark_verify_t data; data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - for (i = 0; i < 32; i++) data.msg[i] = 1 + i; - for (i = 0; i < 32; i++) data.key[i] = 33 + i; + for (i = 0; i < 32; i++) { + data.msg[i] = 1 + i; + } + for (i = 0; i < 32; i++) { + data.key[i] = 33 + i; + } data.siglen = 72; - secp256k1_ecdsa_sign(data.ctx, data.msg, data.sig, &data.siglen, data.key, NULL, NULL); + CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL)); + CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig)); + CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key)); data.pubkeylen = 33; - CHECK(secp256k1_ec_pubkey_create(data.ctx, data.pubkey, &data.pubkeylen, data.key, 1)); + CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1); run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000); diff --git a/src/secp256k1/src/ecdsa.h b/src/secp256k1/src/ecdsa.h index 4ef78e8afb..54ae101b92 100644 --- a/src/secp256k1/src/ecdsa.h +++ b/src/secp256k1/src/ecdsa.h @@ -7,18 +7,15 @@ #ifndef _SECP256K1_ECDSA_ #define _SECP256K1_ECDSA_ +#include <stddef.h> + #include "scalar.h" #include "group.h" #include "ecmult.h" -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_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message); -static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid); -static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid); +static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size); +static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s); +static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message); +static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid); #endif diff --git a/src/secp256k1/src/ecdsa_impl.h b/src/secp256k1/src/ecdsa_impl.h index ed1d228189..d110b4bb1d 100644 --- a/src/secp256k1/src/ecdsa_impl.h +++ b/src/secp256k1/src/ecdsa_impl.h @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * + * Copyright (c) 2013-2015 Pieter Wuille * * Distributed under the MIT software license, see the accompanying * * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ @@ -28,7 +28,7 @@ * sage: '%x' % (EllipticCurve ([F (a), F (b)]).order()) * 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141' */ -static const secp256k1_fe_t secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST( +static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST( 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, 0xBAAEDCE6UL, 0xAF48A03BUL, 0xBFD25E8CUL, 0xD0364141UL ); @@ -42,82 +42,150 @@ static const secp256k1_fe_t secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CON * sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order()) * '14551231950b75fc4402da1722fc9baee' */ -static const secp256k1_fe_t secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( +static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( 0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL ); -static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size) { - unsigned char ra[32] = {0}, sa[32] = {0}; - const unsigned char *rp; - const unsigned char *sp; - int lenr; - int lens; - int overflow; - if (sig[0] != 0x30) { - return 0; +static int secp256k1_der_read_len(const unsigned char **sigp, const unsigned char *sigend) { + int lenleft, b1; + size_t ret = 0; + if (*sigp >= sigend) { + return -1; } - lenr = sig[3]; - if (5+lenr >= size) { - return 0; + b1 = *((*sigp)++); + if (b1 == 0xFF) { + /* X.690-0207 8.1.3.5.c the value 0xFF shall not be used. */ + return -1; } - lens = sig[lenr+5]; - if (sig[1] != lenr+lens+4) { - return 0; + if ((b1 & 0x80) == 0) { + /* X.690-0207 8.1.3.4 short form length octets */ + return b1; } - if (lenr+lens+6 > size) { - return 0; + if (b1 == 0x80) { + /* Indefinite length is not allowed in DER. */ + return -1; + } + /* X.690-207 8.1.3.5 long form length octets */ + lenleft = b1 & 0x7F; + if (lenleft > sigend - *sigp) { + return -1; + } + if (**sigp == 0) { + /* Not the shortest possible length encoding. */ + return -1; + } + if ((size_t)lenleft > sizeof(size_t)) { + /* The resulting length would exceed the range of a size_t, so + * certainly longer than the passed array size. + */ + return -1; + } + while (lenleft > 0) { + if ((ret >> ((sizeof(size_t) - 1) * 8)) != 0) { + } + ret = (ret << 8) | **sigp; + if (ret + lenleft > (size_t)(sigend - *sigp)) { + /* Result exceeds the length of the passed array. */ + return -1; + } + (*sigp)++; + lenleft--; + } + if (ret < 128) { + /* Not the shortest possible length encoding. */ + return -1; } - if (sig[2] != 0x02) { + return ret; +} + +static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char **sig, const unsigned char *sigend) { + int overflow = 0; + unsigned char ra[32] = {0}; + int rlen; + + if (*sig == sigend || **sig != 0x02) { + /* Not a primitive integer (X.690-0207 8.3.1). */ return 0; } - if (lenr == 0) { + (*sig)++; + rlen = secp256k1_der_read_len(sig, sigend); + if (rlen <= 0 || (*sig) + rlen > sigend) { + /* Exceeds bounds or not at least length 1 (X.690-0207 8.3.1). */ return 0; } - if (sig[lenr+4] != 0x02) { + if (**sig == 0x00 && rlen > 1 && (((*sig)[1]) & 0x80) == 0x00) { + /* Excessive 0x00 padding. */ return 0; } - if (lens == 0) { + if (**sig == 0xFF && rlen > 1 && (((*sig)[1]) & 0x80) == 0x80) { + /* Excessive 0xFF padding. */ return 0; } - sp = sig + 6 + lenr; - while (lens > 0 && sp[0] == 0) { - lens--; - sp++; + if ((**sig & 0x80) == 0x80) { + /* Negative. */ + overflow = 1; + } + while (rlen > 0 && **sig == 0) { + /* Skip leading zero bytes */ + rlen--; + (*sig)++; } - if (lens > 32) { + if (rlen > 32) { + overflow = 1; + } + if (!overflow) { + memcpy(ra + 32 - rlen, *sig, rlen); + secp256k1_scalar_set_b32(r, ra, &overflow); + } + if (overflow) { + secp256k1_scalar_set_int(r, 0); + } + (*sig) += rlen; + return 1; +} + +static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *rr, secp256k1_scalar *rs, const unsigned char *sig, size_t size) { + const unsigned char *sigend = sig + size; + int rlen; + if (sig == sigend || *(sig++) != 0x30) { + /* The encoding doesn't start with a constructed sequence (X.690-0207 8.9.1). */ return 0; } - rp = sig + 4; - while (lenr > 0 && rp[0] == 0) { - lenr--; - rp++; + rlen = secp256k1_der_read_len(&sig, sigend); + if (rlen < 0 || sig + rlen > sigend) { + /* Tuple exceeds bounds */ + return 0; } - if (lenr > 32) { + if (sig + rlen != sigend) { + /* Garbage after tuple. */ return 0; } - memcpy(ra + 32 - lenr, rp, lenr); - memcpy(sa + 32 - lens, sp, lens); - overflow = 0; - secp256k1_scalar_set_b32(&r->r, ra, &overflow); - if (overflow) { + + if (!secp256k1_der_parse_integer(rr, &sig, sigend)) { return 0; } - secp256k1_scalar_set_b32(&r->s, sa, &overflow); - if (overflow) { + if (!secp256k1_der_parse_integer(rs, &sig, sigend)) { return 0; } + + if (sig != sigend) { + /* Trailing garbage inside tuple. */ + return 0; + } + return 1; } -static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a) { +static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar* ar, const secp256k1_scalar* as) { unsigned char r[33] = {0}, s[33] = {0}; unsigned char *rp = r, *sp = s; - int lenR = 33, lenS = 33; - secp256k1_scalar_get_b32(&r[1], &a->r); - secp256k1_scalar_get_b32(&s[1], &a->s); + size_t lenR = 33, lenS = 33; + secp256k1_scalar_get_b32(&r[1], ar); + secp256k1_scalar_get_b32(&s[1], as); 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) { + *size = 6 + lenS + lenR; return 0; } *size = 6 + lenS + lenR; @@ -132,26 +200,26 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se return 1; } -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) { +static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) { unsigned char c[32]; - secp256k1_scalar_t sn, u1, u2; - secp256k1_fe_t xr; - secp256k1_gej_t pubkeyj; - secp256k1_gej_t pr; + secp256k1_scalar sn, u1, u2; + secp256k1_fe xr; + secp256k1_gej pubkeyj; + secp256k1_gej pr; - if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) { + if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { return 0; } - secp256k1_scalar_inverse_var(&sn, &sig->s); + secp256k1_scalar_inverse_var(&sn, sigs); secp256k1_scalar_mul(&u1, &sn, message); - secp256k1_scalar_mul(&u2, &sn, &sig->r); + secp256k1_scalar_mul(&u2, &sn, sigr); secp256k1_gej_set_ge(&pubkeyj, pubkey); secp256k1_ecmult(ctx, &pr, &pubkeyj, &u2, &u1); if (secp256k1_gej_is_infinity(&pr)) { return 0; } - secp256k1_scalar_get_b32(c, &sig->r); + secp256k1_scalar_get_b32(c, sigr); secp256k1_fe_set_b32(&xr, c); /** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n) @@ -171,11 +239,11 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, con * secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test. */ if (secp256k1_gej_eq_x_var(&xr, &pr)) { - /* xr.x == xr * xr.z^2 mod p, so the signature is valid. */ + /* xr * pr.z^2 mod p == pr.x, so the signature is valid. */ return 1; } if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_const_p_minus_order) >= 0) { - /* xr + p >= n, so we can skip testing the second case. */ + /* xr + n >= p, so we can skip testing the second case. */ return 0; } secp256k1_fe_add(&xr, &secp256k1_ecdsa_const_order_as_fe); @@ -186,44 +254,11 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, con return 0; } -static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) { - unsigned char brx[32]; - secp256k1_fe_t fx; - secp256k1_ge_t x; - secp256k1_gej_t xj; - secp256k1_scalar_t rn, u1, u2; - secp256k1_gej_t qj; - - if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) { - return 0; - } - - secp256k1_scalar_get_b32(brx, &sig->r); - VERIFY_CHECK(secp256k1_fe_set_b32(&fx, brx)); /* brx comes from a scalar, so is less than the order; certainly less than p */ - if (recid & 2) { - if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) { - return 0; - } - secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe); - } - if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) { - return 0; - } - secp256k1_gej_set_ge(&xj, &x); - secp256k1_scalar_inverse_var(&rn, &sig->r); - secp256k1_scalar_mul(&u1, &rn, message); - secp256k1_scalar_negate(&u1, &u1); - secp256k1_scalar_mul(&u2, &rn, &sig->s); - secp256k1_ecmult(ctx, &qj, &xj, &u2, &u1); - secp256k1_ge_set_gej_var(pubkey, &qj); - return !secp256k1_gej_is_infinity(&qj); -} - -static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) { +static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid) { unsigned char b[32]; - secp256k1_gej_t rp; - secp256k1_ge_t r; - secp256k1_scalar_t n; + secp256k1_gej rp; + secp256k1_ge r; + secp256k1_scalar n; int overflow = 0; secp256k1_ecmult_gen(ctx, &rp, nonce); @@ -231,28 +266,33 @@ static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, s secp256k1_fe_normalize(&r.x); secp256k1_fe_normalize(&r.y); secp256k1_fe_get_b32(b, &r.x); - secp256k1_scalar_set_b32(&sig->r, b, &overflow); - if (secp256k1_scalar_is_zero(&sig->r)) { - /* P.x = order is on the curve, so technically sig->r could end up zero, which would be an invalid signature. */ + secp256k1_scalar_set_b32(sigr, b, &overflow); + if (secp256k1_scalar_is_zero(sigr)) { + /* P.x = order is on the curve, so technically sig->r could end up zero, which would be an invalid signature. + * This branch is cryptographically unreachable as hitting it requires finding the discrete log of P.x = N. + */ secp256k1_gej_clear(&rp); secp256k1_ge_clear(&r); return 0; } if (recid) { + /* The overflow condition is cryptographically unreachable as hitting it requires finding the discrete log + * of some P where P.x >= order, and only 1 in about 2^127 points meet this criteria. + */ *recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0); } - secp256k1_scalar_mul(&n, &sig->r, seckey); + secp256k1_scalar_mul(&n, sigr, seckey); secp256k1_scalar_add(&n, &n, message); - secp256k1_scalar_inverse(&sig->s, nonce); - secp256k1_scalar_mul(&sig->s, &sig->s, &n); + secp256k1_scalar_inverse(sigs, nonce); + secp256k1_scalar_mul(sigs, sigs, &n); secp256k1_scalar_clear(&n); secp256k1_gej_clear(&rp); secp256k1_ge_clear(&r); - if (secp256k1_scalar_is_zero(&sig->s)) { + if (secp256k1_scalar_is_zero(sigs)) { return 0; } - if (secp256k1_scalar_is_high(&sig->s)) { - secp256k1_scalar_negate(&sig->s, &sig->s); + if (secp256k1_scalar_is_high(sigs)) { + secp256k1_scalar_negate(sigs, sigs); if (recid) { *recid ^= 1; } diff --git a/src/secp256k1/src/eckey.h b/src/secp256k1/src/eckey.h index 53b818485e..42739a3bea 100644 --- a/src/secp256k1/src/eckey.h +++ b/src/secp256k1/src/eckey.h @@ -7,20 +7,19 @@ #ifndef _SECP256K1_ECKEY_ #define _SECP256K1_ECKEY_ +#include <stddef.h> + #include "group.h" #include "scalar.h" #include "ecmult.h" #include "ecmult_gen.h" -static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size); -static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed); - -static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen); -static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed); +static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size); +static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, 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(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak); -static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak); -static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak); +static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak); +static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); +static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak); +static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); #endif diff --git a/src/secp256k1/src/eckey_impl.h b/src/secp256k1/src/eckey_impl.h index a332bd34ec..ce38071ac2 100644 --- a/src/secp256k1/src/eckey_impl.h +++ b/src/secp256k1/src/eckey_impl.h @@ -14,12 +14,12 @@ #include "group.h" #include "ecmult_gen.h" -static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size) { +static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) { if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) { - secp256k1_fe_t x; + secp256k1_fe 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; + secp256k1_fe x, y; if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) { return 0; } @@ -33,7 +33,7 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned cha } } -static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed) { +static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) { if (secp256k1_ge_is_infinity(elem)) { return 0; } @@ -51,110 +51,7 @@ static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char return 1; } -static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen) { - unsigned char c[32] = {0}; - const unsigned char *end = privkey + privkeylen; - int lenb = 0; - int len = 0; - int overflow = 0; - /* sequence header */ - if (end < privkey+1 || *privkey != 0x30) { - return 0; - } - privkey++; - /* sequence length constructor */ - 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 */ - 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; - } - 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(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed) { - secp256k1_gej_t rp; - secp256k1_ge_t r; - int pubkeylen = 0; - secp256k1_ecmult_gen(ctx, &rp, key); - 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); - 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); - 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) { +static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak) { secp256k1_scalar_add(key, key, tweak); if (secp256k1_scalar_is_zero(key)) { return 0; @@ -162,9 +59,9 @@ static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp return 1; } -static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) { - secp256k1_gej_t pt; - secp256k1_scalar_t one; +static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { + secp256k1_gej pt; + secp256k1_scalar one; secp256k1_gej_set_ge(&pt, key); secp256k1_scalar_set_int(&one, 1); secp256k1_ecmult(ctx, &pt, &pt, &one, tweak); @@ -176,7 +73,7 @@ static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ct return 1; } -static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak) { +static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak) { if (secp256k1_scalar_is_zero(tweak)) { return 0; } @@ -185,9 +82,9 @@ static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp return 1; } -static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) { - secp256k1_scalar_t zero; - secp256k1_gej_t pt; +static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { + secp256k1_scalar zero; + secp256k1_gej pt; if (secp256k1_scalar_is_zero(tweak)) { return 0; } diff --git a/src/secp256k1/src/ecmult.h b/src/secp256k1/src/ecmult.h index bab9e4ef52..20484134f5 100644 --- a/src/secp256k1/src/ecmult.h +++ b/src/secp256k1/src/ecmult.h @@ -12,20 +12,20 @@ typedef struct { /* For accelerating the computation of a*P + b*G: */ - secp256k1_ge_storage_t (*pre_g)[]; /* odd multiples of the generator */ + secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */ #ifdef USE_ENDOMORPHISM - secp256k1_ge_storage_t (*pre_g_128)[]; /* odd multiples of 2^128*generator */ + secp256k1_ge_storage (*pre_g_128)[]; /* odd multiples of 2^128*generator */ #endif -} secp256k1_ecmult_context_t; +} secp256k1_ecmult_context; -static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx); -static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx); -static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst, - const secp256k1_ecmult_context_t *src); -static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx); -static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx); +static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx); +static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb); +static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, + const secp256k1_ecmult_context *src, const secp256k1_callback *cb); +static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx); +static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx); /** Double multiply: R = na*A + ng*G */ -static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng); +static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng); #endif diff --git a/src/secp256k1/src/ecmult_const.h b/src/secp256k1/src/ecmult_const.h new file mode 100644 index 0000000000..2b0097655c --- /dev/null +++ b/src/secp256k1/src/ecmult_const.h @@ -0,0 +1,15 @@ +/********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_ECMULT_CONST_ +#define _SECP256K1_ECMULT_CONST_ + +#include "scalar.h" +#include "group.h" + +static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q); + +#endif diff --git a/src/secp256k1/src/ecmult_const_impl.h b/src/secp256k1/src/ecmult_const_impl.h new file mode 100644 index 0000000000..90ac94770e --- /dev/null +++ b/src/secp256k1/src/ecmult_const_impl.h @@ -0,0 +1,260 @@ +/********************************************************************** + * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_ECMULT_CONST_IMPL_ +#define _SECP256K1_ECMULT_CONST_IMPL_ + +#include "scalar.h" +#include "group.h" +#include "ecmult_const.h" +#include "ecmult_impl.h" + +#ifdef USE_ENDOMORPHISM + #define WNAF_BITS 128 +#else + #define WNAF_BITS 256 +#endif +#define WNAF_SIZE(w) ((WNAF_BITS + (w) - 1) / (w)) + +/* This is like `ECMULT_TABLE_GET_GE` but is constant time */ +#define ECMULT_CONST_TABLE_GET_GE(r,pre,n,w) do { \ + int m; \ + int abs_n = (n) * (((n) > 0) * 2 - 1); \ + int idx_n = abs_n / 2; \ + secp256k1_fe neg_y; \ + VERIFY_CHECK(((n) & 1) == 1); \ + VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ + VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ + VERIFY_SETUP(secp256k1_fe_clear(&(r)->x)); \ + VERIFY_SETUP(secp256k1_fe_clear(&(r)->y)); \ + for (m = 0; m < ECMULT_TABLE_SIZE(w); m++) { \ + /* This loop is used to avoid secret data in array indices. See + * the comment in ecmult_gen_impl.h for rationale. */ \ + secp256k1_fe_cmov(&(r)->x, &(pre)[m].x, m == idx_n); \ + secp256k1_fe_cmov(&(r)->y, &(pre)[m].y, m == idx_n); \ + } \ + (r)->infinity = 0; \ + secp256k1_fe_negate(&neg_y, &(r)->y, 1); \ + secp256k1_fe_cmov(&(r)->y, &neg_y, (n) != abs_n); \ +} while(0) + + +/** Convert a number to WNAF notation. The number becomes represented by sum(2^{wi} * wnaf[i], i=0..return_val) + * with the following guarantees: + * - each wnaf[i] an odd integer between -(1 << w) and (1 << w) + * - each wnaf[i] is nonzero + * - the number of words set is returned; this is always (WNAF_BITS + w - 1) / w + * + * Adapted from `The Width-w NAF Method Provides Small Memory and Fast Elliptic Scalar + * Multiplications Secure against Side Channel Attacks`, Okeya and Tagaki. M. Joye (Ed.) + * CT-RSA 2003, LNCS 2612, pp. 328-443, 2003. Springer-Verlagy Berlin Heidelberg 2003 + * + * Numbers reference steps of `Algorithm SPA-resistant Width-w NAF with Odd Scalar` on pp. 335 + */ +static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) { + int global_sign; + int skew = 0; + int word = 0; + /* 1 2 3 */ + int u_last; + int u; + +#ifdef USE_ENDOMORPHISM + int flip; + int bit; + secp256k1_scalar neg_s; + int not_neg_one; + /* If we are using the endomorphism, we cannot handle even numbers by negating + * them, since we are working with 128-bit numbers whose negations would be 256 + * bits, eliminating the performance advantage. Instead we use a technique from + * Section 4.2 of the Okeya/Tagaki paper, which is to add either 1 (for even) + * or 2 (for odd) to the number we are encoding, then compensating after the + * multiplication. */ + /* Negative 128-bit numbers will be negated, since otherwise they are 256-bit */ + flip = secp256k1_scalar_is_high(&s); + /* We add 1 to even numbers, 2 to odd ones, noting that negation flips parity */ + bit = flip ^ (s.d[0] & 1); + /* We check for negative one, since adding 2 to it will cause an overflow */ + secp256k1_scalar_negate(&neg_s, &s); + not_neg_one = !secp256k1_scalar_is_one(&neg_s); + secp256k1_scalar_cadd_bit(&s, bit, not_neg_one); + /* If we had negative one, flip == 1, s.d[0] == 0, bit == 1, so caller expects + * that we added two to it and flipped it. In fact for -1 these operations are + * identical. We only flipped, but since skewing is required (in the sense that + * the skew must be 1 or 2, never zero) and flipping is not, we need to change + * our flags to claim that we only skewed. */ + global_sign = secp256k1_scalar_cond_negate(&s, flip); + global_sign *= not_neg_one * 2 - 1; + skew = 1 << bit; +#else + /* Otherwise, we just negate to force oddness */ + int is_even = secp256k1_scalar_is_even(&s); + global_sign = secp256k1_scalar_cond_negate(&s, is_even); +#endif + + /* 4 */ + u_last = secp256k1_scalar_shr_int(&s, w); + while (word * w < WNAF_BITS) { + int sign; + int even; + + /* 4.1 4.4 */ + u = secp256k1_scalar_shr_int(&s, w); + /* 4.2 */ + even = ((u & 1) == 0); + sign = 2 * (u_last > 0) - 1; + u += sign * even; + u_last -= sign * even * (1 << w); + + /* 4.3, adapted for global sign change */ + wnaf[word++] = u_last * global_sign; + + u_last = u; + } + wnaf[word] = u * global_sign; + + VERIFY_CHECK(secp256k1_scalar_is_zero(&s)); + VERIFY_CHECK(word == WNAF_SIZE(w)); + return skew; +} + + +static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *scalar) { + secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_ge tmpa; + secp256k1_fe Z; + +#ifdef USE_ENDOMORPHISM + secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; + int wnaf_1[1 + WNAF_SIZE(WINDOW_A - 1)]; + int wnaf_lam[1 + WNAF_SIZE(WINDOW_A - 1)]; + int skew_1; + int skew_lam; + secp256k1_scalar q_1, q_lam; +#else + int wnaf[1 + WNAF_SIZE(WINDOW_A - 1)]; +#endif + + int i; + secp256k1_scalar sc = *scalar; + + /* build wnaf representation for q. */ +#ifdef USE_ENDOMORPHISM + /* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */ + secp256k1_scalar_split_lambda(&q_1, &q_lam, &sc); + /* no need for zero correction when using endomorphism since even + * numbers have one added to them anyway */ + skew_1 = secp256k1_wnaf_const(wnaf_1, q_1, WINDOW_A - 1); + skew_lam = secp256k1_wnaf_const(wnaf_lam, q_lam, WINDOW_A - 1); +#else + int is_zero = secp256k1_scalar_is_zero(scalar); + /* the wNAF ladder cannot handle zero, so bump this to one .. we will + * correct the result after the fact */ + sc.d[0] += is_zero; + VERIFY_CHECK(!secp256k1_scalar_is_zero(&sc)); + + secp256k1_wnaf_const(wnaf, sc, WINDOW_A - 1); +#endif + + /* Calculate odd multiples of a. + * All multiples are brought to the same Z 'denominator', which is stored + * in Z. Due to secp256k1' isomorphism we can do all operations pretending + * that the Z coordinate was 1, use affine addition formulae, and correct + * the Z coordinate of the result once at the end. + */ + secp256k1_gej_set_ge(r, a); + secp256k1_ecmult_odd_multiples_table_globalz_windowa(pre_a, &Z, r); + for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { + secp256k1_fe_normalize_weak(&pre_a[i].y); + } +#ifdef USE_ENDOMORPHISM + for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { + secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]); + } +#endif + + /* first loop iteration (separated out so we can directly set r, rather + * than having it start at infinity, get doubled several times, then have + * its new value added to it) */ +#ifdef USE_ENDOMORPHISM + i = wnaf_1[WNAF_SIZE(WINDOW_A - 1)]; + VERIFY_CHECK(i != 0); + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A); + secp256k1_gej_set_ge(r, &tmpa); + + i = wnaf_lam[WNAF_SIZE(WINDOW_A - 1)]; + VERIFY_CHECK(i != 0); + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, i, WINDOW_A); + secp256k1_gej_add_ge(r, r, &tmpa); +#else + i = wnaf[WNAF_SIZE(WINDOW_A - 1)]; + VERIFY_CHECK(i != 0); + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A); + secp256k1_gej_set_ge(r, &tmpa); +#endif + /* remaining loop iterations */ + for (i = WNAF_SIZE(WINDOW_A - 1) - 1; i >= 0; i--) { + int n; + int j; + for (j = 0; j < WINDOW_A - 1; ++j) { + secp256k1_gej_double_nonzero(r, r, NULL); + } +#ifdef USE_ENDOMORPHISM + n = wnaf_1[i]; + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); + VERIFY_CHECK(n != 0); + secp256k1_gej_add_ge(r, r, &tmpa); + + n = wnaf_lam[i]; + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); + VERIFY_CHECK(n != 0); + secp256k1_gej_add_ge(r, r, &tmpa); +#else + n = wnaf[i]; + VERIFY_CHECK(n != 0); + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); + secp256k1_gej_add_ge(r, r, &tmpa); +#endif + } + + secp256k1_fe_mul(&r->z, &r->z, &Z); + +#ifdef USE_ENDOMORPHISM + { + /* Correct for wNAF skew */ + secp256k1_ge correction = *a; + secp256k1_ge_storage correction_1_stor; + secp256k1_ge_storage correction_lam_stor; + secp256k1_ge_storage a2_stor; + secp256k1_gej tmpj; + secp256k1_gej_set_ge(&tmpj, &correction); + secp256k1_gej_double_var(&tmpj, &tmpj, NULL); + secp256k1_ge_set_gej(&correction, &tmpj); + secp256k1_ge_to_storage(&correction_1_stor, a); + secp256k1_ge_to_storage(&correction_lam_stor, a); + secp256k1_ge_to_storage(&a2_stor, &correction); + + /* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */ + secp256k1_ge_storage_cmov(&correction_1_stor, &a2_stor, skew_1 == 2); + secp256k1_ge_storage_cmov(&correction_lam_stor, &a2_stor, skew_lam == 2); + + /* Apply the correction */ + secp256k1_ge_from_storage(&correction, &correction_1_stor); + secp256k1_ge_neg(&correction, &correction); + secp256k1_gej_add_ge(r, r, &correction); + + secp256k1_ge_from_storage(&correction, &correction_lam_stor); + secp256k1_ge_neg(&correction, &correction); + secp256k1_ge_mul_lambda(&correction, &correction); + secp256k1_gej_add_ge(r, r, &correction); + } +#else + /* correct for zero */ + r->infinity |= is_zero; +#endif +} + +#endif diff --git a/src/secp256k1/src/ecmult_gen.h b/src/secp256k1/src/ecmult_gen.h index 3745633c47..eb2cc9ead6 100644 --- a/src/secp256k1/src/ecmult_gen.h +++ b/src/secp256k1/src/ecmult_gen.h @@ -23,21 +23,21 @@ typedef struct { * None of the resulting prec group elements have a known scalar, and neither do any of * the intermediate sums while computing a*G. */ - secp256k1_ge_storage_t (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ - secp256k1_scalar_t blind; - secp256k1_gej_t initial; -} secp256k1_ecmult_gen_context_t; + secp256k1_ge_storage (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ + secp256k1_scalar blind; + secp256k1_gej initial; +} secp256k1_ecmult_gen_context; -static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t* ctx); -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t* ctx); -static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst, - const secp256k1_ecmult_gen_context_t* src); -static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t* ctx); -static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context_t* ctx); +static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context* ctx); +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx, const secp256k1_callback* cb); +static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, + const secp256k1_ecmult_gen_context* src, const secp256k1_callback* cb); +static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); +static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx); /** Multiply with the generator: R = a*G */ -static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context_t* ctx, secp256k1_gej_t *r, const secp256k1_scalar_t *a); +static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a); -static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context_t *ctx, const unsigned char *seed32); +static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32); #endif diff --git a/src/secp256k1/src/ecmult_gen_impl.h b/src/secp256k1/src/ecmult_gen_impl.h index 4697753ac8..b63c4d8662 100644 --- a/src/secp256k1/src/ecmult_gen_impl.h +++ b/src/secp256k1/src/ecmult_gen_impl.h @@ -11,22 +11,26 @@ #include "group.h" #include "ecmult_gen.h" #include "hash_impl.h" - -static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t *ctx) { +#ifdef USE_ECMULT_STATIC_PRECOMPUTATION +#include "ecmult_static_context.h" +#endif +static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context *ctx) { ctx->prec = NULL; } -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *ctx) { - secp256k1_ge_t prec[1024]; - secp256k1_gej_t gj; - secp256k1_gej_t nums_gej; +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx, const secp256k1_callback* cb) { +#ifndef USE_ECMULT_STATIC_PRECOMPUTATION + secp256k1_ge prec[1024]; + secp256k1_gej gj; + secp256k1_gej nums_gej; int i, j; +#endif if (ctx->prec != NULL) { return; } - - ctx->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*ctx->prec)); +#ifndef USE_ECMULT_STATIC_PRECOMPUTATION + ctx->prec = (secp256k1_ge_storage (*)[64][16])checked_malloc(cb, sizeof(*ctx->prec)); /* get the generator */ secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); @@ -34,77 +38,93 @@ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *c /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */ { static const unsigned char nums_b32[33] = "The scalar for this x is unknown"; - secp256k1_fe_t nums_x; - secp256k1_ge_t nums_ge; - VERIFY_CHECK(secp256k1_fe_set_b32(&nums_x, nums_b32)); - VERIFY_CHECK(secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0)); + secp256k1_fe nums_x; + secp256k1_ge nums_ge; + int r; + r = secp256k1_fe_set_b32(&nums_x, nums_b32); + (void)r; + VERIFY_CHECK(r); + r = secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0); + (void)r; + VERIFY_CHECK(r); 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, &secp256k1_ge_const_g); + secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g, NULL); } /* compute prec. */ { - secp256k1_gej_t precj[1024]; /* Jacobian versions of prec. */ - secp256k1_gej_t gbase; - secp256k1_gej_t numsbase; + secp256k1_gej precj[1024]; /* Jacobian versions of prec. */ + secp256k1_gej gbase; + secp256k1_gej numsbase; gbase = gj; /* 16^j * G */ numsbase = nums_gej; /* 2^j * nums. */ for (j = 0; j < 64; j++) { /* Set precj[j*16 .. j*16+15] to (numsbase, numsbase + gbase, ..., numsbase + 15*gbase). */ precj[j*16] = numsbase; for (i = 1; i < 16; i++) { - secp256k1_gej_add_var(&precj[j*16 + i], &precj[j*16 + i - 1], &gbase); + secp256k1_gej_add_var(&precj[j*16 + i], &precj[j*16 + i - 1], &gbase, NULL); } /* Multiply gbase by 16. */ for (i = 0; i < 4; i++) { - secp256k1_gej_double_var(&gbase, &gbase); + secp256k1_gej_double_var(&gbase, &gbase, NULL); } /* Multiply numbase by 2. */ - secp256k1_gej_double_var(&numsbase, &numsbase); + secp256k1_gej_double_var(&numsbase, &numsbase, NULL); if (j == 62) { /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ secp256k1_gej_neg(&numsbase, &numsbase); - secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej); + secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL); } } - secp256k1_ge_set_all_gej_var(1024, prec, precj); + secp256k1_ge_set_all_gej_var(1024, prec, precj, cb); } for (j = 0; j < 64; j++) { for (i = 0; i < 16; i++) { secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*16 + i]); } } +#else + (void)cb; + ctx->prec = (secp256k1_ge_storage (*)[64][16])secp256k1_ecmult_static_context; +#endif secp256k1_ecmult_gen_blind(ctx, NULL); } -static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context_t* ctx) { +static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx) { return ctx->prec != NULL; } -static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst, - const secp256k1_ecmult_gen_context_t *src) { +static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, + const secp256k1_ecmult_gen_context *src, const secp256k1_callback* cb) { if (src->prec == NULL) { dst->prec = NULL; } else { - dst->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*dst->prec)); +#ifndef USE_ECMULT_STATIC_PRECOMPUTATION + dst->prec = (secp256k1_ge_storage (*)[64][16])checked_malloc(cb, sizeof(*dst->prec)); memcpy(dst->prec, src->prec, sizeof(*dst->prec)); +#else + (void)cb; + dst->prec = src->prec; +#endif dst->initial = src->initial; dst->blind = src->blind; } } -static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t *ctx) { +static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx) { +#ifndef USE_ECMULT_STATIC_PRECOMPUTATION free(ctx->prec); +#endif secp256k1_scalar_clear(&ctx->blind); secp256k1_gej_clear(&ctx->initial); ctx->prec = NULL; } -static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_gej_t *r, const secp256k1_scalar_t *gn) { - secp256k1_ge_t add; - secp256k1_ge_storage_t adds; - secp256k1_scalar_t gnb; +static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *gn) { + secp256k1_ge add; + secp256k1_ge_storage adds; + secp256k1_scalar gnb; int bits; int i, j; memset(&adds, 0, sizeof(adds)); @@ -136,14 +156,15 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context_t *ctx, secp } /* Setup blinding values for secp256k1_ecmult_gen. */ -static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context_t *ctx, const unsigned char *seed32) { - secp256k1_scalar_t b; - secp256k1_gej_t gb; - secp256k1_fe_t s; +static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32) { + secp256k1_scalar b; + secp256k1_gej gb; + secp256k1_fe s; unsigned char nonce32[32]; secp256k1_rfc6979_hmac_sha256_t rng; int retry; - if (!seed32) { + unsigned char keydata[64] = {0}; + if (seed32 == NULL) { /* When seed is NULL, reset the initial point and blinding value. */ secp256k1_gej_set_ge(&ctx->initial, &secp256k1_ge_const_g); secp256k1_gej_neg(&ctx->initial, &ctx->initial); @@ -155,13 +176,18 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context_t *ctx, cons * and guards against weak or adversarial seeds. This is a simpler and safer interface than * asking the caller for blinding values directly and expecting them to retry on failure. */ - secp256k1_rfc6979_hmac_sha256_initialize(&rng, seed32 ? seed32 : nonce32, 32, nonce32, 32, NULL, 0); + memcpy(keydata, nonce32, 32); + if (seed32 != NULL) { + memcpy(keydata + 32, seed32, 32); + } + secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, seed32 ? 64 : 32); + memset(keydata, 0, sizeof(keydata)); /* Retry for out of range results to achieve uniformity. */ do { secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); retry = !secp256k1_fe_set_b32(&s, nonce32); retry |= secp256k1_fe_is_zero(&s); - } while (retry); + } while (retry); /* This branch true is cryptographically unreachable. Requires sha256_hmac output > Fp. */ /* Randomize the projection to defend against multiplier sidechannels. */ secp256k1_gej_rescale(&ctx->initial, &s); secp256k1_fe_clear(&s); @@ -170,7 +196,7 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context_t *ctx, cons secp256k1_scalar_set_b32(&b, nonce32, &retry); /* A blinding value of 0 works, but would undermine the projection hardening. */ retry |= secp256k1_scalar_is_zero(&b); - } while (retry); + } while (retry); /* This branch true is cryptographically unreachable. Requires sha256_hmac output > order. */ secp256k1_rfc6979_hmac_sha256_finalize(&rng); memset(nonce32, 0, 32); secp256k1_ecmult_gen(ctx, &gb, &b); diff --git a/src/secp256k1/src/ecmult_impl.h b/src/secp256k1/src/ecmult_impl.h index 1b2856f83d..e6e5f47188 100644 --- a/src/secp256k1/src/ecmult_impl.h +++ b/src/secp256k1/src/ecmult_impl.h @@ -24,62 +24,107 @@ #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. +/** The number of entries a table with precomputed multiples needs to have. */ +#define ECMULT_TABLE_SIZE(w) (1 << ((w)-2)) + +/** Fill a table 'prej' with precomputed odd multiples of a. Prej will contain + * the values [1*a,3*a,...,(2*n-1)*a], so it space for n values. zr[0] will + * contain prej[0].z / a.z. The other zr[i] values = prej[i].z / prej[i-1].z. + * Prej's Z values are undefined, except for the last value. */ -static void secp256k1_ecmult_table_precomp_gej_var(secp256k1_gej_t *pre, const secp256k1_gej_t *a, int w) { - secp256k1_gej_t d; +static void secp256k1_ecmult_odd_multiples_table(int n, secp256k1_gej *prej, secp256k1_fe *zr, const secp256k1_gej *a) { + secp256k1_gej d; + secp256k1_ge a_ge, d_ge; int i; - pre[0] = *a; - secp256k1_gej_double_var(&d, &pre[0]); - for (i = 1; i < (1 << (w-2)); i++) { - secp256k1_gej_add_var(&pre[i], &d, &pre[i-1]); + + VERIFY_CHECK(!a->infinity); + + secp256k1_gej_double_var(&d, a, NULL); + + /* + * Perform the additions on an isomorphism where 'd' is affine: drop the z coordinate + * of 'd', and scale the 1P starting value's x/y coordinates without changing its z. + */ + d_ge.x = d.x; + d_ge.y = d.y; + d_ge.infinity = 0; + + secp256k1_ge_set_gej_zinv(&a_ge, a, &d.z); + prej[0].x = a_ge.x; + prej[0].y = a_ge.y; + prej[0].z = a->z; + prej[0].infinity = 0; + + zr[0] = d.z; + for (i = 1; i < n; i++) { + secp256k1_gej_add_ge_var(&prej[i], &prej[i-1], &d_ge, &zr[i]); } + + /* + * Each point in 'prej' has a z coordinate too small by a factor of 'd.z'. Only + * the final point's z coordinate is actually used though, so just update that. + */ + secp256k1_fe_mul(&prej[n-1].z, &prej[n-1].z, &d.z); +} + +/** Fill a table 'pre' with precomputed odd multiples of a. + * + * There are two versions of this function: + * - secp256k1_ecmult_odd_multiples_table_globalz_windowa which brings its + * resulting point set to a single constant Z denominator, stores the X and Y + * coordinates as ge_storage points in pre, and stores the global Z in rz. + * It only operates on tables sized for WINDOW_A wnaf multiples. + * - secp256k1_ecmult_odd_multiples_table_storage_var, which converts its + * resulting point set to actually affine points, and stores those in pre. + * It operates on tables of any size, but uses heap-allocated temporaries. + * + * To compute a*P + b*G, we compute a table for P using the first function, + * and for G using the second (which requires an inverse, but it only needs to + * happen once). + */ +static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge *pre, secp256k1_fe *globalz, const secp256k1_gej *a) { + secp256k1_gej prej[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_fe zr[ECMULT_TABLE_SIZE(WINDOW_A)]; + + /* Compute the odd multiples in Jacobian form. */ + secp256k1_ecmult_odd_multiples_table(ECMULT_TABLE_SIZE(WINDOW_A), prej, zr, a); + /* Bring them to the same Z denominator. */ + secp256k1_ge_globalz_set_table_gej(ECMULT_TABLE_SIZE(WINDOW_A), pre, globalz, prej, zr); } -static void secp256k1_ecmult_table_precomp_ge_storage_var(secp256k1_ge_storage_t *pre, const secp256k1_gej_t *a, int w) { - secp256k1_gej_t d; +static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, secp256k1_ge_storage *pre, const secp256k1_gej *a, const secp256k1_callback *cb) { + secp256k1_gej *prej = (secp256k1_gej*)checked_malloc(cb, sizeof(secp256k1_gej) * n); + secp256k1_ge *prea = (secp256k1_ge*)checked_malloc(cb, sizeof(secp256k1_ge) * n); + secp256k1_fe *zr = (secp256k1_fe*)checked_malloc(cb, sizeof(secp256k1_fe) * n); int i; - const int table_size = 1 << (w-2); - secp256k1_gej_t *prej = (secp256k1_gej_t *)checked_malloc(sizeof(secp256k1_gej_t) * table_size); - secp256k1_ge_t *prea = (secp256k1_ge_t *)checked_malloc(sizeof(secp256k1_ge_t) * table_size); - prej[0] = *a; - secp256k1_gej_double_var(&d, a); - for (i = 1; i < table_size; i++) { - secp256k1_gej_add_var(&prej[i], &d, &prej[i-1]); - } - secp256k1_ge_set_all_gej_var(table_size, prea, prej); - for (i = 0; i < table_size; i++) { + + /* Compute the odd multiples in Jacobian form. */ + secp256k1_ecmult_odd_multiples_table(n, prej, zr, a); + /* Convert them in batch to affine coordinates. */ + secp256k1_ge_set_table_gej_var(n, prea, prej, zr); + /* Convert them to compact storage form. */ + for (i = 0; i < n; i++) { secp256k1_ge_to_storage(&pre[i], &prea[i]); } - free(prej); + free(prea); + free(prej); + free(zr); } -/** 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_GEJ(r,pre,n,w) do { \ +#define ECMULT_TABLE_GET_GE(r,pre,n,w) do { \ VERIFY_CHECK(((n) & 1) == 1); \ VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ if ((n) > 0) { \ *(r) = (pre)[((n)-1)/2]; \ } else { \ - secp256k1_gej_neg((r), &(pre)[(-(n)-1)/2]); \ + secp256k1_ge_neg((r), &(pre)[(-(n)-1)/2]); \ } \ } while(0) + #define ECMULT_TABLE_GET_GE_STORAGE(r,pre,n,w) do { \ VERIFY_CHECK(((n) & 1) == 1); \ VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ @@ -92,15 +137,15 @@ static void secp256k1_ecmult_table_precomp_ge_storage_var(secp256k1_ge_storage_t } \ } while(0) -static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx) { +static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx) { ctx->pre_g = NULL; #ifdef USE_ENDOMORPHISM ctx->pre_g_128 = NULL; #endif } -static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx) { - secp256k1_gej_t gj; +static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb) { + secp256k1_gej gj; if (ctx->pre_g != NULL) { return; @@ -109,35 +154,35 @@ static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx) { /* get the generator */ secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); - ctx->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); + ctx->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); /* precompute the tables with odd multiples */ - secp256k1_ecmult_table_precomp_ge_storage_var(*ctx->pre_g, &gj, WINDOW_G); + secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g, &gj, cb); #ifdef USE_ENDOMORPHISM { - secp256k1_gej_t g_128j; + secp256k1_gej g_128j; int i; - ctx->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); + ctx->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); /* calculate 2^128*generator */ g_128j = gj; for (i = 0; i < 128; i++) { - secp256k1_gej_double_var(&g_128j, &g_128j); + secp256k1_gej_double_var(&g_128j, &g_128j, NULL); } - secp256k1_ecmult_table_precomp_ge_storage_var(*ctx->pre_g_128, &g_128j, WINDOW_G); + secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g_128, &g_128j, cb); } #endif } -static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst, - const secp256k1_ecmult_context_t *src) { +static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, + const secp256k1_ecmult_context *src, const secp256k1_callback *cb) { if (src->pre_g == NULL) { dst->pre_g = NULL; } else { size_t size = sizeof((*dst->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G); - dst->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(size); + dst->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, size); memcpy(dst->pre_g, src->pre_g, size); } #ifdef USE_ENDOMORPHISM @@ -145,17 +190,17 @@ static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst, dst->pre_g_128 = NULL; } else { size_t size = sizeof((*dst->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G); - dst->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(size); + dst->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, size); memcpy(dst->pre_g_128, src->pre_g_128, size); } #endif } -static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx) { +static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx) { return ctx->pre_g != NULL; } -static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx) { +static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx) { free(ctx->pre_g); #ifdef USE_ENDOMORPHISM free(ctx->pre_g_128); @@ -168,54 +213,68 @@ static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx) { * - 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. + * 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 set_bits = 0; +static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a, int w) { + secp256k1_scalar s = *a; + int last_set_bit = -1; int bit = 0; int sign = 1; + int carry = 0; + + VERIFY_CHECK(wnaf != NULL); + VERIFY_CHECK(0 <= len && len <= 256); + VERIFY_CHECK(a != NULL); + VERIFY_CHECK(2 <= w && w <= 31); + + memset(wnaf, 0, len * sizeof(wnaf[0])); if (secp256k1_scalar_get_bits(&s, 255, 1)) { secp256k1_scalar_negate(&s, &s); sign = -1; } - while (bit < 256) { + while (bit < len) { int now; int word; - if (secp256k1_scalar_get_bits(&s, bit, 1) == 0) { + if (secp256k1_scalar_get_bits(&s, bit, 1) == (unsigned int)carry) { bit++; continue; } - while (set_bits < bit) { - wnaf[set_bits++] = 0; - } + now = w; - if (bit + now > 256) { - now = 256 - bit; - } - 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; + if (now > len - bit) { + now = len - bit; } + + word = secp256k1_scalar_get_bits_var(&s, bit, now) + carry; + + carry = (word >> (w-1)) & 1; + word -= carry << w; + + wnaf[bit] = sign * word; + last_set_bit = bit; + bit += now; } - return set_bits; +#ifdef VERIFY + CHECK(carry == 0); + while (bit < 256) { + CHECK(secp256k1_scalar_get_bits(&s, bit++, 1) == 0); + } +#endif + return last_set_bit + 1; } -static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng) { - secp256k1_gej_t tmpj; - secp256k1_gej_t pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_ge_t tmpa; +static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) { + secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_ge tmpa; + secp256k1_fe Z; #ifdef USE_ENDOMORPHISM - secp256k1_gej_t pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_scalar_t na_1, na_lam; + secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_scalar na_1, na_lam; /* Splitted G factors. */ - secp256k1_scalar_t ng_1, ng_128; + secp256k1_scalar ng_1, ng_128; int wnaf_na_1[130]; int wnaf_na_lam[130]; int bits_na_1; @@ -227,7 +286,7 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge #else int wnaf_na[256]; int bits_na; - int wnaf_ng[257]; + int wnaf_ng[256]; int bits_ng; #endif int i; @@ -235,11 +294,11 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge #ifdef USE_ENDOMORPHISM /* 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); + secp256k1_scalar_split_lambda(&na_1, &na_lam, na); /* build wnaf representation for na_1 and na_lam. */ - bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A); - bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, &na_lam, WINDOW_A); + bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, 130, &na_1, WINDOW_A); + bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, 130, &na_lam, WINDOW_A); VERIFY_CHECK(bits_na_1 <= 130); VERIFY_CHECK(bits_na_lam <= 130); bits = bits_na_1; @@ -248,24 +307,33 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge } #else /* build wnaf representation for na. */ - bits_na = secp256k1_ecmult_wnaf(wnaf_na, na, WINDOW_A); + bits_na = secp256k1_ecmult_wnaf(wnaf_na, 256, na, WINDOW_A); bits = bits_na; #endif - /* calculate odd multiples of a */ - secp256k1_ecmult_table_precomp_gej_var(pre_a, a, WINDOW_A); + /* Calculate odd multiples of a. + * All multiples are brought to the same Z 'denominator', which is stored + * in Z. Due to secp256k1' isomorphism we can do all operations pretending + * that the Z coordinate was 1, use affine addition formulae, and correct + * the Z coordinate of the result once at the end. + * The exception is the precomputed G table points, which are actually + * affine. Compared to the base used for other points, they have a Z ratio + * of 1/Z, so we can use secp256k1_gej_add_zinv_var, which uses the same + * isomorphism to efficiently add with a known Z inverse. + */ + secp256k1_ecmult_odd_multiples_table_globalz_windowa(pre_a, &Z, a); #ifdef USE_ENDOMORPHISM for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { - secp256k1_gej_mul_lambda(&pre_a_lam[i], &pre_a[i]); + secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]); } /* split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit) */ secp256k1_scalar_split_128(&ng_1, &ng_128, ng); /* Build wnaf representation for ng_1 and ng_128 */ - bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G); - bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, &ng_128, WINDOW_G); + bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, 129, &ng_1, WINDOW_G); + bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, 129, &ng_128, WINDOW_G); if (bits_ng_1 > bits) { bits = bits_ng_1; } @@ -273,7 +341,7 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge bits = bits_ng_128; } #else - bits_ng = secp256k1_ecmult_wnaf(wnaf_ng, ng, WINDOW_G); + bits_ng = secp256k1_ecmult_wnaf(wnaf_ng, 256, ng, WINDOW_G); if (bits_ng > bits) { bits = bits_ng; } @@ -281,37 +349,41 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge secp256k1_gej_set_infinity(r); - for (i = bits-1; i >= 0; i--) { + for (i = bits - 1; i >= 0; i--) { int n; - secp256k1_gej_double_var(r, r); + secp256k1_gej_double_var(r, r, NULL); #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); + ECMULT_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); + secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); } 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); + ECMULT_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); + secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); } if (i < bits_ng_1 && (n = wnaf_ng_1[i])) { ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G); - secp256k1_gej_add_ge_var(r, r, &tmpa); + secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); } if (i < bits_ng_128 && (n = wnaf_ng_128[i])) { ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g_128, n, WINDOW_G); - secp256k1_gej_add_ge_var(r, r, &tmpa); + secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); } #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); + ECMULT_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); + secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); } if (i < bits_ng && (n = wnaf_ng[i])) { ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G); - secp256k1_gej_add_ge_var(r, r, &tmpa); + secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); } #endif } + + if (!r->infinity) { + secp256k1_fe_mul(&r->z, &r->z, &Z); + } } #endif diff --git a/src/secp256k1/src/field.h b/src/secp256k1/src/field.h index 41b280892d..2d52af5e36 100644 --- a/src/secp256k1/src/field.h +++ b/src/secp256k1/src/field.h @@ -10,7 +10,7 @@ /** Field element module. * * Field elements can be represented in several ways, but code accessing - * it (and implementations) need to take certain properaties into account: + * it (and implementations) need to take certain properties 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 @@ -31,89 +31,91 @@ #endif /** Normalize a field element. */ -static void secp256k1_fe_normalize(secp256k1_fe_t *r); +static void secp256k1_fe_normalize(secp256k1_fe *r); /** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */ -static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r); +static void secp256k1_fe_normalize_weak(secp256k1_fe *r); /** Normalize a field element, without constant-time guarantee. */ -static void secp256k1_fe_normalize_var(secp256k1_fe_t *r); +static void secp256k1_fe_normalize_var(secp256k1_fe *r); /** Verify whether a field element represents zero i.e. would normalize to a zero value. The field * implementation may optionally normalize the input, but this should not be relied upon. */ -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r); +static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r); /** Verify whether a field element represents zero i.e. would normalize to a zero value. The field * implementation may optionally normalize the input, but this should not be relied upon. */ -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r); +static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r); /** Set a field element equal to a small integer. Resulting field element is normalized. */ -static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a); +static void secp256k1_fe_set_int(secp256k1_fe *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); +static int secp256k1_fe_is_zero(const secp256k1_fe *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); +static int secp256k1_fe_is_odd(const secp256k1_fe *a); /** Compare two field elements. Requires magnitude-1 inputs. */ -static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b); +static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *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); +static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *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); +/** Set a field element equal to 32-byte big endian value. If successful, the resulting field element is normalized. */ +static int secp256k1_fe_set_b32(secp256k1_fe *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); +static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *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); +static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *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); +static void secp256k1_fe_mul_int(secp256k1_fe *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); +static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *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); +static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * 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); +static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *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); +/** If a has a square root, it is computed in r and 1 is returned. If a does not + * have a square root, the root of its negation is computed and 0 is returned. + * The input's magnitude can be at most 8. The output magnitude is 1 (but not + * guaranteed to be normalized). The result in r will always be a square + * itself. */ +static int secp256k1_fe_sqrt_var(secp256k1_fe *r, const secp256k1_fe *a); /** 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); +static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *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); +static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a); /** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and * outputs must not overlap in memory. */ -static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp256k1_fe_t *a); +static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe *r, const secp256k1_fe *a); /** Convert a field element to the storage type. */ -static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t*); +static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a); /** Convert a field element back from the storage type. */ -static void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t*); +static void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a); /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ -static void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag); +static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag); /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ -static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag); +static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag); #endif diff --git a/src/secp256k1/src/field_10x26.h b/src/secp256k1/src/field_10x26.h index 44bce6525d..61ee1e0965 100644 --- a/src/secp256k1/src/field_10x26.h +++ b/src/secp256k1/src/field_10x26.h @@ -16,20 +16,20 @@ typedef struct { int magnitude; int normalized; #endif -} secp256k1_fe_t; +} secp256k1_fe; /* Unpacks a constant into a overlapping multi-limbed FE element. */ #define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ (d0) & 0x3FFFFFFUL, \ - ((d0) >> 26) | ((d1) & 0xFFFFFUL) << 6, \ - ((d1) >> 20) | ((d2) & 0x3FFFUL) << 12, \ - ((d2) >> 14) | ((d3) & 0xFFUL) << 18, \ - ((d3) >> 8) | ((d4) & 0x3) << 24, \ - ((d4) >> 2) & 0x3FFFFFFUL, \ - ((d4) >> 28) | ((d5) & 0x3FFFFFUL) << 4, \ - ((d5) >> 22) | ((d6) & 0xFFFF) << 10, \ - ((d6) >> 16) | ((d7) & 0x3FF) << 16, \ - ((d7) >> 10) \ + (((uint32_t)d0) >> 26) | (((uint32_t)(d1) & 0xFFFFFUL) << 6), \ + (((uint32_t)d1) >> 20) | (((uint32_t)(d2) & 0x3FFFUL) << 12), \ + (((uint32_t)d2) >> 14) | (((uint32_t)(d3) & 0xFFUL) << 18), \ + (((uint32_t)d3) >> 8) | (((uint32_t)(d4) & 0x3UL) << 24), \ + (((uint32_t)d4) >> 2) & 0x3FFFFFFUL, \ + (((uint32_t)d4) >> 28) | (((uint32_t)(d5) & 0x3FFFFFUL) << 4), \ + (((uint32_t)d5) >> 22) | (((uint32_t)(d6) & 0xFFFFUL) << 10), \ + (((uint32_t)d6) >> 16) | (((uint32_t)(d7) & 0x3FFUL) << 16), \ + (((uint32_t)d7) >> 10) \ } #ifdef VERIFY @@ -40,8 +40,8 @@ typedef struct { typedef struct { uint32_t n[8]; -} secp256k1_fe_storage_t; +} secp256k1_fe_storage; #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }} - +#define SECP256K1_FE_STORAGE_CONST_GET(d) d.n[7], d.n[6], d.n[5], d.n[4],d.n[3], d.n[2], d.n[1], d.n[0] #endif diff --git a/src/secp256k1/src/field_10x26_impl.h b/src/secp256k1/src/field_10x26_impl.h index 871b91f912..212cc5396a 100644 --- a/src/secp256k1/src/field_10x26_impl.h +++ b/src/secp256k1/src/field_10x26_impl.h @@ -14,7 +14,7 @@ #include "field.h" #ifdef VERIFY -static void secp256k1_fe_verify(const secp256k1_fe_t *a) { +static void secp256k1_fe_verify(const secp256k1_fe *a) { const uint32_t *d = a->n; int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; r &= (d[0] <= 0x3FFFFFFUL * m); @@ -41,12 +41,12 @@ static void secp256k1_fe_verify(const secp256k1_fe_t *a) { VERIFY_CHECK(r == 1); } #else -static void secp256k1_fe_verify(const secp256k1_fe_t *a) { +static void secp256k1_fe_verify(const secp256k1_fe *a) { (void)a; } #endif -static void secp256k1_fe_normalize(secp256k1_fe_t *r) { +static void secp256k1_fe_normalize(secp256k1_fe *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]; @@ -101,7 +101,7 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) { #endif } -static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) { +static void secp256k1_fe_normalize_weak(secp256k1_fe *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]; @@ -132,7 +132,7 @@ static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) { #endif } -static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { +static void secp256k1_fe_normalize_var(secp256k1_fe *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]; @@ -188,7 +188,7 @@ static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { #endif } -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { +static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *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]; @@ -217,7 +217,7 @@ static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { return (z0 == 0) | (z1 == 0x3FFFFFFUL); } -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { +static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r) { uint32_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; uint32_t z0, z1; uint32_t x; @@ -252,7 +252,7 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { t9 &= 0x03FFFFFUL; t1 += (x << 6); - t1 += (t0 >> 26); t0 = z0; + t1 += (t0 >> 26); t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL; t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2; t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3; @@ -269,7 +269,7 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { return (z0 == 0) | (z1 == 0x3FFFFFFUL); } -SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *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 @@ -279,7 +279,7 @@ SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { #endif } -SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { +SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe *a) { const uint32_t *t = a->n; #ifdef VERIFY VERIFY_CHECK(a->normalized); @@ -288,7 +288,7 @@ SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { 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) { +SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); @@ -296,7 +296,7 @@ SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) { return a->n[0] & 1; } -SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { +SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) { int i; #ifdef VERIFY a->magnitude = 0; @@ -307,7 +307,7 @@ SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { } } -static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { +static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { int i; #ifdef VERIFY VERIFY_CHECK(a->normalized); @@ -326,7 +326,7 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b return 0; } -static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { +static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) { int i; 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; @@ -350,7 +350,7 @@ 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) { +static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) { int i; #ifdef VERIFY VERIFY_CHECK(a->normalized); @@ -368,7 +368,7 @@ static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { } } -SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) { +SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { #ifdef VERIFY VERIFY_CHECK(a->magnitude <= m); secp256k1_fe_verify(a); @@ -390,7 +390,7 @@ SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp25 #endif } -SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { r->n[0] *= a; r->n[1] *= a; r->n[2] *= a; @@ -408,7 +408,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) { #endif } -SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a) { #ifdef VERIFY secp256k1_fe_verify(a); #endif @@ -1039,7 +1039,7 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t } -static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) { +static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { #ifdef VERIFY VERIFY_CHECK(a->magnitude <= 8); VERIFY_CHECK(b->magnitude <= 8); @@ -1055,7 +1055,7 @@ static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const s #endif } -static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->magnitude <= 8); secp256k1_fe_verify(a); @@ -1068,7 +1068,7 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { #endif } -static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) { +static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { uint32_t mask0, mask1; mask0 = flag + ~((uint32_t)0); mask1 = ~mask0; @@ -1083,12 +1083,14 @@ static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1); r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1); #ifdef VERIFY - r->magnitude = (r->magnitude & mask0) | (a->magnitude & mask1); - r->normalized = (r->normalized & mask0) | (a->normalized & mask1); + if (a->magnitude > r->magnitude) { + r->magnitude = a->magnitude; + } + r->normalized &= a->normalized; #endif } -static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag) { +static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { uint32_t mask0, mask1; mask0 = flag + ~((uint32_t)0); mask1 = ~mask0; @@ -1102,7 +1104,7 @@ static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); } -static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t *a) { +static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->normalized); #endif @@ -1116,7 +1118,7 @@ static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_f r->n[7] = a->n[8] >> 16 | a->n[9] << 10; } -static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t *a) { +static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { r->n[0] = a->n[0] & 0x3FFFFFFUL; r->n[1] = a->n[0] >> 26 | ((a->n[1] << 6) & 0x3FFFFFFUL); r->n[2] = a->n[1] >> 20 | ((a->n[2] << 12) & 0x3FFFFFFUL); diff --git a/src/secp256k1/src/field_5x52.h b/src/secp256k1/src/field_5x52.h index 4513d36f49..8e69a560dc 100644 --- a/src/secp256k1/src/field_5x52.h +++ b/src/secp256k1/src/field_5x52.h @@ -16,15 +16,15 @@ typedef struct { int magnitude; int normalized; #endif -} secp256k1_fe_t; +} secp256k1_fe; /* Unpacks a constant into a overlapping multi-limbed FE element. */ #define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ - (d0) | ((uint64_t)(d1) & 0xFFFFFUL) << 32, \ - ((d1) >> 20) | ((uint64_t)(d2)) << 12 | ((uint64_t)(d3) & 0xFFUL) << 44, \ - ((d3) >> 8) | ((uint64_t)(d4) & 0xFFFFFFFUL) << 24, \ - ((d4) >> 28) | ((uint64_t)(d5)) << 4 | ((uint64_t)(d6) & 0xFFFFUL) << 36, \ - ((d6) >> 16) | ((uint64_t)(d7)) << 16 \ + (d0) | (((uint64_t)(d1) & 0xFFFFFUL) << 32), \ + ((uint64_t)(d1) >> 20) | (((uint64_t)(d2)) << 12) | (((uint64_t)(d3) & 0xFFUL) << 44), \ + ((uint64_t)(d3) >> 8) | (((uint64_t)(d4) & 0xFFFFFFFUL) << 24), \ + ((uint64_t)(d4) >> 28) | (((uint64_t)(d5)) << 4) | (((uint64_t)(d6) & 0xFFFFUL) << 36), \ + ((uint64_t)(d6) >> 16) | (((uint64_t)(d7)) << 16) \ } #ifdef VERIFY @@ -35,13 +35,13 @@ typedef struct { typedef struct { uint64_t n[4]; -} secp256k1_fe_storage_t; +} secp256k1_fe_storage; #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ \ - (d0) | ((uint64_t)(d1)) << 32, \ - (d2) | ((uint64_t)(d3)) << 32, \ - (d4) | ((uint64_t)(d5)) << 32, \ - (d6) | ((uint64_t)(d7)) << 32 \ + (d0) | (((uint64_t)(d1)) << 32), \ + (d2) | (((uint64_t)(d3)) << 32), \ + (d4) | (((uint64_t)(d5)) << 32), \ + (d6) | (((uint64_t)(d7)) << 32) \ }} #endif diff --git a/src/secp256k1/src/field_5x52_impl.h b/src/secp256k1/src/field_5x52_impl.h index bda4c3dfc2..b31e24ab81 100644 --- a/src/secp256k1/src/field_5x52_impl.h +++ b/src/secp256k1/src/field_5x52_impl.h @@ -31,7 +31,7 @@ */ #ifdef VERIFY -static void secp256k1_fe_verify(const secp256k1_fe_t *a) { +static void secp256k1_fe_verify(const secp256k1_fe *a) { const uint64_t *d = a->n; int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; /* secp256k1 'p' value defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ @@ -51,12 +51,12 @@ static void secp256k1_fe_verify(const secp256k1_fe_t *a) { VERIFY_CHECK(r == 1); } #else -static void secp256k1_fe_verify(const secp256k1_fe_t *a) { +static void secp256k1_fe_verify(const secp256k1_fe *a) { (void)a; } #endif -static void secp256k1_fe_normalize(secp256k1_fe_t *r) { +static void secp256k1_fe_normalize(secp256k1_fe *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 */ @@ -99,7 +99,7 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) { #endif } -static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) { +static void secp256k1_fe_normalize_weak(secp256k1_fe *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 */ @@ -123,7 +123,7 @@ static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) { #endif } -static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { +static void secp256k1_fe_normalize_var(secp256k1_fe *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 */ @@ -167,7 +167,7 @@ static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { #endif } -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { +static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r) { uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ @@ -190,7 +190,7 @@ static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL); } -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { +static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r) { uint64_t t0, t1, t2, t3, t4; uint64_t z0, z1; uint64_t x; @@ -219,7 +219,7 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { t4 &= 0x0FFFFFFFFFFFFULL; - t1 += (t0 >> 52); t0 = z0; + t1 += (t0 >> 52); t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1; t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2; t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3; @@ -231,7 +231,7 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL); } -SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) { r->n[0] = a; r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; #ifdef VERIFY @@ -241,7 +241,7 @@ SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { #endif } -SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { +SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe *a) { const uint64_t *t = a->n; #ifdef VERIFY VERIFY_CHECK(a->normalized); @@ -250,7 +250,7 @@ SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { 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) { +SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); @@ -258,7 +258,7 @@ SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) { return a->n[0] & 1; } -SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { +SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) { int i; #ifdef VERIFY a->magnitude = 0; @@ -269,7 +269,7 @@ SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { } } -static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { +static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { int i; #ifdef VERIFY VERIFY_CHECK(a->normalized); @@ -288,7 +288,7 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b return 0; } -static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { +static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) { int i; r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; for (i=0; i<32; i++) { @@ -311,7 +311,7 @@ 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) { +static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) { int i; #ifdef VERIFY VERIFY_CHECK(a->normalized); @@ -329,7 +329,7 @@ static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { } } -SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) { +SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { #ifdef VERIFY VERIFY_CHECK(a->magnitude <= m); secp256k1_fe_verify(a); @@ -346,7 +346,7 @@ SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp25 #endif } -SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { r->n[0] *= a; r->n[1] *= a; r->n[2] *= a; @@ -359,7 +359,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) { #endif } -SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a) { #ifdef VERIFY secp256k1_fe_verify(a); #endif @@ -375,7 +375,7 @@ SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1 #endif } -static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) { +static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { #ifdef VERIFY VERIFY_CHECK(a->magnitude <= 8); VERIFY_CHECK(b->magnitude <= 8); @@ -391,7 +391,7 @@ static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const s #endif } -static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->magnitude <= 8); secp256k1_fe_verify(a); @@ -404,7 +404,7 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { #endif } -static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) { +static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { uint64_t mask0, mask1; mask0 = flag + ~((uint64_t)0); mask1 = ~mask0; @@ -414,12 +414,14 @@ static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); #ifdef VERIFY - r->magnitude = (r->magnitude & mask0) | (a->magnitude & mask1); - r->normalized = (r->normalized & mask0) | (a->normalized & mask1); + if (a->magnitude > r->magnitude) { + r->magnitude = a->magnitude; + } + r->normalized &= a->normalized; #endif } -static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag) { +static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { uint64_t mask0, mask1; mask0 = flag + ~((uint64_t)0); mask1 = ~mask0; @@ -429,7 +431,7 @@ static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); } -static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t *a) { +static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->normalized); #endif @@ -439,7 +441,7 @@ static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_f r->n[3] = a->n[3] >> 36 | a->n[4] << 16; } -static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t *a) { +static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { r->n[0] = a->n[0] & 0xFFFFFFFFFFFFFULL; r->n[1] = a->n[0] >> 52 | ((a->n[1] << 12) & 0xFFFFFFFFFFFFFULL); r->n[2] = a->n[1] >> 40 | ((a->n[2] << 24) & 0xFFFFFFFFFFFFFULL); diff --git a/src/secp256k1/src/field_impl.h b/src/secp256k1/src/field_impl.h index e6ec11e8f2..77f4aae2f9 100644 --- a/src/secp256k1/src/field_impl.h +++ b/src/secp256k1/src/field_impl.h @@ -21,15 +21,24 @@ #error "Please select field implementation" #endif -SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { - secp256k1_fe_t na; +SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b) { + secp256k1_fe na; secp256k1_fe_negate(&na, a, 1); secp256k1_fe_add(&na, b); return secp256k1_fe_normalizes_to_zero_var(&na); } -static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { - secp256k1_fe_t x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; +static int secp256k1_fe_sqrt_var(secp256k1_fe *r, const secp256k1_fe *a) { + /** Given that p is congruent to 3 mod 4, we can compute the square root of + * a mod p as the (p+1)/4'th power of a. + * + * As (p+1)/4 is an even number, it will have the same result for a and for + * (-a). Only one of these two numbers actually has a square root however, + * so we test at the end by squaring and comparing to the input. + * Also because (p+1)/4 is an even number, the computed square root is + * itself always a square (a ** ((p+1)/4) is the square of a ** ((p+1)/8)). + */ + secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; int j; /** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in @@ -117,8 +126,8 @@ static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { return secp256k1_fe_equal_var(&t1, a); } -static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a) { - secp256k1_fe_t x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; +static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a) { + secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; int j; /** The binary representation of (p - 2) has 5 blocks of 1s, with lengths in @@ -207,11 +216,15 @@ static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a) { secp256k1_fe_mul(r, a, &t1); } -static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a) { #if defined(USE_FIELD_INV_BUILTIN) secp256k1_fe_inv(r, a); #elif defined(USE_FIELD_INV_NUM) - secp256k1_num_t n, m; + secp256k1_num n, m; + static const secp256k1_fe negone = SECP256K1_FE_CONST( + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, 0xFFFFFC2EUL + ); /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ static const unsigned char prime[32] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, @@ -220,21 +233,28 @@ static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F }; unsigned char b[32]; - secp256k1_fe_t c = *a; + int res; + secp256k1_fe c = *a; secp256k1_fe_normalize_var(&c); secp256k1_fe_get_b32(b, &c); secp256k1_num_set_bin(&n, b, 32); secp256k1_num_set_bin(&m, prime, 32); secp256k1_num_mod_inverse(&n, &n, &m); secp256k1_num_get_bin(b, 32, &n); - VERIFY_CHECK(secp256k1_fe_set_b32(r, b)); + res = secp256k1_fe_set_b32(r, b); + (void)res; + VERIFY_CHECK(res); + /* Verify the result is the (unique) valid inverse using non-GMP code. */ + secp256k1_fe_mul(&c, &c, r); + secp256k1_fe_add(&c, &negone); + CHECK(secp256k1_fe_normalizes_to_zero_var(&c)); #else #error "Please select field inverse implementation" #endif } -static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp256k1_fe_t *a) { - secp256k1_fe_t u; +static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe *r, const secp256k1_fe *a) { + secp256k1_fe u; size_t i; if (len < 1) { return; @@ -252,7 +272,7 @@ static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp25 secp256k1_fe_inv_var(&u, &r[--i]); while (i > 0) { - int j = i--; + size_t j = i--; secp256k1_fe_mul(&r[j], &r[i], &u); secp256k1_fe_mul(&u, &u, &a[j]); } diff --git a/src/secp256k1/src/gen_context.c b/src/secp256k1/src/gen_context.c new file mode 100644 index 0000000000..1835fd491d --- /dev/null +++ b/src/secp256k1/src/gen_context.c @@ -0,0 +1,74 @@ +/********************************************************************** + * Copyright (c) 2013, 2014, 2015 Thomas Daede, Cory Fields * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#define USE_BASIC_CONFIG 1 + +#include "basic-config.h" +#include "include/secp256k1.h" +#include "field_impl.h" +#include "scalar_impl.h" +#include "group_impl.h" +#include "ecmult_gen_impl.h" + +static void default_error_callback_fn(const char* str, void* data) { + (void)data; + fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); + abort(); +} + +static const secp256k1_callback default_error_callback = { + default_error_callback_fn, + NULL +}; + +int main(int argc, char **argv) { + secp256k1_ecmult_gen_context ctx; + int inner; + int outer; + FILE* fp; + + (void)argc; + (void)argv; + + fp = fopen("src/ecmult_static_context.h","w"); + if (fp == NULL) { + fprintf(stderr, "Could not open src/ecmult_static_context.h for writing!\n"); + return -1; + } + + fprintf(fp, "#ifndef _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); + fprintf(fp, "#define _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); + fprintf(fp, "#include \"group.h\"\n"); + fprintf(fp, "#define SC SECP256K1_GE_STORAGE_CONST\n"); + fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_static_context[64][16] = {\n"); + + secp256k1_ecmult_gen_context_init(&ctx); + secp256k1_ecmult_gen_context_build(&ctx, &default_error_callback); + for(outer = 0; outer != 64; outer++) { + fprintf(fp,"{\n"); + for(inner = 0; inner != 16; inner++) { + fprintf(fp," SC(%uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu)", SECP256K1_GE_STORAGE_CONST_GET((*ctx.prec)[outer][inner])); + if (inner != 15) { + fprintf(fp,",\n"); + } else { + fprintf(fp,"\n"); + } + } + if (outer != 63) { + fprintf(fp,"},\n"); + } else { + fprintf(fp,"}\n"); + } + } + fprintf(fp,"};\n"); + secp256k1_ecmult_gen_context_clear(&ctx); + + fprintf(fp, "#undef SC\n"); + fprintf(fp, "#endif\n"); + fclose(fp); + + return 0; +} diff --git a/src/secp256k1/src/group.h b/src/secp256k1/src/group.h index 0b08b3b991..ebfe1ca70c 100644 --- a/src/secp256k1/src/group.h +++ b/src/secp256k1/src/group.h @@ -12,110 +12,130 @@ /** A group element of the secp256k1 curve, in affine coordinates. */ typedef struct { - secp256k1_fe_t x; - secp256k1_fe_t y; + secp256k1_fe x; + secp256k1_fe y; int infinity; /* whether this represents the point at infinity */ -} secp256k1_ge_t; +} secp256k1_ge; #define SECP256K1_GE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), 0} #define SECP256K1_GE_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} /** 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; + secp256k1_fe x; /* actual X: x/z^2 */ + secp256k1_fe y; /* actual Y: y/z^3 */ + secp256k1_fe z; int infinity; /* whether this represents the point at infinity */ -} secp256k1_gej_t; +} secp256k1_gej; #define SECP256K1_GEJ_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1), 0} #define SECP256K1_GEJ_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} typedef struct { - secp256k1_fe_storage_t x; - secp256k1_fe_storage_t y; -} secp256k1_ge_storage_t; + secp256k1_fe_storage x; + secp256k1_fe_storage y; +} secp256k1_ge_storage; #define SECP256K1_GE_STORAGE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_STORAGE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_STORAGE_CONST((i),(j),(k),(l),(m),(n),(o),(p))} -/** Set a group element equal to the point at infinity */ -static void secp256k1_ge_set_infinity(secp256k1_ge_t *r); +#define SECP256K1_GE_STORAGE_CONST_GET(t) SECP256K1_FE_STORAGE_CONST_GET(t.x), SECP256K1_FE_STORAGE_CONST_GET(t.y) /** 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); +static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y); + +/** Set a group element (affine) equal to the point with the given X coordinate + * and a Y coordinate that is a quadratic residue modulo p. The return value + * is true iff a coordinate with the given X coordinate exists. + */ +static int secp256k1_ge_set_xquad_var(secp256k1_ge *r, const secp256k1_fe *x); /** 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); +static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd); /** Check whether a group element is the point at infinity. */ -static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a); +static int secp256k1_ge_is_infinity(const secp256k1_ge *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 int secp256k1_ge_is_valid_var(const secp256k1_ge *a); -static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a); +static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *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); +static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a); /** Set a batch of group elements equal to the inputs given in jacobian coordinates */ -static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a); +static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_callback *cb); +/** Set a batch of group elements equal to the inputs given in jacobian + * coordinates (with known z-ratios). zr must contain the known z-ratios such + * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. */ +static void secp256k1_ge_set_table_gej_var(size_t len, secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr); -/** Set a group element (jacobian) equal to the point at infinity. */ -static void secp256k1_gej_set_infinity(secp256k1_gej_t *r); +/** Bring a batch inputs given in jacobian coordinates (with known z-ratios) to + * the same global z "denominator". zr must contain the known z-ratios such + * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. The x and y + * coordinates of the result are stored in r, the common z coordinate is + * stored in globalz. */ +static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp256k1_fe *globalz, const secp256k1_gej *a, const secp256k1_fe *zr); -/** 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 the point at infinity. */ +static void secp256k1_gej_set_infinity(secp256k1_gej *r); /** 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); +static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a); /** Compare the X coordinate of a group element (jacobian). */ -static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a); +static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a); /** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ -static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a); +static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a); /** Check whether a group element is the point at infinity. */ -static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a); +static int secp256k1_gej_is_infinity(const secp256k1_gej *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 double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). + * a may not be zero. Constant time. */ +static void secp256k1_gej_double_nonzero(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); -/** 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 double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). */ +static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); + +/** Set r equal to the sum of a and b. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */ +static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr); /** 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); +static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *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); + guarantee, and b is allowed to be infinity. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */ +static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr); + +/** Set r equal to the sum of a and b (with the inverse of b's Z coordinate passed as bzinv). */ +static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv); #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); +static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a); #endif -/** Clear a secp256k1_gej_t to prevent leaking sensitive information. */ -static void secp256k1_gej_clear(secp256k1_gej_t *r); +/** Clear a secp256k1_gej to prevent leaking sensitive information. */ +static void secp256k1_gej_clear(secp256k1_gej *r); -/** Clear a secp256k1_ge_t to prevent leaking sensitive information. */ -static void secp256k1_ge_clear(secp256k1_ge_t *r); +/** Clear a secp256k1_ge to prevent leaking sensitive information. */ +static void secp256k1_ge_clear(secp256k1_ge *r); /** Convert a group element to the storage type. */ -static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_ge_t*); +static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a); /** Convert a group element back from the storage type. */ -static void secp256k1_ge_from_storage(secp256k1_ge_t *r, const secp256k1_ge_storage_t*); +static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a); /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ -static void secp256k1_ge_storage_cmov(secp256k1_ge_storage_t *r, const secp256k1_ge_storage_t *a, int flag); +static void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag); /** Rescale a jacobian point by b which must be non-zero. Constant-time. */ -static void secp256k1_gej_rescale(secp256k1_gej_t *r, const secp256k1_fe_t *b); +static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *b); #endif diff --git a/src/secp256k1/src/group_impl.h b/src/secp256k1/src/group_impl.h index 0f64576fbb..42e2f6e6eb 100644 --- a/src/secp256k1/src/group_impl.h +++ b/src/secp256k1/src/group_impl.h @@ -16,35 +16,41 @@ /** Generator for secp256k1, value 'g' defined in * "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ -static const secp256k1_ge_t secp256k1_ge_const_g = SECP256K1_GE_CONST( +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( 0x79BE667EUL, 0xF9DCBBACUL, 0x55A06295UL, 0xCE870B07UL, 0x029BFCDBUL, 0x2DCE28D9UL, 0x59F2815BUL, 0x16F81798UL, 0x483ADA77UL, 0x26A3C465UL, 0x5DA4FBFCUL, 0x0E1108A8UL, 0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL ); -static void secp256k1_ge_set_infinity(secp256k1_ge_t *r) { - r->infinity = 1; +static void secp256k1_ge_set_gej_zinv(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zi) { + secp256k1_fe zi2; + secp256k1_fe zi3; + secp256k1_fe_sqr(&zi2, zi); + secp256k1_fe_mul(&zi3, &zi2, zi); + secp256k1_fe_mul(&r->x, &a->x, &zi2); + secp256k1_fe_mul(&r->y, &a->y, &zi3); + r->infinity = a->infinity; } -static void secp256k1_ge_set_xy(secp256k1_ge_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y) { +static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y) { r->infinity = 0; r->x = *x; r->y = *y; } -static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a) { +static int secp256k1_ge_is_infinity(const secp256k1_ge *a) { return a->infinity; } -static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a) { +static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a) { *r = *a; secp256k1_fe_normalize_weak(&r->y); secp256k1_fe_negate(&r->y, &r->y, 1); } -static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a) { - secp256k1_fe_t z2, z3; +static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a) { + secp256k1_fe z2, z3; r->infinity = a->infinity; secp256k1_fe_inv(&a->z, &a->z); secp256k1_fe_sqr(&z2, &a->z); @@ -56,8 +62,8 @@ static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a) { r->y = a->y; } -static void secp256k1_ge_set_gej_var(secp256k1_ge_t *r, secp256k1_gej_t *a) { - secp256k1_fe_t z2, z3; +static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) { + secp256k1_fe z2, z3; r->infinity = a->infinity; if (a->infinity) { return; @@ -72,19 +78,19 @@ static void secp256k1_ge_set_gej_var(secp256k1_ge_t *r, secp256k1_gej_t *a) { r->y = a->y; } -static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a) { - secp256k1_fe_t *az; - secp256k1_fe_t *azi; +static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_callback *cb) { + secp256k1_fe *az; + secp256k1_fe *azi; size_t i; size_t count = 0; - az = (secp256k1_fe_t *)checked_malloc(sizeof(secp256k1_fe_t) * len); + az = (secp256k1_fe *)checked_malloc(cb, sizeof(secp256k1_fe) * len); for (i = 0; i < len; i++) { if (!a[i].infinity) { az[count++] = a[i].z; } } - azi = (secp256k1_fe_t *)checked_malloc(sizeof(secp256k1_fe_t) * count); + azi = (secp256k1_fe *)checked_malloc(cb, sizeof(secp256k1_fe) * count); secp256k1_fe_inv_all_var(count, azi, az); free(az); @@ -92,53 +98,86 @@ static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const se for (i = 0; i < len; i++) { r[i].infinity = a[i].infinity; if (!a[i].infinity) { - secp256k1_fe_t zi2, zi3; - secp256k1_fe_t *zi = &azi[count++]; - secp256k1_fe_sqr(&zi2, zi); - 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); + secp256k1_ge_set_gej_zinv(&r[i], &a[i], &azi[count++]); } } free(azi); } -static void secp256k1_gej_set_infinity(secp256k1_gej_t *r) { +static void secp256k1_ge_set_table_gej_var(size_t len, secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr) { + size_t i = len - 1; + secp256k1_fe zi; + + if (len > 0) { + /* Compute the inverse of the last z coordinate, and use it to compute the last affine output. */ + secp256k1_fe_inv(&zi, &a[i].z); + secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zi); + + /* Work out way backwards, using the z-ratios to scale the x/y values. */ + while (i > 0) { + secp256k1_fe_mul(&zi, &zi, &zr[i]); + i--; + secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zi); + } + } +} + +static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp256k1_fe *globalz, const secp256k1_gej *a, const secp256k1_fe *zr) { + size_t i = len - 1; + secp256k1_fe zs; + + if (len > 0) { + /* The z of the final point gives us the "global Z" for the table. */ + r[i].x = a[i].x; + r[i].y = a[i].y; + *globalz = a[i].z; + r[i].infinity = 0; + zs = zr[i]; + + /* Work our way backwards, using the z-ratios to scale the x/y values. */ + while (i > 0) { + if (i != len - 1) { + secp256k1_fe_mul(&zs, &zs, &zr[i]); + } + i--; + secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zs); + } + } +} + +static void secp256k1_gej_set_infinity(secp256k1_gej *r) { r->infinity = 1; secp256k1_fe_set_int(&r->x, 0); secp256k1_fe_set_int(&r->y, 0); secp256k1_fe_set_int(&r->z, 0); } -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) { +static void secp256k1_gej_clear(secp256k1_gej *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) { +static void secp256k1_ge_clear(secp256k1_ge *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) { - secp256k1_fe_t x2, x3, c; +static int secp256k1_ge_set_xquad_var(secp256k1_ge *r, const secp256k1_fe *x) { + secp256k1_fe x2, x3, c; r->x = *x; secp256k1_fe_sqr(&x2, x); secp256k1_fe_mul(&x3, x, &x2); r->infinity = 0; secp256k1_fe_set_int(&c, 7); secp256k1_fe_add(&c, &x3); - if (!secp256k1_fe_sqrt_var(&r->y, &c)) { + return secp256k1_fe_sqrt_var(&r->y, &c); +} + +static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd) { + if (!secp256k1_ge_set_xquad_var(r, x)) { return 0; } secp256k1_fe_normalize_var(&r->y); @@ -146,24 +185,25 @@ static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, i 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) { +static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a) { r->infinity = a->infinity; r->x = a->x; r->y = a->y; secp256k1_fe_set_int(&r->z, 1); } -static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a) { - secp256k1_fe_t r, r2; +static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a) { + secp256k1_fe r, r2; VERIFY_CHECK(!a->infinity); secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x); r2 = a->x; secp256k1_fe_normalize_weak(&r2); return secp256k1_fe_equal_var(&r, &r2); } -static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a) { +static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a) { r->infinity = a->infinity; r->x = a->x; r->y = a->y; @@ -172,12 +212,12 @@ static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a) { secp256k1_fe_negate(&r->y, &r->y, 1); } -static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a) { +static int secp256k1_gej_is_infinity(const secp256k1_gej *a) { return a->infinity; } -static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) { - secp256k1_fe_t y2, x3, z2, z6; +static int secp256k1_gej_is_valid_var(const secp256k1_gej *a) { + secp256k1_fe y2, x3, z2, z6; if (a->infinity) { return 0; } @@ -196,8 +236,8 @@ static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) { return secp256k1_fe_equal_var(&y2, &x3); } -static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) { - secp256k1_fe_t y2, x3, c; +static int secp256k1_ge_is_valid_var(const secp256k1_ge *a) { + secp256k1_fe y2, x3, c; if (a->infinity) { return 0; } @@ -210,18 +250,27 @@ static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) { return secp256k1_fe_equal_var(&y2, &x3); } -static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) { +static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) { /* Operations: 3 mul, 4 sqr, 0 normalize, 12 mul_int/add/negate */ - secp256k1_fe_t t1,t2,t3,t4; + secp256k1_fe t1,t2,t3,t4; /** For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity, * Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have * y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p. */ r->infinity = a->infinity; if (r->infinity) { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 1); + } return; } + if (rzr != NULL) { + *rzr = a->y; + secp256k1_fe_normalize_weak(rzr); + secp256k1_fe_mul_int(rzr, 2); + } + 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); @@ -244,17 +293,29 @@ static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t * 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) { +static SECP256K1_INLINE void secp256k1_gej_double_nonzero(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) { + VERIFY_CHECK(!secp256k1_gej_is_infinity(a)); + secp256k1_gej_double_var(r, a, rzr); +} + +static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr) { /* Operations: 12 mul, 4 sqr, 2 normalize, 12 mul_int/add/negate */ - secp256k1_fe_t z22, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; + secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; + if (a->infinity) { + VERIFY_CHECK(rzr == NULL); *r = *b; return; } + if (b->infinity) { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 1); + } *r = *a; return; } + r->infinity = 0; secp256k1_fe_sqr(&z22, &b->z); secp256k1_fe_sqr(&z12, &a->z); @@ -266,8 +327,11 @@ static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); if (secp256k1_fe_normalizes_to_zero_var(&h)) { if (secp256k1_fe_normalizes_to_zero_var(&i)) { - secp256k1_gej_double_var(r, a); + secp256k1_gej_double_var(r, a, rzr); } else { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 0); + } r->infinity = 1; } return; @@ -275,7 +339,11 @@ static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, secp256k1_fe_sqr(&i2, &i); secp256k1_fe_sqr(&h2, &h); 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_mul(&h, &h, &b->z); + if (rzr != NULL) { + *rzr = h; + } + secp256k1_fe_mul(&r->z, &a->z, &h); 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); @@ -283,21 +351,23 @@ static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, 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) { +static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr) { /* 8 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */ - secp256k1_fe_t z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; + secp256k1_fe z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; if (a->infinity) { - r->infinity = b->infinity; - r->x = b->x; - r->y = b->y; - secp256k1_fe_set_int(&r->z, 1); + VERIFY_CHECK(rzr == NULL); + secp256k1_gej_set_ge(r, b); return; } if (b->infinity) { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 1); + } *r = *a; return; } r->infinity = 0; + secp256k1_fe_sqr(&z12, &a->z); u1 = a->x; secp256k1_fe_normalize_weak(&u1); secp256k1_fe_mul(&u2, &b->x, &z12); @@ -307,7 +377,69 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t * secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); if (secp256k1_fe_normalizes_to_zero_var(&h)) { if (secp256k1_fe_normalizes_to_zero_var(&i)) { - secp256k1_gej_double_var(r, a); + secp256k1_gej_double_var(r, a, rzr); + } else { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 0); + } + r->infinity = 1; + } + return; + } + secp256k1_fe_sqr(&i2, &i); + secp256k1_fe_sqr(&h2, &h); + secp256k1_fe_mul(&h3, &h, &h2); + if (rzr != NULL) { + *rzr = h; + } + secp256k1_fe_mul(&r->z, &a->z, &h); + 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_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv) { + /* 9 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */ + secp256k1_fe az, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; + + if (b->infinity) { + *r = *a; + return; + } + if (a->infinity) { + secp256k1_fe bzinv2, bzinv3; + r->infinity = b->infinity; + secp256k1_fe_sqr(&bzinv2, bzinv); + secp256k1_fe_mul(&bzinv3, &bzinv2, bzinv); + secp256k1_fe_mul(&r->x, &b->x, &bzinv2); + secp256k1_fe_mul(&r->y, &b->y, &bzinv3); + secp256k1_fe_set_int(&r->z, 1); + return; + } + r->infinity = 0; + + /** We need to calculate (rx,ry,rz) = (ax,ay,az) + (bx,by,1/bzinv). Due to + * secp256k1's isomorphism we can multiply the Z coordinates on both sides + * by bzinv, and get: (rx,ry,rz*bzinv) = (ax,ay,az*bzinv) + (bx,by,1). + * This means that (rx,ry,rz) can be calculated as + * (ax,ay,az*bzinv) + (bx,by,1), when not applying the bzinv factor to rz. + * The variable az below holds the modified Z coordinate for a, which is used + * for the computation of rx and ry, but not for rz. + */ + secp256k1_fe_mul(&az, &a->z, bzinv); + + secp256k1_fe_sqr(&z12, &az); + u1 = a->x; secp256k1_fe_normalize_weak(&u1); + secp256k1_fe_mul(&u2, &b->x, &z12); + s1 = a->y; secp256k1_fe_normalize_weak(&s1); + secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &az); + secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); + secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); + if (secp256k1_fe_normalizes_to_zero_var(&h)) { + if (secp256k1_fe_normalizes_to_zero_var(&i)) { + secp256k1_gej_double_var(r, a, NULL); } else { r->infinity = 1; } @@ -324,11 +456,13 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t * 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) { - /* Operations: 7 mul, 5 sqr, 5 normalize, 17 mul_int/add/negate/cmov */ - static const secp256k1_fe_t fe_1 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_fe_t zz, u1, u2, s1, s2, z, t, m, n, q, rr; - int infinity; + +static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b) { + /* Operations: 7 mul, 5 sqr, 4 normalize, 21 mul_int/add/negate/cmov */ + static const secp256k1_fe fe_1 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); + secp256k1_fe zz, u1, u2, s1, s2, t, tt, m, n, q, rr; + secp256k1_fe m_alt, rr_alt; + int infinity, degenerate; VERIFY_CHECK(!b->infinity); VERIFY_CHECK(a->infinity == 0 || a->infinity == 1); @@ -352,53 +486,102 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c * 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.) + * + * This formula has the benefit of being the same for both addition + * of distinct points and doubling. However, it breaks down in the + * case that either point is infinity, or that y1 = -y2. We handle + * these cases in the following ways: + * + * - If b is infinity we simply bail by means of a VERIFY_CHECK. + * + * - If a is infinity, we detect this, and at the end of the + * computation replace the result (which will be meaningless, + * but we compute to be constant-time) with b.x : b.y : 1. + * + * - If a = -b, we have y1 = -y2, which is a degenerate case. + * But here the answer is infinity, so we simply set the + * infinity flag of the result, overriding the computed values + * without even needing to cmov. + * + * - If y1 = -y2 but x1 != x2, which does occur thanks to certain + * properties of our curve (specifically, 1 has nontrivial cube + * roots in our field, and the curve equation has no x coefficient) + * then the answer is not infinity but also not given by the above + * equation. In this case, we cmov in place an alternate expression + * for lambda. Specifically (y1 - y2)/(x1 - x2). Where both these + * expressions for lambda are defined, they are equal, and can be + * obtained from each other by multiplication by (y1 + y2)/(y1 + y2) + * then substitution of x^3 + 7 for y^2 (using the curve equation). + * For all pairs of nonzero points (a, b) at least one is defined, + * so this covers everything. */ secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */ u1 = a->x; secp256k1_fe_normalize_weak(&u1); /* u1 = U1 = X1*Z2^2 (1) */ secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */ s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */ - secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z2^2 (1) */ + secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z1^2 (1) */ secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */ - z = a->z; /* z = Z = Z1*Z2 (8) */ t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (2) */ m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (2) */ - secp256k1_fe_sqr(&n, &m); /* n = M^2 (1) */ - secp256k1_fe_mul(&q, &n, &t); /* q = Q = T*M^2 (1) */ - secp256k1_fe_sqr(&n, &n); /* n = M^4 (1) */ 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_negate(&m_alt, &u2, 1); /* Malt = -X2*Z1^2 */ + secp256k1_fe_mul(&tt, &u1, &m_alt); /* tt = -U1*U2 (2) */ + secp256k1_fe_add(&rr, &tt); /* rr = R = T^2-U1*U2 (3) */ + /** If lambda = R/M = 0/0 we have a problem (except in the "trivial" + * case that Z = z1z2 = 0, and this is special-cased later on). */ + degenerate = secp256k1_fe_normalizes_to_zero(&m) & + secp256k1_fe_normalizes_to_zero(&rr); + /* This only occurs when y1 == -y2 and x1^3 == x2^3, but x1 != x2. + * This means either x1 == beta*x2 or beta*x1 == x2, where beta is + * a nontrivial cube root of one. In either case, an alternate + * non-indeterminate expression for lambda is (y1 - y2)/(x1 - x2), + * so we set R/M equal to this. */ + rr_alt = s1; + secp256k1_fe_mul_int(&rr_alt, 2); /* rr = Y1*Z2^3 - Y2*Z1^3 (2) */ + secp256k1_fe_add(&m_alt, &u1); /* Malt = X1*Z2^2 - X2*Z1^2 */ + + secp256k1_fe_cmov(&rr_alt, &rr, !degenerate); + secp256k1_fe_cmov(&m_alt, &m, !degenerate); + /* Now Ralt / Malt = lambda and is guaranteed not to be 0/0. + * From here on out Ralt and Malt represent the numerator + * and denominator of lambda; R and M represent the explicit + * expressions x1^2 + x2^2 + x1x2 and y1 + y2. */ + secp256k1_fe_sqr(&n, &m_alt); /* n = Malt^2 (1) */ + secp256k1_fe_mul(&q, &n, &t); /* q = Q = T*Malt^2 (1) */ + /* These two lines use the observation that either M == Malt or M == 0, + * so M^3 * Malt is either Malt^4 (which is computed by squaring), or + * zero (which is "computed" by cmov). So the cost is one squaring + * versus two multiplications. */ + secp256k1_fe_sqr(&n, &n); + secp256k1_fe_cmov(&n, &m, degenerate); /* n = M^3 * Malt (2) */ + secp256k1_fe_sqr(&t, &rr_alt); /* t = Ralt^2 (1) */ + secp256k1_fe_mul(&r->z, &a->z, &m_alt); /* r->z = Malt*Z (1) */ infinity = secp256k1_fe_normalizes_to_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_mul_int(&r->z, 2); /* r->z = Z3 = 2*Malt*Z (2) */ 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_add(&t, &q); /* t = Ralt^2-Q (3) */ + secp256k1_fe_normalize_weak(&t); + r->x = t; /* r->x = Ralt^2-Q (1) */ + secp256k1_fe_mul_int(&t, 2); /* t = 2*x3 (2) */ + secp256k1_fe_add(&t, &q); /* t = 2*x3 - Q: (4) */ + secp256k1_fe_mul(&t, &t, &rr_alt); /* t = Ralt*(2*x3 - Q) (1) */ + secp256k1_fe_add(&t, &n); /* t = Ralt*(2*x3 - Q) + M^3*Malt (3) */ + secp256k1_fe_negate(&r->y, &t, 3); /* r->y = Ralt*(Q - 2x3) - M^3*Malt (4) */ secp256k1_fe_normalize_weak(&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) */ + secp256k1_fe_mul_int(&r->x, 4); /* r->x = X3 = 4*(Ralt^2-Q) */ + secp256k1_fe_mul_int(&r->y, 4); /* r->y = Y3 = 4*Ralt*(Q - 2x3) - 4*M^3*Malt (4) */ - /** In case a->infinity == 1, the above code results in r->x, r->y, and r->z all equal to 0. - * Replace r with b->x, b->y, 1 in that case. - */ + /** In case a->infinity == 1, replace r with (b->x, b->y, 1). */ secp256k1_fe_cmov(&r->x, &b->x, a->infinity); secp256k1_fe_cmov(&r->y, &b->y, a->infinity); secp256k1_fe_cmov(&r->z, &fe_1, a->infinity); r->infinity = infinity; } -static void secp256k1_gej_rescale(secp256k1_gej_t *r, const secp256k1_fe_t *s) { +static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *s) { /* Operations: 4 mul, 1 sqr */ - secp256k1_fe_t zz; + secp256k1_fe zz; VERIFY_CHECK(!secp256k1_fe_is_zero(s)); secp256k1_fe_sqr(&zz, s); secp256k1_fe_mul(&r->x, &r->x, &zz); /* r->x *= s^2 */ @@ -407,8 +590,8 @@ static void secp256k1_gej_rescale(secp256k1_gej_t *r, const secp256k1_fe_t *s) { secp256k1_fe_mul(&r->z, &r->z, s); /* r->z *= s */ } -static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_ge_t *a) { - secp256k1_fe_t x, y; +static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a) { + secp256k1_fe x, y; VERIFY_CHECK(!a->infinity); x = a->x; secp256k1_fe_normalize(&x); @@ -418,20 +601,20 @@ static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_g secp256k1_fe_to_storage(&r->y, &y); } -static void secp256k1_ge_from_storage(secp256k1_ge_t *r, const secp256k1_ge_storage_t *a) { +static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a) { secp256k1_fe_from_storage(&r->x, &a->x); secp256k1_fe_from_storage(&r->y, &a->y); r->infinity = 0; } -static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage_t *r, const secp256k1_ge_storage_t *a, int flag) { +static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag) { secp256k1_fe_storage_cmov(&r->x, &a->x, flag); secp256k1_fe_storage_cmov(&r->y, &a->y, flag); } #ifdef USE_ENDOMORPHISM -static void secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a) { - static const secp256k1_fe_t beta = SECP256K1_FE_CONST( +static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a) { + static const secp256k1_fe beta = SECP256K1_FE_CONST( 0x7ae96a2bul, 0x657c0710ul, 0x6e64479eul, 0xac3434e9ul, 0x9cf04975ul, 0x12f58995ul, 0xc1396c28ul, 0x719501eeul ); diff --git a/src/secp256k1/src/hash.h b/src/secp256k1/src/hash.h index 843423d7f7..0ff01e63fa 100644 --- a/src/secp256k1/src/hash.h +++ b/src/secp256k1/src/hash.h @@ -34,7 +34,7 @@ typedef struct { int retry; } secp256k1_rfc6979_hmac_sha256_t; -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen, const unsigned char *rnd, size_t rndlen); +static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen); static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen); static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng); diff --git a/src/secp256k1/src/hash_impl.h b/src/secp256k1/src/hash_impl.h index 9828827bcd..ae55df6d8a 100644 --- a/src/secp256k1/src/hash_impl.h +++ b/src/secp256k1/src/hash_impl.h @@ -202,7 +202,7 @@ static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsign } -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen, const unsigned char *rnd, size_t rndlen) { +static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen) { secp256k1_hmac_sha256_t hmac; static const unsigned char zero[1] = {0x00}; static const unsigned char one[1] = {0x01}; @@ -215,11 +215,6 @@ static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha2 secp256k1_hmac_sha256_write(&hmac, rng->v, 32); secp256k1_hmac_sha256_write(&hmac, zero, 1); secp256k1_hmac_sha256_write(&hmac, key, keylen); - secp256k1_hmac_sha256_write(&hmac, msg, msglen); - if (rnd && rndlen) { - /* RFC6979 3.6 "Additional data". */ - secp256k1_hmac_sha256_write(&hmac, rnd, rndlen); - } secp256k1_hmac_sha256_finalize(&hmac, rng->k); secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); @@ -230,11 +225,6 @@ static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha2 secp256k1_hmac_sha256_write(&hmac, rng->v, 32); secp256k1_hmac_sha256_write(&hmac, one, 1); secp256k1_hmac_sha256_write(&hmac, key, keylen); - secp256k1_hmac_sha256_write(&hmac, msg, msglen); - if (rnd && rndlen) { - /* RFC6979 3.6 "Additional data". */ - secp256k1_hmac_sha256_write(&hmac, rnd, rndlen); - } secp256k1_hmac_sha256_finalize(&hmac, rng->k); secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); diff --git a/src/secp256k1/src/modules/ecdh/Makefile.am.include b/src/secp256k1/src/modules/ecdh/Makefile.am.include new file mode 100644 index 0000000000..670b9c1152 --- /dev/null +++ b/src/secp256k1/src/modules/ecdh/Makefile.am.include @@ -0,0 +1,8 @@ +include_HEADERS += include/secp256k1_ecdh.h +noinst_HEADERS += src/modules/ecdh/main_impl.h +noinst_HEADERS += src/modules/ecdh/tests_impl.h +if USE_BENCHMARK +noinst_PROGRAMS += bench_ecdh +bench_ecdh_SOURCES = src/bench_ecdh.c +bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS) +endif diff --git a/src/secp256k1/src/modules/ecdh/main_impl.h b/src/secp256k1/src/modules/ecdh/main_impl.h new file mode 100644 index 0000000000..c23e4f82f7 --- /dev/null +++ b/src/secp256k1/src/modules/ecdh/main_impl.h @@ -0,0 +1,54 @@ +/********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_MODULE_ECDH_MAIN_ +#define _SECP256K1_MODULE_ECDH_MAIN_ + +#include "include/secp256k1_ecdh.h" +#include "ecmult_const_impl.h" + +int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *result, const secp256k1_pubkey *point, const unsigned char *scalar) { + int ret = 0; + int overflow = 0; + secp256k1_gej res; + secp256k1_ge pt; + secp256k1_scalar s; + ARG_CHECK(result != NULL); + ARG_CHECK(point != NULL); + ARG_CHECK(scalar != NULL); + (void)ctx; + + secp256k1_pubkey_load(ctx, &pt, point); + secp256k1_scalar_set_b32(&s, scalar, &overflow); + if (overflow || secp256k1_scalar_is_zero(&s)) { + ret = 0; + } else { + unsigned char x[32]; + unsigned char y[1]; + secp256k1_sha256_t sha; + + secp256k1_ecmult_const(&res, &pt, &s); + secp256k1_ge_set_gej(&pt, &res); + /* Compute a hash of the point in compressed form + * Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not + * expect its output to be secret and has a timing sidechannel. */ + secp256k1_fe_normalize(&pt.x); + secp256k1_fe_normalize(&pt.y); + secp256k1_fe_get_b32(x, &pt.x); + y[0] = 0x02 | secp256k1_fe_is_odd(&pt.y); + + secp256k1_sha256_initialize(&sha); + secp256k1_sha256_write(&sha, y, sizeof(y)); + secp256k1_sha256_write(&sha, x, sizeof(x)); + secp256k1_sha256_finalize(&sha, result); + ret = 1; + } + + secp256k1_scalar_clear(&s); + return ret; +} + +#endif diff --git a/src/secp256k1/src/modules/ecdh/tests_impl.h b/src/secp256k1/src/modules/ecdh/tests_impl.h new file mode 100644 index 0000000000..7badc9033f --- /dev/null +++ b/src/secp256k1/src/modules/ecdh/tests_impl.h @@ -0,0 +1,75 @@ +/********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_MODULE_ECDH_TESTS_ +#define _SECP256K1_MODULE_ECDH_TESTS_ + +void test_ecdh_generator_basepoint(void) { + unsigned char s_one[32] = { 0 }; + secp256k1_pubkey point[2]; + int i; + + s_one[31] = 1; + /* Check against pubkey creation when the basepoint is the generator */ + for (i = 0; i < 100; ++i) { + secp256k1_sha256_t sha; + unsigned char s_b32[32]; + unsigned char output_ecdh[32]; + unsigned char output_ser[32]; + unsigned char point_ser[33]; + size_t point_ser_len = sizeof(point_ser); + secp256k1_scalar s; + + random_scalar_order(&s); + secp256k1_scalar_get_b32(s_b32, &s); + + /* compute using ECDH function */ + CHECK(secp256k1_ec_pubkey_create(ctx, &point[0], s_one) == 1); + CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32) == 1); + /* compute "explicitly" */ + CHECK(secp256k1_ec_pubkey_create(ctx, &point[1], s_b32) == 1); + CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1); + CHECK(point_ser_len == sizeof(point_ser)); + secp256k1_sha256_initialize(&sha); + secp256k1_sha256_write(&sha, point_ser, point_ser_len); + secp256k1_sha256_finalize(&sha, output_ser); + /* compare */ + CHECK(memcmp(output_ecdh, output_ser, sizeof(output_ser)) == 0); + } +} + +void test_bad_scalar(void) { + unsigned char s_zero[32] = { 0 }; + unsigned char s_overflow[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 + }; + unsigned char s_rand[32] = { 0 }; + unsigned char output[32]; + secp256k1_scalar rand; + secp256k1_pubkey point; + + /* Create random point */ + random_scalar_order(&rand); + secp256k1_scalar_get_b32(s_rand, &rand); + CHECK(secp256k1_ec_pubkey_create(ctx, &point, s_rand) == 1); + + /* Try to multiply it by bad values */ + CHECK(secp256k1_ecdh(ctx, output, &point, s_zero) == 0); + CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 0); + /* ...and a good one */ + s_overflow[31] -= 1; + CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 1); +} + +void run_ecdh_tests(void) { + test_ecdh_generator_basepoint(); + test_bad_scalar(); +} + +#endif diff --git a/src/secp256k1/src/modules/recovery/Makefile.am.include b/src/secp256k1/src/modules/recovery/Makefile.am.include new file mode 100644 index 0000000000..5de3ea33ea --- /dev/null +++ b/src/secp256k1/src/modules/recovery/Makefile.am.include @@ -0,0 +1,8 @@ +include_HEADERS += include/secp256k1_recovery.h +noinst_HEADERS += src/modules/recovery/main_impl.h +noinst_HEADERS += src/modules/recovery/tests_impl.h +if USE_BENCHMARK +noinst_PROGRAMS += bench_recover +bench_recover_SOURCES = src/bench_recover.c +bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS) +endif diff --git a/src/secp256k1/src/modules/recovery/main_impl.h b/src/secp256k1/src/modules/recovery/main_impl.h new file mode 100644 index 0000000000..ec42f4bb6c --- /dev/null +++ b/src/secp256k1/src/modules/recovery/main_impl.h @@ -0,0 +1,193 @@ +/********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_MODULE_RECOVERY_MAIN_ +#define _SECP256K1_MODULE_RECOVERY_MAIN_ + +#include "include/secp256k1_recovery.h" + +static void secp256k1_ecdsa_recoverable_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const secp256k1_ecdsa_recoverable_signature* sig) { + (void)ctx; + if (sizeof(secp256k1_scalar) == 32) { + /* When the secp256k1_scalar type is exactly 32 byte, use its + * representation inside secp256k1_ecdsa_signature, as conversion is very fast. + * Note that secp256k1_ecdsa_signature_save must use the same representation. */ + memcpy(r, &sig->data[0], 32); + memcpy(s, &sig->data[32], 32); + } else { + secp256k1_scalar_set_b32(r, &sig->data[0], NULL); + secp256k1_scalar_set_b32(s, &sig->data[32], NULL); + } + *recid = sig->data[64]; +} + +static void secp256k1_ecdsa_recoverable_signature_save(secp256k1_ecdsa_recoverable_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s, int recid) { + if (sizeof(secp256k1_scalar) == 32) { + memcpy(&sig->data[0], r, 32); + memcpy(&sig->data[32], s, 32); + } else { + secp256k1_scalar_get_b32(&sig->data[0], r); + secp256k1_scalar_get_b32(&sig->data[32], s); + } + sig->data[64] = recid; +} + +int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature* sig, const unsigned char *input64, int recid) { + secp256k1_scalar r, s; + int ret = 1; + int overflow = 0; + + (void)ctx; + ARG_CHECK(sig != NULL); + ARG_CHECK(input64 != NULL); + ARG_CHECK(recid >= 0 && recid <= 3); + + secp256k1_scalar_set_b32(&r, &input64[0], &overflow); + ret &= !overflow; + secp256k1_scalar_set_b32(&s, &input64[32], &overflow); + ret &= !overflow; + if (ret) { + secp256k1_ecdsa_recoverable_signature_save(sig, &r, &s, recid); + } else { + memset(sig, 0, sizeof(*sig)); + } + return ret; +} + +int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, int *recid, const secp256k1_ecdsa_recoverable_signature* sig) { + secp256k1_scalar r, s; + + (void)ctx; + ARG_CHECK(output64 != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(recid != NULL); + + secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, recid, sig); + secp256k1_scalar_get_b32(&output64[0], &r); + secp256k1_scalar_get_b32(&output64[32], &s); + return 1; +} + +int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const secp256k1_ecdsa_recoverable_signature* sigin) { + secp256k1_scalar r, s; + int recid; + + (void)ctx; + ARG_CHECK(sig != NULL); + ARG_CHECK(sigin != NULL); + + secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, sigin); + secp256k1_ecdsa_signature_save(sig, &r, &s); + return 1; +} + +static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar* sigs, secp256k1_ge *pubkey, const secp256k1_scalar *message, int recid) { + unsigned char brx[32]; + secp256k1_fe fx; + secp256k1_ge x; + secp256k1_gej xj; + secp256k1_scalar rn, u1, u2; + secp256k1_gej qj; + int r; + + if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { + return 0; + } + + secp256k1_scalar_get_b32(brx, sigr); + r = secp256k1_fe_set_b32(&fx, brx); + (void)r; + VERIFY_CHECK(r); /* brx comes from a scalar, so is less than the order; certainly less than p */ + if (recid & 2) { + if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) { + return 0; + } + secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe); + } + if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) { + return 0; + } + secp256k1_gej_set_ge(&xj, &x); + secp256k1_scalar_inverse_var(&rn, sigr); + secp256k1_scalar_mul(&u1, &rn, message); + secp256k1_scalar_negate(&u1, &u1); + secp256k1_scalar_mul(&u2, &rn, sigs); + secp256k1_ecmult(ctx, &qj, &xj, &u2, &u1); + secp256k1_ge_set_gej_var(pubkey, &qj); + return !secp256k1_gej_is_infinity(&qj); +} + +int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { + secp256k1_scalar r, s; + secp256k1_scalar sec, non, msg; + int recid; + int ret = 0; + int overflow = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(signature != NULL); + ARG_CHECK(seckey != NULL); + if (noncefp == NULL) { + noncefp = secp256k1_nonce_function_default; + } + + secp256k1_scalar_set_b32(&sec, seckey, &overflow); + /* Fail if the secret key is invalid. */ + if (!overflow && !secp256k1_scalar_is_zero(&sec)) { + unsigned int count = 0; + secp256k1_scalar_set_b32(&msg, msg32, NULL); + while (1) { + unsigned char nonce32[32]; + ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); + if (!ret) { + break; + } + secp256k1_scalar_set_b32(&non, nonce32, &overflow); + memset(nonce32, 0, 32); + if (!secp256k1_scalar_is_zero(&non) && !overflow) { + if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, &recid)) { + break; + } + } + count++; + } + secp256k1_scalar_clear(&msg); + secp256k1_scalar_clear(&non); + secp256k1_scalar_clear(&sec); + } + if (ret) { + secp256k1_ecdsa_recoverable_signature_save(signature, &r, &s, recid); + } else { + memset(signature, 0, sizeof(*signature)); + } + return ret; +} + +int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32) { + secp256k1_ge q; + secp256k1_scalar r, s; + secp256k1_scalar m; + int recid; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(signature != NULL); + ARG_CHECK(pubkey != NULL); + + secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature); + ARG_CHECK(recid >= 0 && recid < 4); + secp256k1_scalar_set_b32(&m, msg32, NULL); + if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &r, &s, &q, &m, recid)) { + secp256k1_pubkey_save(pubkey, &q); + return 1; + } else { + memset(pubkey, 0, sizeof(*pubkey)); + return 0; + } +} + +#endif diff --git a/src/secp256k1/src/modules/recovery/tests_impl.h b/src/secp256k1/src/modules/recovery/tests_impl.h new file mode 100644 index 0000000000..8932d5f0af --- /dev/null +++ b/src/secp256k1/src/modules/recovery/tests_impl.h @@ -0,0 +1,250 @@ +/********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef _SECP256K1_MODULE_RECOVERY_TESTS_ +#define _SECP256K1_MODULE_RECOVERY_TESTS_ + +void test_ecdsa_recovery_end_to_end(void) { + unsigned char extra[32] = {0x00}; + unsigned char privkey[32]; + unsigned char message[32]; + secp256k1_ecdsa_signature signature[5]; + secp256k1_ecdsa_recoverable_signature rsignature[5]; + unsigned char sig[74]; + secp256k1_pubkey pubkey; + secp256k1_pubkey recpubkey; + int recid = 0; + + /* Generate a random key and message. */ + { + secp256k1_scalar 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(ctx, privkey) == 1); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); + + /* Serialize/parse compact and verify/recover. */ + extra[0] = 0; + CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[0], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, &signature[0], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[4], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[1], message, privkey, NULL, extra) == 1); + extra[31] = 1; + CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[2], message, privkey, NULL, extra) == 1); + extra[31] = 0; + extra[0] = 1; + CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[3], message, privkey, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); + CHECK(memcmp(&signature[4], &signature[0], 64) == 0); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1); + memset(&rsignature[4], 0, sizeof(rsignature[4])); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1); + /* Parse compact (with recovery id) and recover. */ + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); + CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 1); + CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0); + /* Serialize/destroy/parse signature and verify again. */ + CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1); + sig[secp256k1_rand_bits(6)] += 1 + secp256k1_rand_int(255); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 0); + /* Recover again */ + CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 0 || + memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0); +} + +/* Tests several edge cases. */ +void test_ecdsa_recovery_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 + }; + secp256k1_pubkey pubkey; + /* 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, + }; + secp256k1_pubkey pubkeyb; + secp256k1_ecdsa_recoverable_signature rsig; + secp256k1_ecdsa_signature sig; + int recid; + + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 0)); + CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 1)); + CHECK(secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 2)); + CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 3)); + CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); + + for (recid = 0; recid < 4; recid++) { + int i; + int recid2; + /* (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_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid) == 1); + CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 1); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1); + for (recid2 = 0; recid2 < 4; recid2++) { + secp256k1_pubkey pubkey2b; + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid2) == 1); + CHECK(secp256k1_ecdsa_recover(ctx, &pubkey2b, &rsig, msg32) == 1); + /* Verifying with (order + r,4) should always fail. */ + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderlong, sizeof(sigbderlong)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + } + /* DER parsing tests. */ + /* Zero length r/s. */ + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zr, sizeof(sigcder_zr)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zs, sizeof(sigcder_zs)) == 0); + /* Leading zeros. */ + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt1, sizeof(sigbderalt1)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt2, sizeof(sigbderalt2)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 0); + sigbderalt3[4] = 1; + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + sigbderalt4[7] = 1; + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + /* Damage signature. */ + sigbder[7]++; + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + sigbder[7]--; + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, 6) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder) - 1) == 0); + for(i = 0; i < 8; i++) { + int c; + unsigned char orig = sigbder[i]; + /*Try every single-byte change.*/ + for (c = 0; c < 256; c++) { + if (c == orig ) { + continue; + } + sigbder[i] = c; + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 0 || secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + } + sigbder[i] = orig; + } + } + + /* 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, + }; + secp256k1_pubkey pubkeyc; + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); + CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyc, &rsig, msg32) == 1); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 1); + sigcder[4] = 0; + sigc64[31] = 0; + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); + CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0); + sigcder[4] = 1; + sigcder[7] = 0; + sigc64[31] = 1; + sigc64[63] = 0; + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); + CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0); + } +} + +void run_recovery_tests(void) { + int i; + for (i = 0; i < 64*count; i++) { + test_ecdsa_recovery_end_to_end(); + } + test_ecdsa_recovery_edge_cases(); +} + +#endif diff --git a/src/secp256k1/src/modules/schnorr/Makefile.am.include b/src/secp256k1/src/modules/schnorr/Makefile.am.include new file mode 100644 index 0000000000..b3bfa7d5cc --- /dev/null +++ b/src/secp256k1/src/modules/schnorr/Makefile.am.include @@ -0,0 +1,10 @@ +include_HEADERS += include/secp256k1_schnorr.h +noinst_HEADERS += src/modules/schnorr/main_impl.h +noinst_HEADERS += src/modules/schnorr/schnorr.h +noinst_HEADERS += src/modules/schnorr/schnorr_impl.h +noinst_HEADERS += src/modules/schnorr/tests_impl.h +if USE_BENCHMARK +noinst_PROGRAMS += bench_schnorr_verify +bench_schnorr_verify_SOURCES = src/bench_schnorr_verify.c +bench_schnorr_verify_LDADD = libsecp256k1.la $(SECP_LIBS) +endif diff --git a/src/secp256k1/src/modules/schnorr/main_impl.h b/src/secp256k1/src/modules/schnorr/main_impl.h new file mode 100644 index 0000000000..fa176a1767 --- /dev/null +++ b/src/secp256k1/src/modules/schnorr/main_impl.h @@ -0,0 +1,164 @@ +/********************************************************************** + * Copyright (c) 2014-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODULE_SCHNORR_MAIN +#define SECP256K1_MODULE_SCHNORR_MAIN + +#include "include/secp256k1_schnorr.h" +#include "modules/schnorr/schnorr_impl.h" + +static void secp256k1_schnorr_msghash_sha256(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32) { + secp256k1_sha256_t sha; + secp256k1_sha256_initialize(&sha); + secp256k1_sha256_write(&sha, r32, 32); + secp256k1_sha256_write(&sha, msg32, 32); + secp256k1_sha256_finalize(&sha, h32); +} + +static const unsigned char secp256k1_schnorr_algo16[17] = "Schnorr+SHA256 "; + +int secp256k1_schnorr_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { + secp256k1_scalar sec, non; + int ret = 0; + int overflow = 0; + unsigned int count = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(sig64 != NULL); + ARG_CHECK(seckey != NULL); + if (noncefp == NULL) { + noncefp = secp256k1_nonce_function_default; + } + + secp256k1_scalar_set_b32(&sec, seckey, NULL); + while (1) { + unsigned char nonce32[32]; + ret = noncefp(nonce32, msg32, seckey, secp256k1_schnorr_algo16, (void*)noncedata, count); + if (!ret) { + break; + } + secp256k1_scalar_set_b32(&non, nonce32, &overflow); + memset(nonce32, 0, 32); + if (!secp256k1_scalar_is_zero(&non) && !overflow) { + if (secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64, &sec, &non, NULL, secp256k1_schnorr_msghash_sha256, msg32)) { + break; + } + } + count++; + } + if (!ret) { + memset(sig64, 0, 64); + } + secp256k1_scalar_clear(&non); + secp256k1_scalar_clear(&sec); + return ret; +} + +int secp256k1_schnorr_verify(const secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg32, const secp256k1_pubkey *pubkey) { + secp256k1_ge q; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(sig64 != NULL); + ARG_CHECK(pubkey != NULL); + + secp256k1_pubkey_load(ctx, &q, pubkey); + return secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64, &q, secp256k1_schnorr_msghash_sha256, msg32); +} + +int secp256k1_schnorr_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *sig64, const unsigned char *msg32) { + secp256k1_ge q; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(sig64 != NULL); + ARG_CHECK(pubkey != NULL); + + if (secp256k1_schnorr_sig_recover(&ctx->ecmult_ctx, sig64, &q, secp256k1_schnorr_msghash_sha256, msg32)) { + secp256k1_pubkey_save(pubkey, &q); + return 1; + } else { + memset(pubkey, 0, sizeof(*pubkey)); + return 0; + } +} + +int secp256k1_schnorr_generate_nonce_pair(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, unsigned char *privnonce32, const unsigned char *sec32, const unsigned char *msg32, secp256k1_nonce_function noncefp, const void* noncedata) { + int count = 0; + int ret = 1; + secp256k1_gej Qj; + secp256k1_ge Q; + secp256k1_scalar sec; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(sec32 != NULL); + ARG_CHECK(pubnonce != NULL); + ARG_CHECK(privnonce32 != NULL); + + if (noncefp == NULL) { + noncefp = secp256k1_nonce_function_default; + } + + do { + int overflow; + ret = noncefp(privnonce32, sec32, msg32, secp256k1_schnorr_algo16, (void*)noncedata, count++); + if (!ret) { + break; + } + secp256k1_scalar_set_b32(&sec, privnonce32, &overflow); + if (overflow || secp256k1_scalar_is_zero(&sec)) { + continue; + } + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &sec); + secp256k1_ge_set_gej(&Q, &Qj); + + secp256k1_pubkey_save(pubnonce, &Q); + break; + } while(1); + + secp256k1_scalar_clear(&sec); + if (!ret) { + memset(pubnonce, 0, sizeof(*pubnonce)); + } + return ret; +} + +int secp256k1_schnorr_partial_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const unsigned char *sec32, const secp256k1_pubkey *pubnonce_others, const unsigned char *secnonce32) { + int overflow = 0; + secp256k1_scalar sec, non; + secp256k1_ge pubnon; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(sig64 != NULL); + ARG_CHECK(sec32 != NULL); + ARG_CHECK(secnonce32 != NULL); + ARG_CHECK(pubnonce_others != NULL); + + secp256k1_scalar_set_b32(&sec, sec32, &overflow); + if (overflow || secp256k1_scalar_is_zero(&sec)) { + return -1; + } + secp256k1_scalar_set_b32(&non, secnonce32, &overflow); + if (overflow || secp256k1_scalar_is_zero(&non)) { + return -1; + } + secp256k1_pubkey_load(ctx, &pubnon, pubnonce_others); + return secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64, &sec, &non, &pubnon, secp256k1_schnorr_msghash_sha256, msg32); +} + +int secp256k1_schnorr_partial_combine(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char * const *sig64sin, size_t n) { + ARG_CHECK(sig64 != NULL); + ARG_CHECK(n >= 1); + ARG_CHECK(sig64sin != NULL); + return secp256k1_schnorr_sig_combine(sig64, n, sig64sin); +} + +#endif diff --git a/src/secp256k1/src/modules/schnorr/schnorr.h b/src/secp256k1/src/modules/schnorr/schnorr.h new file mode 100644 index 0000000000..de18147bd5 --- /dev/null +++ b/src/secp256k1/src/modules/schnorr/schnorr.h @@ -0,0 +1,20 @@ +/*********************************************************************** + * Copyright (c) 2014-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php. * + ***********************************************************************/ + +#ifndef _SECP256K1_MODULE_SCHNORR_H_ +#define _SECP256K1_MODULE_SCHNORR_H_ + +#include "scalar.h" +#include "group.h" + +typedef void (*secp256k1_schnorr_msghash)(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32); + +static int secp256k1_schnorr_sig_sign(const secp256k1_ecmult_gen_context* ctx, unsigned char *sig64, const secp256k1_scalar *key, const secp256k1_scalar *nonce, const secp256k1_ge *pubnonce, secp256k1_schnorr_msghash hash, const unsigned char *msg32); +static int secp256k1_schnorr_sig_verify(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, const secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32); +static int secp256k1_schnorr_sig_recover(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32); +static int secp256k1_schnorr_sig_combine(unsigned char *sig64, size_t n, const unsigned char * const *sig64ins); + +#endif diff --git a/src/secp256k1/src/modules/schnorr/schnorr_impl.h b/src/secp256k1/src/modules/schnorr/schnorr_impl.h new file mode 100644 index 0000000000..e13ab6db7c --- /dev/null +++ b/src/secp256k1/src/modules/schnorr/schnorr_impl.h @@ -0,0 +1,207 @@ +/*********************************************************************** + * Copyright (c) 2014-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php. * + ***********************************************************************/ + +#ifndef _SECP256K1_SCHNORR_IMPL_H_ +#define _SECP256K1_SCHNORR_IMPL_H_ + +#include <string.h> + +#include "schnorr.h" +#include "num.h" +#include "field.h" +#include "group.h" +#include "ecmult.h" +#include "ecmult_gen.h" + +/** + * Custom Schnorr-based signature scheme. They support multiparty signing, public key + * recovery and batch validation. + * + * Rationale for verifying R's y coordinate: + * In order to support batch validation and public key recovery, the full R point must + * be known to verifiers, rather than just its x coordinate. In order to not risk + * being more strict in batch validation than normal validation, validators must be + * required to reject signatures with incorrect y coordinate. This is only possible + * by including a (relatively slow) field inverse, or a field square root. However, + * batch validation offers potentially much higher benefits than this cost. + * + * Rationale for having an implicit y coordinate oddness: + * If we commit to having the full R point known to verifiers, there are two mechanism. + * Either include its oddness in the signature, or give it an implicit fixed value. + * As the R y coordinate can be flipped by a simple negation of the nonce, we choose the + * latter, as it comes with nearly zero impact on signing or validation performance, and + * saves a byte in the signature. + * + * Signing: + * Inputs: 32-byte message m, 32-byte scalar key x (!=0), 32-byte scalar nonce k (!=0) + * + * Compute point R = k * G. Reject nonce if R's y coordinate is odd (or negate nonce). + * Compute 32-byte r, the serialization of R's x coordinate. + * Compute scalar h = Hash(r || m). Reject nonce if h == 0 or h >= order. + * Compute scalar s = k - h * x. + * The signature is (r, s). + * + * + * Verification: + * Inputs: 32-byte message m, public key point Q, signature: (32-byte r, scalar s) + * + * Signature is invalid if s >= order. + * Signature is invalid if r >= p. + * Compute scalar h = Hash(r || m). Signature is invalid if h == 0 or h >= order. + * Option 1 (faster for single verification): + * Compute point R = h * Q + s * G. Signature is invalid if R is infinity or R's y coordinate is odd. + * Signature is valid if the serialization of R's x coordinate equals r. + * Option 2 (allows batch validation and pubkey recovery): + * Decompress x coordinate r into point R, with odd y coordinate. Fail if R is not on the curve. + * Signature is valid if R + h * Q + s * G == 0. + */ + +static int secp256k1_schnorr_sig_sign(const secp256k1_ecmult_gen_context* ctx, unsigned char *sig64, const secp256k1_scalar *key, const secp256k1_scalar *nonce, const secp256k1_ge *pubnonce, secp256k1_schnorr_msghash hash, const unsigned char *msg32) { + secp256k1_gej Rj; + secp256k1_ge Ra; + unsigned char h32[32]; + secp256k1_scalar h, s; + int overflow; + secp256k1_scalar n; + + if (secp256k1_scalar_is_zero(key) || secp256k1_scalar_is_zero(nonce)) { + return 0; + } + n = *nonce; + + secp256k1_ecmult_gen(ctx, &Rj, &n); + if (pubnonce != NULL) { + secp256k1_gej_add_ge(&Rj, &Rj, pubnonce); + } + secp256k1_ge_set_gej(&Ra, &Rj); + secp256k1_fe_normalize(&Ra.y); + if (secp256k1_fe_is_odd(&Ra.y)) { + /* R's y coordinate is odd, which is not allowed (see rationale above). + Force it to be even by negating the nonce. Note that this even works + for multiparty signing, as the R point is known to all participants, + which can all decide to flip the sign in unison, resulting in the + overall R point to be negated too. */ + secp256k1_scalar_negate(&n, &n); + } + secp256k1_fe_normalize(&Ra.x); + secp256k1_fe_get_b32(sig64, &Ra.x); + hash(h32, sig64, msg32); + overflow = 0; + secp256k1_scalar_set_b32(&h, h32, &overflow); + if (overflow || secp256k1_scalar_is_zero(&h)) { + secp256k1_scalar_clear(&n); + return 0; + } + secp256k1_scalar_mul(&s, &h, key); + secp256k1_scalar_negate(&s, &s); + secp256k1_scalar_add(&s, &s, &n); + secp256k1_scalar_clear(&n); + secp256k1_scalar_get_b32(sig64 + 32, &s); + return 1; +} + +static int secp256k1_schnorr_sig_verify(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, const secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32) { + secp256k1_gej Qj, Rj; + secp256k1_ge Ra; + secp256k1_fe Rx; + secp256k1_scalar h, s; + unsigned char hh[32]; + int overflow; + + if (secp256k1_ge_is_infinity(pubkey)) { + return 0; + } + hash(hh, sig64, msg32); + overflow = 0; + secp256k1_scalar_set_b32(&h, hh, &overflow); + if (overflow || secp256k1_scalar_is_zero(&h)) { + return 0; + } + overflow = 0; + secp256k1_scalar_set_b32(&s, sig64 + 32, &overflow); + if (overflow) { + return 0; + } + if (!secp256k1_fe_set_b32(&Rx, sig64)) { + return 0; + } + secp256k1_gej_set_ge(&Qj, pubkey); + secp256k1_ecmult(ctx, &Rj, &Qj, &h, &s); + if (secp256k1_gej_is_infinity(&Rj)) { + return 0; + } + secp256k1_ge_set_gej_var(&Ra, &Rj); + secp256k1_fe_normalize_var(&Ra.y); + if (secp256k1_fe_is_odd(&Ra.y)) { + return 0; + } + return secp256k1_fe_equal_var(&Rx, &Ra.x); +} + +static int secp256k1_schnorr_sig_recover(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32) { + secp256k1_gej Qj, Rj; + secp256k1_ge Ra; + secp256k1_fe Rx; + secp256k1_scalar h, s; + unsigned char hh[32]; + int overflow; + + hash(hh, sig64, msg32); + overflow = 0; + secp256k1_scalar_set_b32(&h, hh, &overflow); + if (overflow || secp256k1_scalar_is_zero(&h)) { + return 0; + } + overflow = 0; + secp256k1_scalar_set_b32(&s, sig64 + 32, &overflow); + if (overflow) { + return 0; + } + if (!secp256k1_fe_set_b32(&Rx, sig64)) { + return 0; + } + if (!secp256k1_ge_set_xo_var(&Ra, &Rx, 0)) { + return 0; + } + secp256k1_gej_set_ge(&Rj, &Ra); + secp256k1_scalar_inverse_var(&h, &h); + secp256k1_scalar_negate(&s, &s); + secp256k1_scalar_mul(&s, &s, &h); + secp256k1_ecmult(ctx, &Qj, &Rj, &h, &s); + if (secp256k1_gej_is_infinity(&Qj)) { + return 0; + } + secp256k1_ge_set_gej(pubkey, &Qj); + return 1; +} + +static int secp256k1_schnorr_sig_combine(unsigned char *sig64, size_t n, const unsigned char * const *sig64ins) { + secp256k1_scalar s = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + size_t i; + for (i = 0; i < n; i++) { + secp256k1_scalar si; + int overflow; + secp256k1_scalar_set_b32(&si, sig64ins[i] + 32, &overflow); + if (overflow) { + return -1; + } + if (i) { + if (memcmp(sig64ins[i - 1], sig64ins[i], 32) != 0) { + return -1; + } + } + secp256k1_scalar_add(&s, &s, &si); + } + if (secp256k1_scalar_is_zero(&s)) { + return 0; + } + memcpy(sig64, sig64ins[0], 32); + secp256k1_scalar_get_b32(sig64 + 32, &s); + secp256k1_scalar_clear(&s); + return 1; +} + +#endif diff --git a/src/secp256k1/src/modules/schnorr/tests_impl.h b/src/secp256k1/src/modules/schnorr/tests_impl.h new file mode 100644 index 0000000000..5bd14a03e3 --- /dev/null +++ b/src/secp256k1/src/modules/schnorr/tests_impl.h @@ -0,0 +1,175 @@ +/********************************************************************** + * Copyright (c) 2014-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODULE_SCHNORR_TESTS +#define SECP256K1_MODULE_SCHNORR_TESTS + +#include "include/secp256k1_schnorr.h" + +void test_schnorr_end_to_end(void) { + unsigned char privkey[32]; + unsigned char message[32]; + unsigned char schnorr_signature[64]; + secp256k1_pubkey pubkey, recpubkey; + + /* Generate a random key and message. */ + { + secp256k1_scalar key; + random_scalar_order_test(&key); + secp256k1_scalar_get_b32(privkey, &key); + secp256k1_rand256_test(message); + } + + /* Construct and verify corresponding public key. */ + CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); + + /* Schnorr sign. */ + CHECK(secp256k1_schnorr_sign(ctx, schnorr_signature, message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 1); + CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) == 1); + CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0); + /* Destroy signature and verify again. */ + schnorr_signature[secp256k1_rand_bits(6)] += 1 + secp256k1_rand_int(255); + CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 0); + CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) != 1 || + memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0); +} + +/** Horribly broken hash function. Do not use for anything but tests. */ +void test_schnorr_hash(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32) { + int i; + for (i = 0; i < 32; i++) { + h32[i] = r32[i] ^ msg32[i]; + } +} + +void test_schnorr_sign_verify(void) { + unsigned char msg32[32]; + unsigned char sig64[3][64]; + secp256k1_gej pubkeyj[3]; + secp256k1_ge pubkey[3]; + secp256k1_scalar nonce[3], key[3]; + int i = 0; + int k; + + secp256k1_rand256_test(msg32); + + for (k = 0; k < 3; k++) { + random_scalar_order_test(&key[k]); + + do { + random_scalar_order_test(&nonce[k]); + if (secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64[k], &key[k], &nonce[k], NULL, &test_schnorr_hash, msg32)) { + break; + } + } while(1); + + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubkeyj[k], &key[k]); + secp256k1_ge_set_gej_var(&pubkey[k], &pubkeyj[k]); + CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64[k], &pubkey[k], &test_schnorr_hash, msg32)); + + for (i = 0; i < 4; i++) { + int pos = secp256k1_rand_bits(6); + int mod = 1 + secp256k1_rand_int(255); + sig64[k][pos] ^= mod; + CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64[k], &pubkey[k], &test_schnorr_hash, msg32) == 0); + sig64[k][pos] ^= mod; + } + } +} + +void test_schnorr_threshold(void) { + unsigned char msg[32]; + unsigned char sec[5][32]; + secp256k1_pubkey pub[5]; + unsigned char nonce[5][32]; + secp256k1_pubkey pubnonce[5]; + unsigned char sig[5][64]; + const unsigned char* sigs[5]; + unsigned char allsig[64]; + const secp256k1_pubkey* pubs[5]; + secp256k1_pubkey allpub; + int n, i; + int damage; + int ret = 0; + + damage = secp256k1_rand_bits(1) ? (1 + secp256k1_rand_int(4)) : 0; + secp256k1_rand256_test(msg); + n = 2 + secp256k1_rand_int(4); + for (i = 0; i < n; i++) { + do { + secp256k1_rand256_test(sec[i]); + } while (!secp256k1_ec_seckey_verify(ctx, sec[i])); + CHECK(secp256k1_ec_pubkey_create(ctx, &pub[i], sec[i])); + CHECK(secp256k1_schnorr_generate_nonce_pair(ctx, &pubnonce[i], nonce[i], msg, sec[i], NULL, NULL)); + pubs[i] = &pub[i]; + } + if (damage == 1) { + nonce[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); + } else if (damage == 2) { + sec[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); + } + for (i = 0; i < n; i++) { + secp256k1_pubkey allpubnonce; + const secp256k1_pubkey *pubnonces[4]; + int j; + for (j = 0; j < i; j++) { + pubnonces[j] = &pubnonce[j]; + } + for (j = i + 1; j < n; j++) { + pubnonces[j - 1] = &pubnonce[j]; + } + CHECK(secp256k1_ec_pubkey_combine(ctx, &allpubnonce, pubnonces, n - 1)); + ret |= (secp256k1_schnorr_partial_sign(ctx, sig[i], msg, sec[i], &allpubnonce, nonce[i]) != 1) * 1; + sigs[i] = sig[i]; + } + if (damage == 3) { + sig[secp256k1_rand_int(n)][secp256k1_rand_bits(6)] ^= 1 + secp256k1_rand_int(255); + } + ret |= (secp256k1_ec_pubkey_combine(ctx, &allpub, pubs, n) != 1) * 2; + if ((ret & 1) == 0) { + ret |= (secp256k1_schnorr_partial_combine(ctx, allsig, sigs, n) != 1) * 4; + } + if (damage == 4) { + allsig[secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); + } + if ((ret & 7) == 0) { + ret |= (secp256k1_schnorr_verify(ctx, allsig, msg, &allpub) != 1) * 8; + } + CHECK((ret == 0) == (damage == 0)); +} + +void test_schnorr_recovery(void) { + unsigned char msg32[32]; + unsigned char sig64[64]; + secp256k1_ge Q; + + secp256k1_rand256_test(msg32); + secp256k1_rand256_test(sig64); + secp256k1_rand256_test(sig64 + 32); + if (secp256k1_schnorr_sig_recover(&ctx->ecmult_ctx, sig64, &Q, &test_schnorr_hash, msg32) == 1) { + CHECK(secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64, &Q, &test_schnorr_hash, msg32) == 1); + } +} + +void run_schnorr_tests(void) { + int i; + for (i = 0; i < 32*count; i++) { + test_schnorr_end_to_end(); + } + for (i = 0; i < 32 * count; i++) { + test_schnorr_sign_verify(); + } + for (i = 0; i < 16 * count; i++) { + test_schnorr_recovery(); + } + for (i = 0; i < 10 * count; i++) { + test_schnorr_threshold(); + } +} + +#endif diff --git a/src/secp256k1/src/num.h b/src/secp256k1/src/num.h index 339b6bb6ec..ebfa71eb44 100644 --- a/src/secp256k1/src/num.h +++ b/src/secp256k1/src/num.h @@ -20,48 +20,48 @@ #endif /** Copy a number. */ -static void secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a); +static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *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); +static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *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); +static void secp256k1_num_set_bin(secp256k1_num *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); +static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m); /** Compare the absolute value of two numbers. */ -static int secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b); +static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b); /** Test whether two number are equal (including sign). */ -static int secp256k1_num_eq(const secp256k1_num_t *a, const secp256k1_num_t *b); +static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b); /** Add two (signed) numbers. */ -static void secp256k1_num_add(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); +static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); /** Subtract two (signed) numbers. */ -static void secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); +static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); /** Multiply two (signed) numbers. */ -static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); +static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *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); +static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m); /** Right-shift the passed number by bits bits. */ -static void secp256k1_num_shift(secp256k1_num_t *r, int bits); +static void secp256k1_num_shift(secp256k1_num *r, int bits); /** Check whether a number is zero. */ -static int secp256k1_num_is_zero(const secp256k1_num_t *a); +static int secp256k1_num_is_zero(const secp256k1_num *a); /** Check whether a number is strictly negative. */ -static int secp256k1_num_is_neg(const secp256k1_num_t *a); +static int secp256k1_num_is_neg(const secp256k1_num *a); /** Change a number's sign. */ -static void secp256k1_num_negate(secp256k1_num_t *r); +static void secp256k1_num_negate(secp256k1_num *r); #endif diff --git a/src/secp256k1/src/num_gmp.h b/src/secp256k1/src/num_gmp.h index baa1f2bf2e..7dd813088a 100644 --- a/src/secp256k1/src/num_gmp.h +++ b/src/secp256k1/src/num_gmp.h @@ -15,6 +15,6 @@ typedef struct { mp_limb_t data[2*NUM_LIMBS]; int neg; int limbs; -} secp256k1_num_t; +} secp256k1_num; #endif diff --git a/src/secp256k1/src/num_gmp_impl.h b/src/secp256k1/src/num_gmp_impl.h index dbbc458d5d..7b6a89719a 100644 --- a/src/secp256k1/src/num_gmp_impl.h +++ b/src/secp256k1/src/num_gmp_impl.h @@ -15,18 +15,18 @@ #include "num.h" #ifdef VERIFY -static void secp256k1_num_sanity(const secp256k1_num_t *a) { +static void secp256k1_num_sanity(const secp256k1_num *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) { +static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a) { *r = *a; } -static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a) { +static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a) { unsigned char tmp[65]; int len = 0; int shift = 0; @@ -42,7 +42,7 @@ static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const sec memset(tmp, 0, sizeof(tmp)); } -static void secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen) { +static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen) { int len; VERIFY_CHECK(alen > 0); VERIFY_CHECK(alen <= 64); @@ -59,7 +59,7 @@ static void secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, un } } -static void secp256k1_num_add_abs(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { +static void secp256k1_num_add_abs(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { mp_limb_t c = mpn_add(r->data, a->data, a->limbs, b->data, b->limbs); r->limbs = a->limbs; if (c != 0) { @@ -68,8 +68,9 @@ static void secp256k1_num_add_abs(secp256k1_num_t *r, const secp256k1_num_t *a, } } -static void secp256k1_num_sub_abs(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { +static void secp256k1_num_sub_abs(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { mp_limb_t c = mpn_sub(r->data, a->data, a->limbs, b->data, b->limbs); + (void)c; VERIFY_CHECK(c == 0); r->limbs = a->limbs; while (r->limbs > 1 && r->data[r->limbs-1]==0) { @@ -77,7 +78,7 @@ static void secp256k1_num_sub_abs(secp256k1_num_t *r, const secp256k1_num_t *a, } } -static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m) { +static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m) { secp256k1_num_sanity(r); secp256k1_num_sanity(m); @@ -97,7 +98,7 @@ static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m) { } } -static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m) { +static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m) { int i; mp_limb_t g[NUM_LIMBS+1]; mp_limb_t u[NUM_LIMBS+1]; @@ -125,6 +126,7 @@ static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t } sn = NUM_LIMBS+1; gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs); + (void)gn; VERIFY_CHECK(gn == 1); VERIFY_CHECK(g[0] == 1); r->neg = a->neg ^ m->neg; @@ -142,15 +144,15 @@ static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t memset(v, 0, sizeof(v)); } -static int secp256k1_num_is_zero(const secp256k1_num_t *a) { +static int secp256k1_num_is_zero(const secp256k1_num *a) { return (a->limbs == 1 && a->data[0] == 0); } -static int secp256k1_num_is_neg(const secp256k1_num_t *a) { +static int secp256k1_num_is_neg(const secp256k1_num *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) { +static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b) { if (a->limbs > b->limbs) { return 1; } @@ -160,7 +162,7 @@ static int secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b) return mpn_cmp(a->data, b->data, a->limbs); } -static int secp256k1_num_eq(const secp256k1_num_t *a, const secp256k1_num_t *b) { +static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b) { if (a->limbs > b->limbs) { return 0; } @@ -173,7 +175,7 @@ static int secp256k1_num_eq(const secp256k1_num_t *a, const secp256k1_num_t *b) 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) { +static void secp256k1_num_subadd(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *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) { @@ -192,19 +194,19 @@ static void secp256k1_num_subadd(secp256k1_num_t *r, const secp256k1_num_t *a, c } } -static void secp256k1_num_add(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { +static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *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) { +static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *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) { +static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { mp_limb_t tmp[2*NUM_LIMBS+1]; secp256k1_num_sanity(a); secp256k1_num_sanity(b); @@ -231,13 +233,13 @@ static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, cons memset(tmp, 0, sizeof(tmp)); } -static void secp256k1_num_shift(secp256k1_num_t *r, int bits) { - int i; +static void secp256k1_num_shift(secp256k1_num *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) { + int i; /* Shift full limbs. */ for (i = 0; i < r->limbs; i++) { int index = i + (bits / GMP_NUMB_BITS); @@ -253,7 +255,7 @@ static void secp256k1_num_shift(secp256k1_num_t *r, int bits) { } } -static void secp256k1_num_negate(secp256k1_num_t *r) { +static void secp256k1_num_negate(secp256k1_num *r) { r->neg ^= 1; } diff --git a/src/secp256k1/src/scalar.h b/src/secp256k1/src/scalar.h index f5d09f8d47..b590ccd6dd 100644 --- a/src/secp256k1/src/scalar.h +++ b/src/secp256k1/src/scalar.h @@ -22,72 +22,83 @@ #endif /** Clear a scalar to prevent the leak of sensitive data. */ -static void secp256k1_scalar_clear(secp256k1_scalar_t *r); +static void secp256k1_scalar_clear(secp256k1_scalar *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); +static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *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); +static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *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); +static void secp256k1_scalar_set_b32(secp256k1_scalar *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); +static void secp256k1_scalar_set_int(secp256k1_scalar *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); +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* 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); +static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *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); +/** Conditionally add a power of two to a scalar. The result is not allowed to overflow. */ +static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag); /** 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); +static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); + +/** Shift a scalar right by some amount strictly between 0 and 16, returning + * the low bits that were shifted off */ +static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n); /** Compute the square of a scalar (modulo the group order). */ -static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a); +static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *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); +static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *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); +static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *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); +static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a); /** Check whether a scalar equals zero. */ -static int secp256k1_scalar_is_zero(const secp256k1_scalar_t *a); +static int secp256k1_scalar_is_zero(const secp256k1_scalar *a); /** Check whether a scalar equals one. */ -static int secp256k1_scalar_is_one(const secp256k1_scalar_t *a); +static int secp256k1_scalar_is_one(const secp256k1_scalar *a); + +/** Check whether a scalar, considered as an nonnegative integer, is even. */ +static int secp256k1_scalar_is_even(const secp256k1_scalar *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); +static int secp256k1_scalar_is_high(const secp256k1_scalar *a); + +/** Conditionally negate a number, in constant time. + * Returns -1 if the number was negated, 1 otherwise */ +static int secp256k1_scalar_cond_negate(secp256k1_scalar *a, int flag); #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); +static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a); /** Get the order of the group as a number. */ -static void secp256k1_scalar_order_get_num(secp256k1_num_t *r); +static void secp256k1_scalar_order_get_num(secp256k1_num *r); #endif /** Compare two scalars. */ -static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b); +static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b); #ifdef USE_ENDOMORPHISM /** Find r1 and r2 such that r1+r2*2^128 = a. */ -static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a); +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); /** 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); +static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *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); +static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift); #endif diff --git a/src/secp256k1/src/scalar_4x64.h b/src/secp256k1/src/scalar_4x64.h index 82899aa7b0..cff406038f 100644 --- a/src/secp256k1/src/scalar_4x64.h +++ b/src/secp256k1/src/scalar_4x64.h @@ -12,7 +12,7 @@ /** A scalar modulo the group order of the secp256k1 curve. */ typedef struct { uint64_t d[4]; -} secp256k1_scalar_t; +} secp256k1_scalar; #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{((uint64_t)(d1)) << 32 | (d0), ((uint64_t)(d3)) << 32 | (d2), ((uint64_t)(d5)) << 32 | (d4), ((uint64_t)(d7)) << 32 | (d6)}} diff --git a/src/secp256k1/src/scalar_4x64_impl.h b/src/secp256k1/src/scalar_4x64_impl.h index ff365292f8..aa2703dd23 100644 --- a/src/secp256k1/src/scalar_4x64_impl.h +++ b/src/secp256k1/src/scalar_4x64_impl.h @@ -24,26 +24,26 @@ #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) { +SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *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) { +SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *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) { +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *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) { +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { VERIFY_CHECK(count < 32); VERIFY_CHECK(offset + count <= 256); if ((offset + count - 1) >> 6 == offset >> 6) { @@ -54,7 +54,7 @@ SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256 } } -SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar_t *a) { +SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { int yes = 0; int no = 0; no |= (a->d[3] < SECP256K1_N_3); /* No need for a > check. */ @@ -66,7 +66,7 @@ SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scal return yes; } -SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, unsigned int overflow) { +SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, unsigned int overflow) { uint128_t t; VERIFY_CHECK(overflow <= 1); t = (uint128_t)r->d[0] + overflow * SECP256K1_N_C_0; @@ -80,7 +80,7 @@ SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, unsig return overflow; } -static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { int overflow; uint128_t t = (uint128_t)a->d[0] + b->d[0]; r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; @@ -96,9 +96,10 @@ static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t return overflow; } -static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { +static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { uint128_t t; VERIFY_CHECK(bit < 256); + bit += ((uint32_t) flag - 1) & 0x100; /* forcing (bit >> 6) > 3 makes this a noop */ 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)); @@ -113,7 +114,7 @@ static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { #endif } -static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *b32, int *overflow) { +static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { int over; 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; @@ -125,18 +126,18 @@ static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char } } -static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_t* a) { +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* 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) { +SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *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) { +static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *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; @@ -148,11 +149,11 @@ static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scala r->d[3] = t & nonzero; } -SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar_t *a) { +SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *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) { +static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { int yes = 0; int no = 0; no |= (a->d[3] < SECP256K1_N_H_3); @@ -164,6 +165,22 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { return yes; } +static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { + /* If we are flag = 0, mask = 00...00 and this is a no-op; + * if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */ + uint64_t mask = !flag - 1; + uint64_t nonzero = (secp256k1_scalar_is_zero(r) != 0) - 1; + uint128_t t = (uint128_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask); + r->d[0] = t & nonzero; t >>= 64; + t += (uint128_t)(r->d[1] ^ mask) + (SECP256K1_N_1 & mask); + r->d[1] = t & nonzero; t >>= 64; + t += (uint128_t)(r->d[2] ^ mask) + (SECP256K1_N_2 & mask); + r->d[2] = t & nonzero; t >>= 64; + t += (uint128_t)(r->d[3] ^ mask) + (SECP256K1_N_3 & mask); + r->d[3] = t & nonzero; + return 2 * (mask == 0) - 1; +} + /* 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. */ @@ -250,7 +267,7 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { VERIFY_CHECK(c2 == 0); \ } -static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l) { +static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) { #ifdef USE_ASM_X86_64 /* Reduce 512 bits into 385. */ uint64_t m0, m1, m2, m3, m4, m5, m6; @@ -559,7 +576,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l 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) { +static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar *a, const secp256k1_scalar *b) { #ifdef USE_ASM_X86_64 const uint64_t *pb = b->d; __asm__ __volatile__( @@ -721,12 +738,12 @@ static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar_t *a, extract(l[5]); muladd_fast(a->d[3], b->d[3]); extract_fast(l[6]); - VERIFY_CHECK(c1 <= 0); + VERIFY_CHECK(c1 == 0); l[7] = c0; #endif } -static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar_t *a) { +static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar *a) { #ifdef USE_ASM_X86_64 __asm__ __volatile__( /* Preload */ @@ -871,19 +888,32 @@ static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar_t *a) #undef extract #undef extract_fast -static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *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) { +static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { + int ret; + VERIFY_CHECK(n > 0); + VERIFY_CHECK(n < 16); + ret = r->d[0] & ((1 << n) - 1); + r->d[0] = (r->d[0] >> n) + (r->d[1] << (64 - n)); + r->d[1] = (r->d[1] >> n) + (r->d[2] << (64 - n)); + r->d[2] = (r->d[2] >> n) + (r->d[3] << (64 - n)); + r->d[3] = (r->d[3] >> n); + return ret; +} + +static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *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) { +#ifdef USE_ENDOMORPHISM +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { r1->d[0] = a->d[0]; r1->d[1] = a->d[1]; r1->d[2] = 0; @@ -893,12 +923,13 @@ static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_ r2->d[2] = 0; r2->d[3] = 0; } +#endif -SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *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) { +SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift) { uint64_t l[8]; unsigned int shiftlimbs; unsigned int shiftlow; @@ -912,9 +943,7 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t * 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); - } + secp256k1_scalar_cadd_bit(r, 0, (l[(shift - 1) >> 6] >> ((shift - 1) & 0x3f)) & 1); } #endif diff --git a/src/secp256k1/src/scalar_8x32.h b/src/secp256k1/src/scalar_8x32.h index f17017e24e..1319664f65 100644 --- a/src/secp256k1/src/scalar_8x32.h +++ b/src/secp256k1/src/scalar_8x32.h @@ -12,7 +12,7 @@ /** A scalar modulo the group order of the secp256k1 curve. */ typedef struct { uint32_t d[8]; -} secp256k1_scalar_t; +} secp256k1_scalar; #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)}} diff --git a/src/secp256k1/src/scalar_8x32_impl.h b/src/secp256k1/src/scalar_8x32_impl.h index 22b31d4112..aae4f35c08 100644 --- a/src/secp256k1/src/scalar_8x32_impl.h +++ b/src/secp256k1/src/scalar_8x32_impl.h @@ -34,7 +34,7 @@ #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) { +SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { r->d[0] = 0; r->d[1] = 0; r->d[2] = 0; @@ -45,7 +45,7 @@ SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar_t *r) { r->d[7] = 0; } -SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, unsigned int v) { +SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { r->d[0] = v; r->d[1] = 0; r->d[2] = 0; @@ -56,12 +56,12 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, uns r->d[7] = 0; } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) { +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *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) { +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { VERIFY_CHECK(count < 32); VERIFY_CHECK(offset + count <= 256); if ((offset + count - 1) >> 5 == offset >> 5) { @@ -72,7 +72,7 @@ SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256 } } -SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar_t *a) { +SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { int yes = 0; int no = 0; no |= (a->d[7] < SECP256K1_N_7); /* No need for a > check. */ @@ -90,7 +90,7 @@ SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scal return yes; } -SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, uint32_t overflow) { +SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, uint32_t overflow) { uint64_t t; VERIFY_CHECK(overflow <= 1); t = (uint64_t)r->d[0] + overflow * SECP256K1_N_C_0; @@ -112,7 +112,7 @@ SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, uint3 return overflow; } -static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { int overflow; uint64_t t = (uint64_t)a->d[0] + b->d[0]; r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; @@ -136,9 +136,10 @@ static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t return overflow; } -static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { +static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { uint64_t t; VERIFY_CHECK(bit < 256); + bit += ((uint32_t) flag - 1) & 0x100; /* forcing (bit >> 5) > 7 makes this a noop */ 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)); @@ -161,7 +162,7 @@ static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { #endif } -static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *b32, int *overflow) { +static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { int over; 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; @@ -177,7 +178,7 @@ static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char } } -static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_t* a) { +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* 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]; @@ -188,11 +189,11 @@ static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_ 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) { +SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *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) { +static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *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; @@ -212,11 +213,11 @@ static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scala r->d[7] = t & nonzero; } -SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar_t *a) { +SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *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) { +static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { int yes = 0; int no = 0; no |= (a->d[7] < SECP256K1_N_H_7); @@ -234,6 +235,31 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { return yes; } +static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { + /* If we are flag = 0, mask = 00...00 and this is a no-op; + * if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */ + uint32_t mask = !flag - 1; + uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(r) == 0); + uint64_t t = (uint64_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask); + r->d[0] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[1] ^ mask) + (SECP256K1_N_1 & mask); + r->d[1] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[2] ^ mask) + (SECP256K1_N_2 & mask); + r->d[2] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[3] ^ mask) + (SECP256K1_N_3 & mask); + r->d[3] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[4] ^ mask) + (SECP256K1_N_4 & mask); + r->d[4] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[5] ^ mask) + (SECP256K1_N_5 & mask); + r->d[5] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[6] ^ mask) + (SECP256K1_N_6 & mask); + r->d[6] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[7] ^ mask) + (SECP256K1_N_7 & mask); + r->d[7] = t & nonzero; + return 2 * (mask == 0) - 1; +} + + /* 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. */ @@ -320,7 +346,7 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { VERIFY_CHECK(c2 == 0); \ } -static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint32_t *l) { +static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint32_t *l) { uint64_t c; 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]; uint32_t m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12; @@ -462,7 +488,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint32_t *l secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r)); } -static void secp256k1_scalar_mul_512(uint32_t *l, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +static void secp256k1_scalar_mul_512(uint32_t *l, const secp256k1_scalar *a, const secp256k1_scalar *b) { /* 96 bit accumulator. */ uint32_t c0 = 0, c1 = 0, c2 = 0; @@ -550,7 +576,7 @@ static void secp256k1_scalar_mul_512(uint32_t *l, const secp256k1_scalar_t *a, c l[15] = c0; } -static void secp256k1_scalar_sqr_512(uint32_t *l, const secp256k1_scalar_t *a) { +static void secp256k1_scalar_sqr_512(uint32_t *l, const secp256k1_scalar *a) { /* 96 bit accumulator. */ uint32_t c0 = 0, c1 = 0, c2 = 0; @@ -618,20 +644,36 @@ static void secp256k1_scalar_sqr_512(uint32_t *l, const secp256k1_scalar_t *a) { #undef extract #undef extract_fast -static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *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) { +static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { + int ret; + VERIFY_CHECK(n > 0); + VERIFY_CHECK(n < 16); + ret = r->d[0] & ((1 << n) - 1); + r->d[0] = (r->d[0] >> n) + (r->d[1] << (32 - n)); + r->d[1] = (r->d[1] >> n) + (r->d[2] << (32 - n)); + r->d[2] = (r->d[2] >> n) + (r->d[3] << (32 - n)); + r->d[3] = (r->d[3] >> n) + (r->d[4] << (32 - n)); + r->d[4] = (r->d[4] >> n) + (r->d[5] << (32 - n)); + r->d[5] = (r->d[5] >> n) + (r->d[6] << (32 - n)); + r->d[6] = (r->d[6] >> n) + (r->d[7] << (32 - n)); + r->d[7] = (r->d[7] >> n); + return ret; +} + +static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { uint32_t l[16]; secp256k1_scalar_sqr_512(l, a); secp256k1_scalar_reduce_512(r, l); } #ifdef USE_ENDOMORPHISM -static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) { +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { r1->d[0] = a->d[0]; r1->d[1] = a->d[1]; r1->d[2] = a->d[2]; @@ -651,11 +693,11 @@ static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_ } #endif -SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *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) { +SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift) { uint32_t l[16]; unsigned int shiftlimbs; unsigned int shiftlow; @@ -673,9 +715,7 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t * 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); - } + secp256k1_scalar_cadd_bit(r, 0, (l[(shift - 1) >> 5] >> ((shift - 1) & 0x1f)) & 1); } #endif diff --git a/src/secp256k1/src/scalar_impl.h b/src/secp256k1/src/scalar_impl.h index 33824983e4..88ea97de86 100644 --- a/src/secp256k1/src/scalar_impl.h +++ b/src/secp256k1/src/scalar_impl.h @@ -25,14 +25,14 @@ #endif #ifndef USE_NUM_NONE -static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a) { +static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a) { unsigned char c[32]; secp256k1_scalar_get_b32(c, a); secp256k1_num_set_bin(r, c, 32); } /** secp256k1 curve order, see secp256k1_ecdsa_const_order_as_fe in ecdsa_impl.h */ -static void secp256k1_scalar_order_get_num(secp256k1_num_t *r) { +static void secp256k1_scalar_order_get_num(secp256k1_num *r) { static const unsigned char order[32] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, @@ -43,11 +43,11 @@ static void secp256k1_scalar_order_get_num(secp256k1_num_t *r) { } #endif -static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scalar_t *x) { - secp256k1_scalar_t *t; +static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { + secp256k1_scalar *t; int i; /* 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 x2, x3, x4, x6, x7, x8, x15, x30, x60, x120, x127; secp256k1_scalar_sqr(&x2, x); secp256k1_scalar_mul(&x2, &x2, x); @@ -234,18 +234,27 @@ static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scal secp256k1_scalar_mul(r, t, &x6); /* 111111 */ } -static void secp256k1_scalar_inverse_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *x) { +SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { + /* d[0] is present and is the lowest word for all representations */ + return !(a->d[0] & 1); +} + +static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { #if defined(USE_SCALAR_INV_BUILTIN) secp256k1_scalar_inverse(r, x); #elif defined(USE_SCALAR_INV_NUM) unsigned char b[32]; - secp256k1_num_t n, m; - secp256k1_scalar_get_b32(b, x); + secp256k1_num n, m; + secp256k1_scalar t = *x; + secp256k1_scalar_get_b32(b, &t); secp256k1_num_set_bin(&n, b, 32); secp256k1_scalar_order_get_num(&m); secp256k1_num_mod_inverse(&n, &n, &m); secp256k1_num_get_bin(b, 32, &n); secp256k1_scalar_set_b32(r, b, NULL); + /* Verify that the inverse was computed correctly, without GMP code. */ + secp256k1_scalar_mul(&t, &t, r); + CHECK(secp256k1_scalar_is_one(&t)); #else #error "Please select scalar inverse implementation" #endif @@ -290,30 +299,31 @@ static void secp256k1_scalar_inverse_var(secp256k1_scalar_t *r, const secp256k1_ * The function below splits a in r1 and r2, such that r1 + lambda * r2 == a (mod order). */ -static void secp256k1_scalar_split_lambda_var(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) { - secp256k1_scalar_t c1, c2; - static const secp256k1_scalar_t minus_lambda = SECP256K1_SCALAR_CONST( +static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { + secp256k1_scalar c1, c2; + static const secp256k1_scalar minus_lambda = SECP256K1_SCALAR_CONST( 0xAC9C52B3UL, 0x3FA3CF1FUL, 0x5AD9E3FDUL, 0x77ED9BA4UL, 0xA880B9FCUL, 0x8EC739C2UL, 0xE0CFC810UL, 0xB51283CFUL ); - static const secp256k1_scalar_t minus_b1 = SECP256K1_SCALAR_CONST( + static const secp256k1_scalar minus_b1 = SECP256K1_SCALAR_CONST( 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 0xE4437ED6UL, 0x010E8828UL, 0x6F547FA9UL, 0x0ABFE4C3UL ); - static const secp256k1_scalar_t minus_b2 = SECP256K1_SCALAR_CONST( + static const secp256k1_scalar minus_b2 = SECP256K1_SCALAR_CONST( 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, 0x8A280AC5UL, 0x0774346DUL, 0xD765CDA8UL, 0x3DB1562CUL ); - static const secp256k1_scalar_t g1 = SECP256K1_SCALAR_CONST( + static const secp256k1_scalar g1 = SECP256K1_SCALAR_CONST( 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00003086UL, 0xD221A7D4UL, 0x6BCDE86CUL, 0x90E49284UL, 0xEB153DABUL ); - static const secp256k1_scalar_t g2 = SECP256K1_SCALAR_CONST( + static const secp256k1_scalar g2 = SECP256K1_SCALAR_CONST( 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x0000E443UL, 0x7ED6010EUL, 0x88286F54UL, 0x7FA90ABFUL, 0xE4C42212UL ); VERIFY_CHECK(r1 != a); VERIFY_CHECK(r2 != a); + /* these _var calls are constant time since the shift amount is constant */ secp256k1_scalar_mul_shift_var(&c1, a, &g1, 272); secp256k1_scalar_mul_shift_var(&c2, a, &g2, 272); secp256k1_scalar_mul(&c1, &c1, &minus_b1); diff --git a/src/secp256k1/src/secp256k1.c b/src/secp256k1/src/secp256k1.c index d6192dc4ed..62d192baeb 100644 --- a/src/secp256k1/src/secp256k1.c +++ b/src/secp256k1/src/secp256k1.c @@ -14,150 +14,348 @@ #include "scalar_impl.h" #include "group_impl.h" #include "ecmult_impl.h" +#include "ecmult_const_impl.h" #include "ecmult_gen_impl.h" #include "ecdsa_impl.h" #include "eckey_impl.h" #include "hash_impl.h" +#define ARG_CHECK(cond) do { \ + if (EXPECT(!(cond), 0)) { \ + secp256k1_callback_call(&ctx->illegal_callback, #cond); \ + return 0; \ + } \ +} while(0) + +static void default_illegal_callback_fn(const char* str, void* data) { + (void)data; + fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str); + abort(); +} + +static const secp256k1_callback default_illegal_callback = { + default_illegal_callback_fn, + NULL +}; + +static void default_error_callback_fn(const char* str, void* data) { + (void)data; + fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); + abort(); +} + +static const secp256k1_callback default_error_callback = { + default_error_callback_fn, + NULL +}; + + struct secp256k1_context_struct { - secp256k1_ecmult_context_t ecmult_ctx; - secp256k1_ecmult_gen_context_t ecmult_gen_ctx; + secp256k1_ecmult_context ecmult_ctx; + secp256k1_ecmult_gen_context ecmult_gen_ctx; + secp256k1_callback illegal_callback; + secp256k1_callback error_callback; }; -secp256k1_context_t* secp256k1_context_create(int flags) { - secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(sizeof(secp256k1_context_t)); +secp256k1_context* secp256k1_context_create(unsigned int flags) { + secp256k1_context* ret = (secp256k1_context*)checked_malloc(&default_error_callback, sizeof(secp256k1_context)); + ret->illegal_callback = default_illegal_callback; + ret->error_callback = default_error_callback; + + if (EXPECT((flags & SECP256K1_FLAGS_TYPE_MASK) != SECP256K1_FLAGS_TYPE_CONTEXT, 0)) { + secp256k1_callback_call(&ret->illegal_callback, + "Invalid flags"); + free(ret); + return NULL; + } secp256k1_ecmult_context_init(&ret->ecmult_ctx); secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx); - if (flags & SECP256K1_CONTEXT_SIGN) { - secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx); + if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN) { + secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &ret->error_callback); } - if (flags & SECP256K1_CONTEXT_VERIFY) { - secp256k1_ecmult_context_build(&ret->ecmult_ctx); + if (flags & SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) { + secp256k1_ecmult_context_build(&ret->ecmult_ctx, &ret->error_callback); } return ret; } -secp256k1_context_t* secp256k1_context_clone(const secp256k1_context_t* ctx) { - secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(sizeof(secp256k1_context_t)); - secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx); - secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx); +secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { + secp256k1_context* ret = (secp256k1_context*)checked_malloc(&ctx->error_callback, sizeof(secp256k1_context)); + ret->illegal_callback = ctx->illegal_callback; + ret->error_callback = ctx->error_callback; + secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx, &ctx->error_callback); + secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx, &ctx->error_callback); return ret; } -void secp256k1_context_destroy(secp256k1_context_t* ctx) { - secp256k1_ecmult_context_clear(&ctx->ecmult_ctx); - secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); +void secp256k1_context_destroy(secp256k1_context* ctx) { + if (ctx != NULL) { + secp256k1_ecmult_context_clear(&ctx->ecmult_ctx); + secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); - free(ctx); + free(ctx); + } } -int secp256k1_ecdsa_verify(const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) { - secp256k1_ge_t q; - secp256k1_ecdsa_sig_t s; - secp256k1_scalar_t m; - int ret = -3; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - DEBUG_CHECK(msg32 != NULL); - DEBUG_CHECK(sig != NULL); - DEBUG_CHECK(pubkey != NULL); +void secp256k1_context_set_illegal_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { + if (fun == NULL) { + fun = default_illegal_callback_fn; + } + ctx->illegal_callback.fn = fun; + ctx->illegal_callback.data = data; +} - secp256k1_scalar_set_b32(&m, msg32, NULL); +void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { + if (fun == NULL) { + fun = default_error_callback_fn; + } + ctx->error_callback.fn = fun; + ctx->error_callback.data = data; +} - if (secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen)) { - if (secp256k1_ecdsa_sig_parse(&s, sig, siglen)) { - if (secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &s, &q, &m)) { - /* success is 1, all other values are fail */ - ret = 1; - } else { - ret = 0; - } - } else { - ret = -2; - } +static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) { + if (sizeof(secp256k1_ge_storage) == 64) { + /* When the secp256k1_ge_storage type is exactly 64 byte, use its + * representation inside secp256k1_pubkey, as conversion is very fast. + * Note that secp256k1_pubkey_save must use the same representation. */ + secp256k1_ge_storage s; + memcpy(&s, &pubkey->data[0], 64); + secp256k1_ge_from_storage(ge, &s); + } else { + /* Otherwise, fall back to 32-byte big endian for X and Y. */ + secp256k1_fe x, y; + secp256k1_fe_set_b32(&x, pubkey->data); + secp256k1_fe_set_b32(&y, pubkey->data + 32); + secp256k1_ge_set_xy(ge, &x, &y); + } + ARG_CHECK(!secp256k1_fe_is_zero(&ge->x)); + return 1; +} + +static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) { + if (sizeof(secp256k1_ge_storage) == 64) { + secp256k1_ge_storage s; + secp256k1_ge_to_storage(&s, ge); + memcpy(&pubkey->data[0], &s, 64); } else { - ret = -1; + VERIFY_CHECK(!secp256k1_ge_is_infinity(ge)); + secp256k1_fe_normalize_var(&ge->x); + secp256k1_fe_normalize_var(&ge->y); + secp256k1_fe_get_b32(pubkey->data, &ge->x); + secp256k1_fe_get_b32(pubkey->data + 32, &ge->y); } +} + +int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, const unsigned char *input, size_t inputlen) { + secp256k1_ge Q; + + (void)ctx; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + memset(pubkey, 0, sizeof(*pubkey)); + ARG_CHECK(input != NULL); + if (!secp256k1_eckey_pubkey_parse(&Q, input, inputlen)) { + return 0; + } + secp256k1_pubkey_save(pubkey, &Q); + secp256k1_ge_clear(&Q); + return 1; +} + +int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey* pubkey, unsigned int flags) { + secp256k1_ge Q; + size_t len; + int ret = 0; + (void)ctx; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(outputlen != NULL); + ARG_CHECK(*outputlen >= ((flags & SECP256K1_FLAGS_BIT_COMPRESSION) ? 33 : 65)); + len = *outputlen; + *outputlen = 0; + ARG_CHECK(output != NULL); + memset(output, 0, len); + ARG_CHECK(pubkey != NULL); + ARG_CHECK((flags & SECP256K1_FLAGS_TYPE_MASK) == SECP256K1_FLAGS_TYPE_COMPRESSION); + if (secp256k1_pubkey_load(ctx, &Q, pubkey)) { + ret = secp256k1_eckey_pubkey_serialize(&Q, output, &len, flags & SECP256K1_FLAGS_BIT_COMPRESSION); + if (ret) { + *outputlen = len; + } + } return ret; } -static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { - secp256k1_rfc6979_hmac_sha256_t rng; - unsigned int i; - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key32, 32, msg32, 32, (const unsigned char*)data, data != NULL ? 32 : 0); - for (i = 0; i <= counter; i++) { - secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); - } - secp256k1_rfc6979_hmac_sha256_finalize(&rng); - return 1; +static void secp256k1_ecdsa_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_ecdsa_signature* sig) { + (void)ctx; + if (sizeof(secp256k1_scalar) == 32) { + /* When the secp256k1_scalar type is exactly 32 byte, use its + * representation inside secp256k1_ecdsa_signature, as conversion is very fast. + * Note that secp256k1_ecdsa_signature_save must use the same representation. */ + memcpy(r, &sig->data[0], 32); + memcpy(s, &sig->data[32], 32); + } else { + secp256k1_scalar_set_b32(r, &sig->data[0], NULL); + secp256k1_scalar_set_b32(s, &sig->data[32], NULL); + } } -const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979; -const secp256k1_nonce_function_t secp256k1_nonce_function_default = nonce_function_rfc6979; +static void secp256k1_ecdsa_signature_save(secp256k1_ecdsa_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s) { + if (sizeof(secp256k1_scalar) == 32) { + memcpy(&sig->data[0], r, 32); + memcpy(&sig->data[32], s, 32); + } else { + secp256k1_scalar_get_b32(&sig->data[0], r); + secp256k1_scalar_get_b32(&sig->data[32], s); + } +} -int secp256k1_ecdsa_sign(const secp256k1_context_t* ctx, const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) { - secp256k1_ecdsa_sig_t sig; - secp256k1_scalar_t sec, non, msg; - int ret = 0; +int secp256k1_ecdsa_signature_parse_der(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { + secp256k1_scalar r, s; + + (void)ctx; + ARG_CHECK(sig != NULL); + ARG_CHECK(input != NULL); + + if (secp256k1_ecdsa_sig_parse(&r, &s, input, inputlen)) { + secp256k1_ecdsa_signature_save(sig, &r, &s); + return 1; + } else { + memset(sig, 0, sizeof(*sig)); + return 0; + } +} + +int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input64) { + secp256k1_scalar r, s; + int ret = 1; int overflow = 0; - unsigned int count = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - DEBUG_CHECK(msg32 != NULL); - DEBUG_CHECK(signature != NULL); - DEBUG_CHECK(signaturelen != NULL); - DEBUG_CHECK(seckey != NULL); - if (noncefp == NULL) { - noncefp = secp256k1_nonce_function_default; + + (void)ctx; + ARG_CHECK(sig != NULL); + ARG_CHECK(input64 != NULL); + + secp256k1_scalar_set_b32(&r, &input64[0], &overflow); + ret &= !overflow; + secp256k1_scalar_set_b32(&s, &input64[32], &overflow); + ret &= !overflow; + if (ret) { + secp256k1_ecdsa_signature_save(sig, &r, &s); + } else { + memset(sig, 0, sizeof(*sig)); } + return ret; +} - secp256k1_scalar_set_b32(&sec, seckey, &overflow); - /* Fail if the secret key is invalid. */ - if (!overflow && !secp256k1_scalar_is_zero(&sec)) { - secp256k1_scalar_set_b32(&msg, msg32, NULL); - while (1) { - unsigned char nonce32[32]; - ret = noncefp(nonce32, msg32, seckey, count, noncedata); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&non, nonce32, &overflow); - memset(nonce32, 0, 32); - if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &sig, &sec, &msg, &non, NULL)) { - break; - } - } - count++; - } +int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_ecdsa_signature* sig) { + secp256k1_scalar r, s; + + (void)ctx; + ARG_CHECK(output != NULL); + ARG_CHECK(outputlen != NULL); + ARG_CHECK(sig != NULL); + + secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); + return secp256k1_ecdsa_sig_serialize(output, outputlen, &r, &s); +} + +int secp256k1_ecdsa_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, const secp256k1_ecdsa_signature* sig) { + secp256k1_scalar r, s; + + (void)ctx; + ARG_CHECK(output64 != NULL); + ARG_CHECK(sig != NULL); + + secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); + secp256k1_scalar_get_b32(&output64[0], &r); + secp256k1_scalar_get_b32(&output64[32], &s); + return 1; +} + +int secp256k1_ecdsa_signature_normalize(const secp256k1_context* ctx, secp256k1_ecdsa_signature *sigout, const secp256k1_ecdsa_signature *sigin) { + secp256k1_scalar r, s; + int ret = 0; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sigin != NULL); + + secp256k1_ecdsa_signature_load(ctx, &r, &s, sigin); + ret = secp256k1_scalar_is_high(&s); + if (sigout != NULL) { if (ret) { - ret = secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig); + secp256k1_scalar_negate(&s, &s); } - secp256k1_scalar_clear(&msg); - secp256k1_scalar_clear(&non); - secp256k1_scalar_clear(&sec); - } - if (!ret) { - *signaturelen = 0; + secp256k1_ecdsa_signature_save(sigout, &r, &s); } + return ret; } -int secp256k1_ecdsa_sign_compact(const secp256k1_context_t* ctx, const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata, int *recid) { - secp256k1_ecdsa_sig_t sig; - secp256k1_scalar_t sec, non, msg; +int secp256k1_ecdsa_verify(const secp256k1_context* ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msg32, const secp256k1_pubkey *pubkey) { + secp256k1_ge q; + secp256k1_scalar r, s; + secp256k1_scalar m; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(pubkey != NULL); + + secp256k1_scalar_set_b32(&m, msg32, NULL); + secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); + return (!secp256k1_scalar_is_high(&s) && + secp256k1_pubkey_load(ctx, &q, pubkey) && + secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &r, &s, &q, &m)); +} + +static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { + unsigned char keydata[112]; + int keylen = 64; + secp256k1_rfc6979_hmac_sha256_t rng; + unsigned int i; + /* We feed a byte array to the PRNG as input, consisting of: + * - the private key (32 bytes) and message (32 bytes), see RFC 6979 3.2d. + * - optionally 32 extra bytes of data, see RFC 6979 3.6 Additional Data. + * - optionally 16 extra bytes with the algorithm name. + * Because the arguments have distinct fixed lengths it is not possible for + * different argument mixtures to emulate each other and result in the same + * nonces. + */ + memcpy(keydata, key32, 32); + memcpy(keydata + 32, msg32, 32); + if (data != NULL) { + memcpy(keydata + 64, data, 32); + keylen = 96; + } + if (algo16 != NULL) { + memcpy(keydata + keylen, algo16, 16); + keylen += 16; + } + secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, keylen); + memset(keydata, 0, sizeof(keydata)); + for (i = 0; i <= counter; i++) { + secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); + } + secp256k1_rfc6979_hmac_sha256_finalize(&rng); + return 1; +} + +const secp256k1_nonce_function secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979; +const secp256k1_nonce_function secp256k1_nonce_function_default = nonce_function_rfc6979; + +int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { + secp256k1_scalar r, s; + secp256k1_scalar sec, non, msg; int ret = 0; int overflow = 0; - unsigned int count = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - DEBUG_CHECK(msg32 != NULL); - DEBUG_CHECK(sig64 != NULL); - DEBUG_CHECK(seckey != NULL); + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(signature != NULL); + ARG_CHECK(seckey != NULL); if (noncefp == NULL) { noncefp = secp256k1_nonce_function_default; } @@ -165,139 +363,87 @@ int secp256k1_ecdsa_sign_compact(const secp256k1_context_t* ctx, const unsigned secp256k1_scalar_set_b32(&sec, seckey, &overflow); /* Fail if the secret key is invalid. */ if (!overflow && !secp256k1_scalar_is_zero(&sec)) { + unsigned int count = 0; secp256k1_scalar_set_b32(&msg, msg32, NULL); while (1) { unsigned char nonce32[32]; - ret = noncefp(nonce32, msg32, seckey, count, noncedata); + ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); if (!ret) { break; } secp256k1_scalar_set_b32(&non, nonce32, &overflow); memset(nonce32, 0, 32); - if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &sig, &sec, &msg, &non, recid)) { + if (!overflow && !secp256k1_scalar_is_zero(&non)) { + if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, NULL)) { break; } } count++; } - 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); } - if (!ret) { - memset(sig64, 0, 64); - } - return ret; -} - -int secp256k1_ecdsa_recover_compact(const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) { - secp256k1_ge_t q; - secp256k1_ecdsa_sig_t sig; - secp256k1_scalar_t m; - int ret = 0; - int overflow = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - DEBUG_CHECK(msg32 != NULL); - DEBUG_CHECK(sig64 != NULL); - DEBUG_CHECK(pubkey != NULL); - DEBUG_CHECK(pubkeylen != NULL); - DEBUG_CHECK(recid >= 0 && recid <= 3); - - secp256k1_scalar_set_b32(&sig.r, sig64, &overflow); - if (!overflow) { - secp256k1_scalar_set_b32(&sig.s, sig64 + 32, &overflow); - if (!overflow) { - secp256k1_scalar_set_b32(&m, msg32, NULL); - - if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &sig, &q, &m, recid)) { - ret = secp256k1_eckey_pubkey_serialize(&q, pubkey, pubkeylen, compressed); - } - } + if (ret) { + secp256k1_ecdsa_signature_save(signature, &r, &s); + } else { + memset(signature, 0, sizeof(*signature)); } return ret; } -int secp256k1_ec_seckey_verify(const secp256k1_context_t* ctx, const unsigned char *seckey) { - secp256k1_scalar_t sec; +int secp256k1_ec_seckey_verify(const secp256k1_context* ctx, const unsigned char *seckey) { + secp256k1_scalar sec; int ret; int overflow; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(seckey != NULL); + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); (void)ctx; secp256k1_scalar_set_b32(&sec, seckey, &overflow); - ret = !secp256k1_scalar_is_zero(&sec) && !overflow; + ret = !overflow && !secp256k1_scalar_is_zero(&sec); secp256k1_scalar_clear(&sec); return ret; } -int secp256k1_ec_pubkey_verify(const secp256k1_context_t* ctx, const unsigned char *pubkey, int pubkeylen) { - secp256k1_ge_t q; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(pubkey != NULL); - (void)ctx; - - return secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen); -} - -int secp256k1_ec_pubkey_create(const secp256k1_context_t* ctx, unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed) { - secp256k1_gej_t pj; - secp256k1_ge_t p; - secp256k1_scalar_t sec; +int secp256k1_ec_pubkey_create(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) { + secp256k1_gej pj; + secp256k1_ge p; + secp256k1_scalar sec; int overflow; int ret = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - DEBUG_CHECK(pubkey != NULL); - DEBUG_CHECK(pubkeylen != NULL); - DEBUG_CHECK(seckey != NULL); + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + memset(pubkey, 0, sizeof(*pubkey)); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(seckey != NULL); secp256k1_scalar_set_b32(&sec, seckey, &overflow); - if (!overflow) { + ret = (!overflow) & (!secp256k1_scalar_is_zero(&sec)); + if (ret) { secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pj, &sec); - secp256k1_scalar_clear(&sec); secp256k1_ge_set_gej(&p, &pj); - ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, compressed); - } - if (!ret) { - *pubkeylen = 0; - } - return ret; -} - -int secp256k1_ec_pubkey_decompress(const secp256k1_context_t* ctx, unsigned char *pubkey, int *pubkeylen) { - secp256k1_ge_t p; - int ret = 0; - DEBUG_CHECK(pubkey != NULL); - DEBUG_CHECK(pubkeylen != NULL); - (void)ctx; - - if (secp256k1_eckey_pubkey_parse(&p, pubkey, *pubkeylen)) { - ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, 0); + secp256k1_pubkey_save(pubkey, &p); } + secp256k1_scalar_clear(&sec); return ret; } -int secp256k1_ec_privkey_tweak_add(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *tweak) { - secp256k1_scalar_t term; - secp256k1_scalar_t sec; +int secp256k1_ec_privkey_tweak_add(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak) { + secp256k1_scalar term; + secp256k1_scalar sec; int ret = 0; int overflow = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(seckey != NULL); - DEBUG_CHECK(tweak != NULL); + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); + ARG_CHECK(tweak != NULL); (void)ctx; secp256k1_scalar_set_b32(&term, tweak, &overflow); secp256k1_scalar_set_b32(&sec, seckey, NULL); - ret = secp256k1_eckey_privkey_tweak_add(&sec, &term) && !overflow; + ret = !overflow && secp256k1_eckey_privkey_tweak_add(&sec, &term); + memset(seckey, 0, 32); if (ret) { secp256k1_scalar_get_b32(seckey, &sec); } @@ -307,45 +453,44 @@ int secp256k1_ec_privkey_tweak_add(const secp256k1_context_t* ctx, unsigned char return ret; } -int secp256k1_ec_pubkey_tweak_add(const secp256k1_context_t* ctx, unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { - secp256k1_ge_t p; - secp256k1_scalar_t term; +int secp256k1_ec_pubkey_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak) { + secp256k1_ge p; + secp256k1_scalar term; int ret = 0; int overflow = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - DEBUG_CHECK(pubkey != NULL); - DEBUG_CHECK(tweak != NULL); + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); + ARG_CHECK(pubkey != NULL); + ARG_CHECK(tweak != NULL); secp256k1_scalar_set_b32(&term, tweak, &overflow); - if (!overflow) { - ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); - if (ret) { - ret = secp256k1_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &p, &term); - } - if (ret) { - int oldlen = pubkeylen; - ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); - VERIFY_CHECK(pubkeylen == oldlen); + ret = !overflow && secp256k1_pubkey_load(ctx, &p, pubkey); + memset(pubkey, 0, sizeof(*pubkey)); + if (ret) { + if (secp256k1_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &p, &term)) { + secp256k1_pubkey_save(pubkey, &p); + } else { + ret = 0; } } return ret; } -int secp256k1_ec_privkey_tweak_mul(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *tweak) { - secp256k1_scalar_t factor; - secp256k1_scalar_t sec; +int secp256k1_ec_privkey_tweak_mul(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak) { + secp256k1_scalar factor; + secp256k1_scalar sec; int ret = 0; int overflow = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(seckey != NULL); - DEBUG_CHECK(tweak != NULL); + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); + ARG_CHECK(tweak != NULL); (void)ctx; secp256k1_scalar_set_b32(&factor, tweak, &overflow); secp256k1_scalar_set_b32(&sec, seckey, NULL); - ret = secp256k1_eckey_privkey_tweak_mul(&sec, &factor) && !overflow; + ret = !overflow && secp256k1_eckey_privkey_tweak_mul(&sec, &factor); + memset(seckey, 0, 32); if (ret) { secp256k1_scalar_get_b32(seckey, &sec); } @@ -355,65 +500,69 @@ int secp256k1_ec_privkey_tweak_mul(const secp256k1_context_t* ctx, unsigned char return ret; } -int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context_t* ctx, unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { - secp256k1_ge_t p; - secp256k1_scalar_t factor; +int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak) { + secp256k1_ge p; + secp256k1_scalar factor; int ret = 0; int overflow = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - DEBUG_CHECK(pubkey != NULL); - DEBUG_CHECK(tweak != NULL); + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); + ARG_CHECK(pubkey != NULL); + ARG_CHECK(tweak != NULL); secp256k1_scalar_set_b32(&factor, tweak, &overflow); - if (!overflow) { - ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); - if (ret) { - ret = secp256k1_eckey_pubkey_tweak_mul(&ctx->ecmult_ctx, &p, &factor); - } - if (ret) { - int oldlen = pubkeylen; - ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); - VERIFY_CHECK(pubkeylen == oldlen); + ret = !overflow && secp256k1_pubkey_load(ctx, &p, pubkey); + memset(pubkey, 0, sizeof(*pubkey)); + if (ret) { + if (secp256k1_eckey_pubkey_tweak_mul(&ctx->ecmult_ctx, &p, &factor)) { + secp256k1_pubkey_save(pubkey, &p); + } else { + ret = 0; } } return ret; } -int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed) { - secp256k1_scalar_t key; - int ret = 0; - DEBUG_CHECK(seckey != NULL); - DEBUG_CHECK(privkey != NULL); - DEBUG_CHECK(privkeylen != NULL); - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - - secp256k1_scalar_set_b32(&key, seckey, NULL); - ret = secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, privkeylen, &key, compressed); - secp256k1_scalar_clear(&key); - return ret; +int secp256k1_context_randomize(secp256k1_context* ctx, const unsigned char *seed32) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); + return 1; } -int secp256k1_ec_privkey_import(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *privkey, int privkeylen) { - secp256k1_scalar_t key; - int ret = 0; - DEBUG_CHECK(seckey != NULL); - DEBUG_CHECK(privkey != NULL); - (void)ctx; +int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, const secp256k1_pubkey * const *pubnonces, size_t n) { + size_t i; + secp256k1_gej Qj; + secp256k1_ge Q; - ret = secp256k1_eckey_privkey_parse(&key, privkey, privkeylen); - if (ret) { - secp256k1_scalar_get_b32(seckey, &key); - } - secp256k1_scalar_clear(&key); - return ret; -} + ARG_CHECK(pubnonce != NULL); + memset(pubnonce, 0, sizeof(*pubnonce)); + ARG_CHECK(n >= 1); + ARG_CHECK(pubnonces != NULL); -int secp256k1_context_randomize(secp256k1_context_t* ctx, const unsigned char *seed32) { - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); + secp256k1_gej_set_infinity(&Qj); + + for (i = 0; i < n; i++) { + secp256k1_pubkey_load(ctx, &Q, pubnonces[i]); + secp256k1_gej_add_ge(&Qj, &Qj, &Q); + } + if (secp256k1_gej_is_infinity(&Qj)) { + return 0; + } + secp256k1_ge_set_gej(&Q, &Qj); + secp256k1_pubkey_save(pubnonce, &Q); return 1; } + +#ifdef ENABLE_MODULE_ECDH +# include "modules/ecdh/main_impl.h" +#endif + +#ifdef ENABLE_MODULE_SCHNORR +# include "modules/schnorr/main_impl.h" +#endif + +#ifdef ENABLE_MODULE_RECOVERY +# include "modules/recovery/main_impl.h" +#endif diff --git a/src/secp256k1/src/testrand.h b/src/secp256k1/src/testrand.h index 041bb92c47..f8efa93c7c 100644 --- a/src/secp256k1/src/testrand.h +++ b/src/secp256k1/src/testrand.h @@ -16,13 +16,23 @@ /** Seed the pseudorandom number generator for testing. */ SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16); -/** Generate a pseudorandom 32-bit number. */ +/** Generate a pseudorandom number in the range [0..2**32-1]. */ static uint32_t secp256k1_rand32(void); +/** Generate a pseudorandom number in the range [0..2**bits-1]. Bits must be 1 or + * more. */ +static uint32_t secp256k1_rand_bits(int bits); + +/** Generate a pseudorandom number in the range [0..range-1]. */ +static uint32_t secp256k1_rand_int(uint32_t range); + /** 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); +/** Generate pseudorandom bytes with long sequences of zero and one bits. */ +static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len); + #endif diff --git a/src/secp256k1/src/testrand_impl.h b/src/secp256k1/src/testrand_impl.h index 21c69f1c51..15c7b9f12d 100644 --- a/src/secp256k1/src/testrand_impl.h +++ b/src/secp256k1/src/testrand_impl.h @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * + * Copyright (c) 2013-2015 Pieter Wuille * * Distributed under the MIT software license, see the accompanying * * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ @@ -16,9 +16,11 @@ static secp256k1_rfc6979_hmac_sha256_t secp256k1_test_rng; static uint32_t secp256k1_test_rng_precomputed[8]; static int secp256k1_test_rng_precomputed_used = 8; +static uint64_t secp256k1_test_rng_integer; +static int secp256k1_test_rng_integer_bits_left = 0; SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16) { - secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, (const unsigned char*)"TestRNG", 7, seed16, 16, NULL, 0); + secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, seed16, 16); } SECP256K1_INLINE static uint32_t secp256k1_rand32(void) { @@ -29,32 +31,80 @@ SECP256K1_INLINE static uint32_t secp256k1_rand32(void) { return secp256k1_test_rng_precomputed[secp256k1_test_rng_precomputed_used++]; } +static uint32_t secp256k1_rand_bits(int bits) { + uint32_t ret; + if (secp256k1_test_rng_integer_bits_left < bits) { + secp256k1_test_rng_integer |= (((uint64_t)secp256k1_rand32()) << secp256k1_test_rng_integer_bits_left); + secp256k1_test_rng_integer_bits_left += 32; + } + ret = secp256k1_test_rng_integer; + secp256k1_test_rng_integer >>= bits; + secp256k1_test_rng_integer_bits_left -= bits; + ret &= ((~((uint32_t)0)) >> (32 - bits)); + return ret; +} + +static uint32_t secp256k1_rand_int(uint32_t range) { + /* We want a uniform integer between 0 and range-1, inclusive. + * B is the smallest number such that range <= 2**B. + * two mechanisms implemented here: + * - generate B bits numbers until one below range is found, and return it + * - find the largest multiple M of range that is <= 2**(B+A), generate B+A + * bits numbers until one below M is found, and return it modulo range + * The second mechanism consumes A more bits of entropy in every iteration, + * but may need fewer iterations due to M being closer to 2**(B+A) then + * range is to 2**B. The array below (indexed by B) contains a 0 when the + * first mechanism is to be used, and the number A otherwise. + */ + static const int addbits[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0}; + uint32_t trange, mult; + int bits = 0; + if (range <= 1) { + return 0; + } + trange = range - 1; + while (trange > 0) { + trange >>= 1; + bits++; + } + if (addbits[bits]) { + bits = bits + addbits[bits]; + mult = ((~((uint32_t)0)) >> (32 - bits)) / range; + trange = range * mult; + } else { + trange = range; + mult = 1; + } + while(1) { + uint32_t x = secp256k1_rand_bits(bits); + if (x < trange) { + return (mult == 1) ? x : (x % range); + } + } +} + static void secp256k1_rand256(unsigned char *b32) { secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, b32, 32); } -static void secp256k1_rand256_test(unsigned char *b32) { - int bits=0; - uint64_t ent = 0; - int entleft = 0; - memset(b32, 0, 32); - while (bits < 256) { +static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len) { + size_t bits = 0; + memset(bytes, 0, len); + while (bits < len * 8) { int now; uint32_t val; - if (entleft < 12) { - ent |= ((uint64_t)secp256k1_rand32()) << entleft; - entleft += 32; - } - now = 1 + ((ent % 64)*((ent >> 6) % 32)+16)/31; - val = 1 & (ent >> 11); - ent >>= 12; - entleft -= 12; - while (now > 0 && bits < 256) { - b32[bits / 8] |= val << (bits % 8); + now = 1 + (secp256k1_rand_bits(6) * secp256k1_rand_bits(5) + 16) / 31; + val = secp256k1_rand_bits(1); + while (now > 0 && bits < len * 8) { + bytes[bits / 8] |= val << (bits % 8); now--; bits++; } } } +static void secp256k1_rand256_test(unsigned char *b32) { + secp256k1_rand_bytes_test(b32, 32); +} + #endif diff --git a/src/secp256k1/src/tests.c b/src/secp256k1/src/tests.c index d0e05057f2..687a5f2fdd 100644 --- a/src/secp256k1/src/tests.c +++ b/src/secp256k1/src/tests.c @@ -14,6 +14,7 @@ #include <time.h> #include "secp256k1.c" +#include "include/secp256k1.h" #include "testrand_impl.h" #ifdef ENABLE_OPENSSL_TESTS @@ -23,10 +24,40 @@ #include "openssl/obj_mac.h" #endif +#include "contrib/lax_der_parsing.c" +#include "contrib/lax_der_privatekey_parsing.c" + +#if !defined(VG_CHECK) +# if defined(VALGRIND) +# include <valgrind/memcheck.h> +# define VG_UNDEF(x,y) VALGRIND_MAKE_MEM_UNDEFINED((x),(y)) +# define VG_CHECK(x,y) VALGRIND_CHECK_MEM_IS_DEFINED((x),(y)) +# else +# define VG_UNDEF(x,y) +# define VG_CHECK(x,y) +# endif +#endif + static int count = 64; -static secp256k1_context_t *ctx = NULL; +static secp256k1_context *ctx = NULL; + +static void counting_illegal_callback_fn(const char* str, void* data) { + /* Dummy callback function that just counts. */ + int32_t *p; + (void)str; + p = data; + (*p)++; +} -void random_field_element_test(secp256k1_fe_t *fe) { +static void uncounting_illegal_callback_fn(const char* str, void* data) { + /* Dummy callback function that just counts (backwards). */ + int32_t *p; + (void)str; + p = data; + (*p)--; +} + +void random_field_element_test(secp256k1_fe *fe) { do { unsigned char b32[32]; secp256k1_rand256_test(b32); @@ -36,9 +67,9 @@ void random_field_element_test(secp256k1_fe_t *fe) { } while(1); } -void random_field_element_magnitude(secp256k1_fe_t *fe) { - secp256k1_fe_t zero; - int n = secp256k1_rand32() % 9; +void random_field_element_magnitude(secp256k1_fe *fe) { + secp256k1_fe zero; + int n = secp256k1_rand_int(9); secp256k1_fe_normalize(fe); if (n == 0) { return; @@ -47,23 +78,22 @@ void random_field_element_magnitude(secp256k1_fe_t *fe) { secp256k1_fe_negate(&zero, &zero, 0); secp256k1_fe_mul_int(&zero, n - 1); secp256k1_fe_add(fe, &zero); -#ifdef VERIFY - CHECK(fe->magnitude == n); -#endif + VERIFY_CHECK(fe->magnitude == n); } -void random_group_element_test(secp256k1_ge_t *ge) { - secp256k1_fe_t fe; +void random_group_element_test(secp256k1_ge *ge) { + secp256k1_fe fe; do { random_field_element_test(&fe); - if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_rand32() & 1)) { + if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_rand_bits(1))) { + secp256k1_fe_normalize(&ge->y); break; } } while(1); } -void random_group_element_jacobian_test(secp256k1_gej_t *gej, const secp256k1_ge_t *ge) { - secp256k1_fe_t z2, z3; +void random_group_element_jacobian_test(secp256k1_gej *gej, const secp256k1_ge *ge) { + secp256k1_fe z2, z3; do { random_field_element_test(&gej->z); if (!secp256k1_fe_is_zero(&gej->z)) { @@ -77,7 +107,7 @@ void random_group_element_jacobian_test(secp256k1_gej_t *gej, const secp256k1_ge gej->infinity = ge->infinity; } -void random_scalar_order_test(secp256k1_scalar_t *num) { +void random_scalar_order_test(secp256k1_scalar *num) { do { unsigned char b32[32]; int overflow = 0; @@ -90,7 +120,7 @@ void random_scalar_order_test(secp256k1_scalar_t *num) { } while(1); } -void random_scalar_order(secp256k1_scalar_t *num) { +void random_scalar_order(secp256k1_scalar *num) { do { unsigned char b32[32]; int overflow = 0; @@ -104,19 +134,31 @@ void random_scalar_order(secp256k1_scalar_t *num) { } void run_context_tests(void) { - secp256k1_context_t *none = secp256k1_context_create(0); - secp256k1_context_t *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - secp256k1_context_t *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); - secp256k1_context_t *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - - secp256k1_gej_t pubj; - secp256k1_ge_t pub; - secp256k1_scalar_t msg, key, nonce; - secp256k1_ecdsa_sig_t sig; + secp256k1_pubkey pubkey; + secp256k1_ecdsa_signature sig; + unsigned char ctmp[32]; + int32_t ecount; + int32_t ecount2; + secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); + secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); + secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + + secp256k1_gej pubj; + secp256k1_ge pub; + secp256k1_scalar msg, key, nonce; + secp256k1_scalar sigr, sigs; + + ecount = 0; + ecount2 = 10; + secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount2); + secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, NULL); + CHECK(vrfy->error_callback.fn != sign->error_callback.fn); /*** clone and destroy all of them to make sure cloning was complete ***/ { - secp256k1_context_t *ctx_tmp; + secp256k1_context *ctx_tmp; ctx_tmp = none; none = secp256k1_context_clone(none); secp256k1_context_destroy(ctx_tmp); ctx_tmp = sign; sign = secp256k1_context_clone(sign); secp256k1_context_destroy(ctx_tmp); @@ -124,30 +166,74 @@ void run_context_tests(void) { ctx_tmp = both; both = secp256k1_context_clone(both); secp256k1_context_destroy(ctx_tmp); } + /* Verify that the error callback makes it across the clone. */ + CHECK(vrfy->error_callback.fn != sign->error_callback.fn); + /* And that it resets back to default. */ + secp256k1_context_set_error_callback(sign, NULL, NULL); + CHECK(vrfy->error_callback.fn == sign->error_callback.fn); + /*** attempt to use them ***/ random_scalar_order_test(&msg); random_scalar_order_test(&key); secp256k1_ecmult_gen(&both->ecmult_gen_ctx, &pubj, &key); secp256k1_ge_set_gej(&pub, &pubj); + /* Verify context-type checking illegal-argument errors. */ + memset(ctmp, 1, 32); + CHECK(secp256k1_ec_pubkey_create(vrfy, &pubkey, ctmp) == 0); + CHECK(ecount == 1); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(sign, &pubkey, ctmp) == 1); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ecdsa_sign(vrfy, &sig, ctmp, ctmp, NULL, NULL) == 0); + CHECK(ecount == 2); + VG_UNDEF(&sig, sizeof(sig)); + CHECK(secp256k1_ecdsa_sign(sign, &sig, ctmp, ctmp, NULL, NULL) == 1); + VG_CHECK(&sig, sizeof(sig)); + CHECK(ecount2 == 10); + CHECK(secp256k1_ecdsa_verify(sign, &sig, ctmp, &pubkey) == 0); + CHECK(ecount2 == 11); + CHECK(secp256k1_ecdsa_verify(vrfy, &sig, ctmp, &pubkey) == 1); + CHECK(ecount == 2); + CHECK(secp256k1_ec_pubkey_tweak_add(sign, &pubkey, ctmp) == 0); + CHECK(ecount2 == 12); + CHECK(secp256k1_ec_pubkey_tweak_add(vrfy, &pubkey, ctmp) == 1); + CHECK(ecount == 2); + CHECK(secp256k1_ec_pubkey_tweak_mul(sign, &pubkey, ctmp) == 0); + CHECK(ecount2 == 13); + CHECK(secp256k1_ec_pubkey_tweak_mul(vrfy, &pubkey, ctmp) == 1); + CHECK(ecount == 2); + CHECK(secp256k1_context_randomize(vrfy, ctmp) == 0); + CHECK(ecount == 3); + CHECK(secp256k1_context_randomize(sign, NULL) == 1); + CHECK(ecount2 == 13); + secp256k1_context_set_illegal_callback(vrfy, NULL, NULL); + secp256k1_context_set_illegal_callback(sign, NULL, NULL); + + /* This shouldn't leak memory, due to already-set tests. */ + secp256k1_ecmult_gen_context_build(&sign->ecmult_gen_ctx, NULL); + secp256k1_ecmult_context_build(&vrfy->ecmult_ctx, NULL); + /* obtain a working nonce */ do { random_scalar_order_test(&nonce); - } while(!secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL)); + } while(!secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); /* try signing */ - CHECK(secp256k1_ecdsa_sig_sign(&sign->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL)); - CHECK(secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL)); + CHECK(secp256k1_ecdsa_sig_sign(&sign->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); + CHECK(secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); /* try verifying */ - CHECK(secp256k1_ecdsa_sig_verify(&vrfy->ecmult_ctx, &sig, &pub, &msg)); - CHECK(secp256k1_ecdsa_sig_verify(&both->ecmult_ctx, &sig, &pub, &msg)); + CHECK(secp256k1_ecdsa_sig_verify(&vrfy->ecmult_ctx, &sigr, &sigs, &pub, &msg)); + CHECK(secp256k1_ecdsa_sig_verify(&both->ecmult_ctx, &sigr, &sigs, &pub, &msg)); /* cleanup */ secp256k1_context_destroy(none); secp256k1_context_destroy(sign); secp256k1_context_destroy(vrfy); secp256k1_context_destroy(both); + /* Defined as no-op. */ + secp256k1_context_destroy(NULL); } /***** HASH TESTS *****/ @@ -178,7 +264,7 @@ void run_sha256_tests(void) { secp256k1_sha256_finalize(&hasher, out); CHECK(memcmp(out, outputs[i], 32) == 0); if (strlen(inputs[i]) > 0) { - int split = secp256k1_rand32() % strlen(inputs[i]); + int split = secp256k1_rand_int(strlen(inputs[i])); secp256k1_sha256_initialize(&hasher); secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); @@ -222,7 +308,7 @@ void run_hmac_sha256_tests(void) { secp256k1_hmac_sha256_finalize(&hasher, out); CHECK(memcmp(out, outputs[i], 32) == 0); if (strlen(inputs[i]) > 0) { - int split = secp256k1_rand32() % strlen(inputs[i]); + int split = secp256k1_rand_int(strlen(inputs[i])); secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); @@ -233,16 +319,14 @@ void run_hmac_sha256_tests(void) { } void run_rfc6979_hmac_sha256_tests(void) { - static const unsigned char key1[32] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00}; - static const unsigned char msg1[32] = {0x4b, 0xf5, 0x12, 0x2f, 0x34, 0x45, 0x54, 0xc5, 0x3b, 0xde, 0x2e, 0xbb, 0x8c, 0xd2, 0xb7, 0xe3, 0xd1, 0x60, 0x0a, 0xd6, 0x31, 0xc3, 0x85, 0xa5, 0xd7, 0xcc, 0xe2, 0x3c, 0x77, 0x85, 0x45, 0x9a}; + static const unsigned char key1[65] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x4b, 0xf5, 0x12, 0x2f, 0x34, 0x45, 0x54, 0xc5, 0x3b, 0xde, 0x2e, 0xbb, 0x8c, 0xd2, 0xb7, 0xe3, 0xd1, 0x60, 0x0a, 0xd6, 0x31, 0xc3, 0x85, 0xa5, 0xd7, 0xcc, 0xe2, 0x3c, 0x77, 0x85, 0x45, 0x9a, 0}; static const unsigned char out1[3][32] = { {0x4f, 0xe2, 0x95, 0x25, 0xb2, 0x08, 0x68, 0x09, 0x15, 0x9a, 0xcd, 0xf0, 0x50, 0x6e, 0xfb, 0x86, 0xb0, 0xec, 0x93, 0x2c, 0x7b, 0xa4, 0x42, 0x56, 0xab, 0x32, 0x1e, 0x42, 0x1e, 0x67, 0xe9, 0xfb}, {0x2b, 0xf0, 0xff, 0xf1, 0xd3, 0xc3, 0x78, 0xa2, 0x2d, 0xc5, 0xde, 0x1d, 0x85, 0x65, 0x22, 0x32, 0x5c, 0x65, 0xb5, 0x04, 0x49, 0x1a, 0x0c, 0xbd, 0x01, 0xcb, 0x8f, 0x3a, 0xa6, 0x7f, 0xfd, 0x4a}, {0xf5, 0x28, 0xb4, 0x10, 0xcb, 0x54, 0x1f, 0x77, 0x00, 0x0d, 0x7a, 0xfb, 0x6c, 0x5b, 0x53, 0xc5, 0xc4, 0x71, 0xea, 0xb4, 0x3e, 0x46, 0x6d, 0x9a, 0xc5, 0x19, 0x0c, 0x39, 0xc8, 0x2f, 0xd8, 0x2e} }; - static const unsigned char key2[32] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - static const unsigned char msg2[32] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}; + static const unsigned char key2[64] = {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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}; static const unsigned char out2[3][32] = { {0x9c, 0x23, 0x6c, 0x16, 0x5b, 0x82, 0xae, 0x0c, 0xd5, 0x90, 0x65, 0x9e, 0x10, 0x0b, 0x6b, 0xab, 0x30, 0x36, 0xe7, 0xba, 0x8b, 0x06, 0x74, 0x9b, 0xaf, 0x69, 0x81, 0xe1, 0x6f, 0x1a, 0x2b, 0x95}, {0xdf, 0x47, 0x10, 0x61, 0x62, 0x5b, 0xc0, 0xea, 0x14, 0xb6, 0x82, 0xfe, 0xee, 0x2c, 0x9c, 0x02, 0xf2, 0x35, 0xda, 0x04, 0x20, 0x4c, 0x1d, 0x62, 0xa1, 0x53, 0x6c, 0x6e, 0x17, 0xae, 0xd7, 0xa9}, @@ -251,24 +335,23 @@ void run_rfc6979_hmac_sha256_tests(void) { secp256k1_rfc6979_hmac_sha256_t rng; unsigned char out[32]; - unsigned char zero[1] = {0}; int i; - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 32, msg1, 32, NULL, 1); + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 64); for (i = 0; i < 3; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); CHECK(memcmp(out, out1[i], 32) == 0); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 32, msg1, 32, zero, 1); + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 65); for (i = 0; i < 3; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); CHECK(memcmp(out, out1[i], 32) != 0); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 32, msg2, 32, zero, 0); + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 64); for (i = 0; i < 3; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); CHECK(memcmp(out, out2[i], 32) == 0); @@ -276,30 +359,102 @@ void run_rfc6979_hmac_sha256_tests(void) { secp256k1_rfc6979_hmac_sha256_finalize(&rng); } +/***** RANDOM TESTS *****/ + +void test_rand_bits(int rand32, int bits) { + /* (1-1/2^B)^rounds[B] < 1/10^9, so rounds is the number of iterations to + * get a false negative chance below once in a billion */ + static const unsigned int rounds[7] = {1, 30, 73, 156, 322, 653, 1316}; + /* We try multiplying the results with various odd numbers, which shouldn't + * influence the uniform distribution modulo a power of 2. */ + static const uint32_t mults[6] = {1, 3, 21, 289, 0x9999, 0x80402011}; + /* We only select up to 6 bits from the output to analyse */ + unsigned int usebits = bits > 6 ? 6 : bits; + unsigned int maxshift = bits - usebits; + /* For each of the maxshift+1 usebits-bit sequences inside a bits-bit + number, track all observed outcomes, one per bit in a uint64_t. */ + uint64_t x[6][27] = {{0}}; + unsigned int i, shift, m; + /* Multiply the output of all rand calls with the odd number m, which + should not change the uniformity of its distribution. */ + for (i = 0; i < rounds[usebits]; i++) { + uint32_t r = (rand32 ? secp256k1_rand32() : secp256k1_rand_bits(bits)); + CHECK((((uint64_t)r) >> bits) == 0); + for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) { + uint32_t rm = r * mults[m]; + for (shift = 0; shift <= maxshift; shift++) { + x[m][shift] |= (((uint64_t)1) << ((rm >> shift) & ((1 << usebits) - 1))); + } + } + } + for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) { + for (shift = 0; shift <= maxshift; shift++) { + /* Test that the lower usebits bits of x[shift] are 1 */ + CHECK(((~x[m][shift]) << (64 - (1 << usebits))) == 0); + } + } +} + +/* Subrange must be a whole divisor of range, and at most 64 */ +void test_rand_int(uint32_t range, uint32_t subrange) { + /* (1-1/subrange)^rounds < 1/10^9 */ + int rounds = (subrange * 2073) / 100; + int i; + uint64_t x = 0; + CHECK((range % subrange) == 0); + for (i = 0; i < rounds; i++) { + uint32_t r = secp256k1_rand_int(range); + CHECK(r < range); + r = r % subrange; + x |= (((uint64_t)1) << r); + } + /* Test that the lower subrange bits of x are 1. */ + CHECK(((~x) << (64 - subrange)) == 0); +} + +void run_rand_bits(void) { + size_t b; + test_rand_bits(1, 32); + for (b = 1; b <= 32; b++) { + test_rand_bits(0, b); + } +} + +void run_rand_int(void) { + static const uint32_t ms[] = {1, 3, 17, 1000, 13771, 999999, 33554432}; + static const uint32_t ss[] = {1, 3, 6, 9, 13, 31, 64}; + unsigned int m, s; + for (m = 0; m < sizeof(ms) / sizeof(ms[0]); m++) { + for (s = 0; s < sizeof(ss) / sizeof(ss[0]); s++) { + test_rand_int(ms[m] * ss[s], ss[s]); + } + } +} + /***** NUM TESTS *****/ #ifndef USE_NUM_NONE -void random_num_negate(secp256k1_num_t *num) { - if (secp256k1_rand32() & 1) { +void random_num_negate(secp256k1_num *num) { + if (secp256k1_rand_bits(1)) { secp256k1_num_negate(num); } } -void random_num_order_test(secp256k1_num_t *num) { - secp256k1_scalar_t sc; +void random_num_order_test(secp256k1_num *num) { + secp256k1_scalar sc; random_scalar_order_test(&sc); secp256k1_scalar_get_num(num, &sc); } -void random_num_order(secp256k1_num_t *num) { - secp256k1_scalar_t sc; +void random_num_order(secp256k1_num *num) { + secp256k1_scalar sc; random_scalar_order(&sc); secp256k1_scalar_get_num(num, &sc); } void test_num_negate(void) { - secp256k1_num_t n1; - secp256k1_num_t n2; + secp256k1_num n1; + secp256k1_num n2; random_num_order_test(&n1); /* n1 = R */ random_num_negate(&n1); secp256k1_num_copy(&n2, &n1); /* n2 = R */ @@ -318,16 +473,15 @@ void test_num_negate(void) { } void test_num_add_sub(void) { - secp256k1_num_t n1; - secp256k1_num_t n2; - secp256k1_num_t n1p2, n2p1, n1m2, n2m1; - int r = secp256k1_rand32(); + secp256k1_num n1; + secp256k1_num n2; + secp256k1_num n1p2, n2p1, n1m2, n2m1; random_num_order_test(&n1); /* n1 = R1 */ - if (r & 1) { + if (secp256k1_rand_bits(1)) { random_num_negate(&n1); } random_num_order_test(&n2); /* n2 = R2 */ - if (r & 2) { + if (secp256k1_rand_bits(1)) { random_num_negate(&n2); } secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = R1 + R2 */ @@ -358,12 +512,12 @@ void run_num_smalltests(void) { /***** SCALAR TESTS *****/ void scalar_test(void) { - secp256k1_scalar_t s; - secp256k1_scalar_t s1; - secp256k1_scalar_t s2; + secp256k1_scalar s; + secp256k1_scalar s1; + secp256k1_scalar s2; #ifndef USE_NUM_NONE - secp256k1_num_t snum, s1num, s2num; - secp256k1_num_t order, half_order; + secp256k1_num snum, s1num, s2num; + secp256k1_num order, half_order; #endif unsigned char c[32]; @@ -390,10 +544,10 @@ void scalar_test(void) { { int i; /* 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 n; secp256k1_scalar_set_int(&n, 0); for (i = 0; i < 256; i += 4) { - secp256k1_scalar_t t; + secp256k1_scalar t; int j; secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits(&s, 256 - 4 - i, 4)); for (j = 0; j < 4; j++) { @@ -406,13 +560,13 @@ void scalar_test(void) { { /* 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 n; int i = 0; secp256k1_scalar_set_int(&n, 0); while (i < 256) { - secp256k1_scalar_t t; + secp256k1_scalar t; int j; - int now = (secp256k1_rand32() % 15) + 1; + int now = secp256k1_rand_int(15) + 1; if (now + i > 256) { now = 256 - i; } @@ -429,9 +583,9 @@ void scalar_test(void) { #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_t r2num; - secp256k1_scalar_t r; + secp256k1_num rnum; + secp256k1_num r2num; + secp256k1_scalar r; secp256k1_num_add(&rnum, &snum, &s2num); secp256k1_num_mod(&rnum, &order); secp256k1_scalar_add(&r, &s, &s2); @@ -440,10 +594,10 @@ void scalar_test(void) { } { - /* Test that multipying the scalars is equal to multiplying their numbers modulo the order. */ - secp256k1_scalar_t r; - secp256k1_num_t r2num; - secp256k1_num_t rnum; + /* Test that multiplying the scalars is equal to multiplying their numbers modulo the order. */ + secp256k1_scalar r; + secp256k1_num r2num; + secp256k1_num rnum; secp256k1_num_mul(&rnum, &snum, &s2num); secp256k1_num_mod(&rnum, &order); secp256k1_scalar_mul(&r, &s, &s2); @@ -457,9 +611,9 @@ void scalar_test(void) { } { - secp256k1_scalar_t neg; - secp256k1_num_t negnum; - secp256k1_num_t negnum2; + secp256k1_scalar neg; + secp256k1_num negnum; + secp256k1_num negnum2; /* 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. */ @@ -484,12 +638,12 @@ void scalar_test(void) { { /* Test secp256k1_scalar_mul_shift_var. */ - secp256k1_scalar_t r; - secp256k1_num_t one; - secp256k1_num_t rnum; - secp256k1_num_t rnum2; + secp256k1_scalar r; + secp256k1_num one; + secp256k1_num rnum; + secp256k1_num rnum2; unsigned char cone[1] = {0x01}; - unsigned int shift = 256 + (secp256k1_rand32() % 257); + unsigned int shift = 256 + secp256k1_rand_int(257); secp256k1_scalar_mul_shift_var(&r, &s1, &s2, shift); secp256k1_num_mul(&rnum, &s1num, &s2num); secp256k1_num_shift(&rnum, shift - 1); @@ -499,15 +653,29 @@ void scalar_test(void) { secp256k1_scalar_get_num(&rnum2, &r); CHECK(secp256k1_num_eq(&rnum, &rnum2)); } + + { + /* test secp256k1_scalar_shr_int */ + secp256k1_scalar r; + int i; + random_scalar_order_test(&r); + for (i = 0; i < 100; ++i) { + int low; + int shift = 1 + secp256k1_rand_int(15); + int expected = r.d[0] % (1 << shift); + low = secp256k1_scalar_shr_int(&r, shift); + CHECK(expected == low); + } + } #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 inv; #ifndef USE_NUM_NONE - secp256k1_num_t invnum; - secp256k1_num_t invnum2; + secp256k1_num invnum; + secp256k1_num invnum2; #endif secp256k1_scalar_inverse(&inv, &s); #ifndef USE_NUM_NONE @@ -526,18 +694,18 @@ void scalar_test(void) { { /* Test commutativity of add. */ - secp256k1_scalar_t r1, r2; + secp256k1_scalar r1, r2; secp256k1_scalar_add(&r1, &s1, &s2); secp256k1_scalar_add(&r2, &s2, &s1); CHECK(secp256k1_scalar_eq(&r1, &r2)); } { - secp256k1_scalar_t r1, r2; - secp256k1_scalar_t b; + secp256k1_scalar r1, r2; + secp256k1_scalar b; int i; /* Test add_bit. */ - int bit = secp256k1_rand32() % 256; + int bit = secp256k1_rand_bits(8); secp256k1_scalar_set_int(&b, 1); CHECK(secp256k1_scalar_is_one(&b)); for (i = 0; i < bit; i++) { @@ -547,14 +715,17 @@ void scalar_test(void) { r2 = s1; if (!secp256k1_scalar_add(&r1, &r1, &b)) { /* No overflow happened. */ - secp256k1_scalar_add_bit(&r2, bit); + secp256k1_scalar_cadd_bit(&r2, bit, 1); + CHECK(secp256k1_scalar_eq(&r1, &r2)); + /* cadd is a noop when flag is zero */ + secp256k1_scalar_cadd_bit(&r2, bit, 0); CHECK(secp256k1_scalar_eq(&r1, &r2)); } } { /* Test commutativity of mul. */ - secp256k1_scalar_t r1, r2; + secp256k1_scalar r1, r2; secp256k1_scalar_mul(&r1, &s1, &s2); secp256k1_scalar_mul(&r2, &s2, &s1); CHECK(secp256k1_scalar_eq(&r1, &r2)); @@ -562,7 +733,7 @@ void scalar_test(void) { { /* Test associativity of add. */ - secp256k1_scalar_t r1, r2; + secp256k1_scalar r1, r2; secp256k1_scalar_add(&r1, &s1, &s2); secp256k1_scalar_add(&r1, &r1, &s); secp256k1_scalar_add(&r2, &s2, &s); @@ -572,7 +743,7 @@ void scalar_test(void) { { /* Test associativity of mul. */ - secp256k1_scalar_t r1, r2; + secp256k1_scalar r1, r2; secp256k1_scalar_mul(&r1, &s1, &s2); secp256k1_scalar_mul(&r1, &r1, &s); secp256k1_scalar_mul(&r2, &s2, &s); @@ -582,7 +753,7 @@ void scalar_test(void) { { /* Test distributitivity of mul over add. */ - secp256k1_scalar_t r1, r2, t; + secp256k1_scalar r1, r2, t; secp256k1_scalar_add(&r1, &s1, &s2); secp256k1_scalar_mul(&r1, &r1, &s); secp256k1_scalar_mul(&r2, &s1, &s); @@ -593,7 +764,7 @@ void scalar_test(void) { { /* Test square. */ - secp256k1_scalar_t r1, r2; + secp256k1_scalar r1, r2; secp256k1_scalar_sqr(&r1, &s1); secp256k1_scalar_mul(&r2, &s1, &s1); CHECK(secp256k1_scalar_eq(&r1, &r2)); @@ -601,7 +772,7 @@ void scalar_test(void) { { /* Test multiplicative identity. */ - secp256k1_scalar_t r1, v1; + secp256k1_scalar r1, v1; secp256k1_scalar_set_int(&v1,1); secp256k1_scalar_mul(&r1, &s1, &v1); CHECK(secp256k1_scalar_eq(&r1, &s1)); @@ -609,7 +780,7 @@ void scalar_test(void) { { /* Test additive identity. */ - secp256k1_scalar_t r1, v0; + secp256k1_scalar r1, v0; secp256k1_scalar_set_int(&v0,0); secp256k1_scalar_add(&r1, &s1, &v0); CHECK(secp256k1_scalar_eq(&r1, &s1)); @@ -617,7 +788,7 @@ void scalar_test(void) { { /* Test zero product property. */ - secp256k1_scalar_t r1, v0; + secp256k1_scalar r1, v0; secp256k1_scalar_set_int(&v0,0); secp256k1_scalar_mul(&r1, &s1, &v0); CHECK(secp256k1_scalar_eq(&r1, &v0)); @@ -633,7 +804,7 @@ void run_scalar_tests(void) { { /* (-1)+1 should be zero. */ - secp256k1_scalar_t s, o; + secp256k1_scalar s, o; secp256k1_scalar_set_int(&s, 1); CHECK(secp256k1_scalar_is_one(&s)); secp256k1_scalar_negate(&o, &s); @@ -646,8 +817,8 @@ void run_scalar_tests(void) { #ifndef USE_NUM_NONE { /* A scalar with value of the curve order should be 0. */ - secp256k1_num_t order; - secp256k1_scalar_t zero; + secp256k1_num order; + secp256k1_scalar zero; unsigned char bin[32]; int overflow = 0; secp256k1_scalar_order_get_num(&order); @@ -657,11 +828,589 @@ void run_scalar_tests(void) { CHECK(secp256k1_scalar_is_zero(&zero)); } #endif + + { + /* Does check_overflow check catch all ones? */ + static const secp256k1_scalar overflowed = SECP256K1_SCALAR_CONST( + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL + ); + CHECK(secp256k1_scalar_check_overflow(&overflowed)); + } + + { + /* Static test vectors. + * These were reduced from ~10^12 random vectors based on comparison-decision + * and edge-case coverage on 32-bit and 64-bit implementations. + * The responses were generated with Sage 5.9. + */ + secp256k1_scalar x; + secp256k1_scalar y; + secp256k1_scalar z; + secp256k1_scalar zz; + secp256k1_scalar one; + secp256k1_scalar r1; + secp256k1_scalar r2; +#if defined(USE_SCALAR_INV_NUM) + secp256k1_scalar zzv; +#endif + int overflow; + unsigned char chal[32][2][32] = { + {{0xff, 0xff, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, + 0xff, 0xff, 0x03, 0x00, 0xc0, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff}}, + {{0xef, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x80, 0xff}}, + {{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x80, 0xff, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x00}, + {0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xe0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff}}, + {{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x1e, 0xf8, 0xff, 0xff, 0xff, 0xfd, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0x00, 0x00, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xe0, + 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, + 0xf3, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {{0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x1f, 0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, + 0x00, 0xfe, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff}}, + {{0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xfc, 0x9f, + 0xff, 0xff, 0xff, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0x0f, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}, + {0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0xf8, 0xff, 0x0f, 0xc0, 0xff, 0xff, + 0xff, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x07, 0x80, 0xff, 0xff, 0xff}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, + 0xf7, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0}, + {0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, + {{0x00, 0xf8, 0xff, 0x03, 0xff, 0xff, 0xff, 0x00, + 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x03, 0xc0, 0xff, 0x0f, 0xfc, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x3f, 0x00, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, + {{0x8f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x7f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0f, 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, 0xc0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x03, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x80, 0xff, 0x7f}, + {0xff, 0xcf, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, + 0xbf, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00}}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, + 0xff, 0xff, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0x01, 0xfc, 0xff, 0x01, 0x00, 0xfe, 0xff}, + {0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00}}, + {{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x7f, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf0, 0xff, 0xff, + 0xe0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x00}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0xfc, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, + 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0x7e, 0x00, 0x00}}, + {{0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x1f, 0x00, 0x00, 0xfe, 0x07, 0x00}, + {0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfb, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60}}, + {{0xff, 0x01, 0x00, 0xff, 0xff, 0xff, 0x0f, 0x00, + 0x80, 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0x1f, 0x00, 0xf0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00}}, + {{0x80, 0x00, 0x00, 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, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, + 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0xff, 0xff, 0xcf, 0xff, 0x1f, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x7e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00}, + {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xff, 0xff, 0x7f, 0x00, 0x80, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}, + {0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x80, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0x7f, 0xf8, 0xff, 0xff, 0x1f, 0x00, 0xfe}}, + {{0xff, 0xff, 0xff, 0x3f, 0xf8, 0xff, 0xff, 0xff, + 0xff, 0x03, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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, 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, 0x40}}, + {{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, 0x00}}, + {{0x7f, 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, 0xff, 0xff, 0xff, 0xff}, + {0x7f, 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, 0xff, 0xff, 0xff, 0xff}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xc0, + 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff}}, + {{0x7f, 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, 0xff, 0xff, 0xff, 0xff}, + {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, 0x02}}, + {{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}, + {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}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x7e, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x07, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0xff, 0x01, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, + {{0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x00, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, + 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, + 0xff, 0xff, 0x3f, 0x00, 0xf8, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x3f, 0x00, 0x00, 0xc0, 0xf1, 0x7f, 0x00}}, + {{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x00}, + {0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, + 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, + 0x00, 0x00, 0xfc, 0xff, 0xff, 0x01, 0xff, 0xff}}, + {{0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x80, 0x00, 0x00, 0x80, 0xff, 0x03, 0xe0, 0x01, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xfc, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}, + {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0xff, 0xff, 0xf0, 0x07, 0x00, 0x3c, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x07, 0xe0, 0xff, 0x00, 0x00, 0x00}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x80, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x7f, 0xfe, 0xff, 0x1f, + 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0xfe, 0xff}}, + {{0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, + 0xff, 0xff, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xf0}, + {0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, + 0xf8, 0x07, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xc7, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff}} + }; + unsigned char res[32][2][32] = { + {{0x0c, 0x3b, 0x0a, 0xca, 0x8d, 0x1a, 0x2f, 0xb9, + 0x8a, 0x7b, 0x53, 0x5a, 0x1f, 0xc5, 0x22, 0xa1, + 0x07, 0x2a, 0x48, 0xea, 0x02, 0xeb, 0xb3, 0xd6, + 0x20, 0x1e, 0x86, 0xd0, 0x95, 0xf6, 0x92, 0x35}, + {0xdc, 0x90, 0x7a, 0x07, 0x2e, 0x1e, 0x44, 0x6d, + 0xf8, 0x15, 0x24, 0x5b, 0x5a, 0x96, 0x37, 0x9c, + 0x37, 0x7b, 0x0d, 0xac, 0x1b, 0x65, 0x58, 0x49, + 0x43, 0xb7, 0x31, 0xbb, 0xa7, 0xf4, 0x97, 0x15}}, + {{0xf1, 0xf7, 0x3a, 0x50, 0xe6, 0x10, 0xba, 0x22, + 0x43, 0x4d, 0x1f, 0x1f, 0x7c, 0x27, 0xca, 0x9c, + 0xb8, 0xb6, 0xa0, 0xfc, 0xd8, 0xc0, 0x05, 0x2f, + 0xf7, 0x08, 0xe1, 0x76, 0xdd, 0xd0, 0x80, 0xc8}, + {0xe3, 0x80, 0x80, 0xb8, 0xdb, 0xe3, 0xa9, 0x77, + 0x00, 0xb0, 0xf5, 0x2e, 0x27, 0xe2, 0x68, 0xc4, + 0x88, 0xe8, 0x04, 0xc1, 0x12, 0xbf, 0x78, 0x59, + 0xe6, 0xa9, 0x7c, 0xe1, 0x81, 0xdd, 0xb9, 0xd5}}, + {{0x96, 0xe2, 0xee, 0x01, 0xa6, 0x80, 0x31, 0xef, + 0x5c, 0xd0, 0x19, 0xb4, 0x7d, 0x5f, 0x79, 0xab, + 0xa1, 0x97, 0xd3, 0x7e, 0x33, 0xbb, 0x86, 0x55, + 0x60, 0x20, 0x10, 0x0d, 0x94, 0x2d, 0x11, 0x7c}, + {0xcc, 0xab, 0xe0, 0xe8, 0x98, 0x65, 0x12, 0x96, + 0x38, 0x5a, 0x1a, 0xf2, 0x85, 0x23, 0x59, 0x5f, + 0xf9, 0xf3, 0xc2, 0x81, 0x70, 0x92, 0x65, 0x12, + 0x9c, 0x65, 0x1e, 0x96, 0x00, 0xef, 0xe7, 0x63}}, + {{0xac, 0x1e, 0x62, 0xc2, 0x59, 0xfc, 0x4e, 0x5c, + 0x83, 0xb0, 0xd0, 0x6f, 0xce, 0x19, 0xf6, 0xbf, + 0xa4, 0xb0, 0xe0, 0x53, 0x66, 0x1f, 0xbf, 0xc9, + 0x33, 0x47, 0x37, 0xa9, 0x3d, 0x5d, 0xb0, 0x48}, + {0x86, 0xb9, 0x2a, 0x7f, 0x8e, 0xa8, 0x60, 0x42, + 0x26, 0x6d, 0x6e, 0x1c, 0xa2, 0xec, 0xe0, 0xe5, + 0x3e, 0x0a, 0x33, 0xbb, 0x61, 0x4c, 0x9f, 0x3c, + 0xd1, 0xdf, 0x49, 0x33, 0xcd, 0x72, 0x78, 0x18}}, + {{0xf7, 0xd3, 0xcd, 0x49, 0x5c, 0x13, 0x22, 0xfb, + 0x2e, 0xb2, 0x2f, 0x27, 0xf5, 0x8a, 0x5d, 0x74, + 0xc1, 0x58, 0xc5, 0xc2, 0x2d, 0x9f, 0x52, 0xc6, + 0x63, 0x9f, 0xba, 0x05, 0x76, 0x45, 0x7a, 0x63}, + {0x8a, 0xfa, 0x55, 0x4d, 0xdd, 0xa3, 0xb2, 0xc3, + 0x44, 0xfd, 0xec, 0x72, 0xde, 0xef, 0xc0, 0x99, + 0xf5, 0x9f, 0xe2, 0x52, 0xb4, 0x05, 0x32, 0x58, + 0x57, 0xc1, 0x8f, 0xea, 0xc3, 0x24, 0x5b, 0x94}}, + {{0x05, 0x83, 0xee, 0xdd, 0x64, 0xf0, 0x14, 0x3b, + 0xa0, 0x14, 0x4a, 0x3a, 0x41, 0x82, 0x7c, 0xa7, + 0x2c, 0xaa, 0xb1, 0x76, 0xbb, 0x59, 0x64, 0x5f, + 0x52, 0xad, 0x25, 0x29, 0x9d, 0x8f, 0x0b, 0xb0}, + {0x7e, 0xe3, 0x7c, 0xca, 0xcd, 0x4f, 0xb0, 0x6d, + 0x7a, 0xb2, 0x3e, 0xa0, 0x08, 0xb9, 0xa8, 0x2d, + 0xc2, 0xf4, 0x99, 0x66, 0xcc, 0xac, 0xd8, 0xb9, + 0x72, 0x2a, 0x4a, 0x3e, 0x0f, 0x7b, 0xbf, 0xf4}}, + {{0x8c, 0x9c, 0x78, 0x2b, 0x39, 0x61, 0x7e, 0xf7, + 0x65, 0x37, 0x66, 0x09, 0x38, 0xb9, 0x6f, 0x70, + 0x78, 0x87, 0xff, 0xcf, 0x93, 0xca, 0x85, 0x06, + 0x44, 0x84, 0xa7, 0xfe, 0xd3, 0xa4, 0xe3, 0x7e}, + {0xa2, 0x56, 0x49, 0x23, 0x54, 0xa5, 0x50, 0xe9, + 0x5f, 0xf0, 0x4d, 0xe7, 0xdc, 0x38, 0x32, 0x79, + 0x4f, 0x1c, 0xb7, 0xe4, 0xbb, 0xf8, 0xbb, 0x2e, + 0x40, 0x41, 0x4b, 0xcc, 0xe3, 0x1e, 0x16, 0x36}}, + {{0x0c, 0x1e, 0xd7, 0x09, 0x25, 0x40, 0x97, 0xcb, + 0x5c, 0x46, 0xa8, 0xda, 0xef, 0x25, 0xd5, 0xe5, + 0x92, 0x4d, 0xcf, 0xa3, 0xc4, 0x5d, 0x35, 0x4a, + 0xe4, 0x61, 0x92, 0xf3, 0xbf, 0x0e, 0xcd, 0xbe}, + {0xe4, 0xaf, 0x0a, 0xb3, 0x30, 0x8b, 0x9b, 0x48, + 0x49, 0x43, 0xc7, 0x64, 0x60, 0x4a, 0x2b, 0x9e, + 0x95, 0x5f, 0x56, 0xe8, 0x35, 0xdc, 0xeb, 0xdc, + 0xc7, 0xc4, 0xfe, 0x30, 0x40, 0xc7, 0xbf, 0xa4}}, + {{0xd4, 0xa0, 0xf5, 0x81, 0x49, 0x6b, 0xb6, 0x8b, + 0x0a, 0x69, 0xf9, 0xfe, 0xa8, 0x32, 0xe5, 0xe0, + 0xa5, 0xcd, 0x02, 0x53, 0xf9, 0x2c, 0xe3, 0x53, + 0x83, 0x36, 0xc6, 0x02, 0xb5, 0xeb, 0x64, 0xb8}, + {0x1d, 0x42, 0xb9, 0xf9, 0xe9, 0xe3, 0x93, 0x2c, + 0x4c, 0xee, 0x6c, 0x5a, 0x47, 0x9e, 0x62, 0x01, + 0x6b, 0x04, 0xfe, 0xa4, 0x30, 0x2b, 0x0d, 0x4f, + 0x71, 0x10, 0xd3, 0x55, 0xca, 0xf3, 0x5e, 0x80}}, + {{0x77, 0x05, 0xf6, 0x0c, 0x15, 0x9b, 0x45, 0xe7, + 0xb9, 0x11, 0xb8, 0xf5, 0xd6, 0xda, 0x73, 0x0c, + 0xda, 0x92, 0xea, 0xd0, 0x9d, 0xd0, 0x18, 0x92, + 0xce, 0x9a, 0xaa, 0xee, 0x0f, 0xef, 0xde, 0x30}, + {0xf1, 0xf1, 0xd6, 0x9b, 0x51, 0xd7, 0x77, 0x62, + 0x52, 0x10, 0xb8, 0x7a, 0x84, 0x9d, 0x15, 0x4e, + 0x07, 0xdc, 0x1e, 0x75, 0x0d, 0x0c, 0x3b, 0xdb, + 0x74, 0x58, 0x62, 0x02, 0x90, 0x54, 0x8b, 0x43}}, + {{0xa6, 0xfe, 0x0b, 0x87, 0x80, 0x43, 0x67, 0x25, + 0x57, 0x5d, 0xec, 0x40, 0x50, 0x08, 0xd5, 0x5d, + 0x43, 0xd7, 0xe0, 0xaa, 0xe0, 0x13, 0xb6, 0xb0, + 0xc0, 0xd4, 0xe5, 0x0d, 0x45, 0x83, 0xd6, 0x13}, + {0x40, 0x45, 0x0a, 0x92, 0x31, 0xea, 0x8c, 0x60, + 0x8c, 0x1f, 0xd8, 0x76, 0x45, 0xb9, 0x29, 0x00, + 0x26, 0x32, 0xd8, 0xa6, 0x96, 0x88, 0xe2, 0xc4, + 0x8b, 0xdb, 0x7f, 0x17, 0x87, 0xcc, 0xc8, 0xf2}}, + {{0xc2, 0x56, 0xe2, 0xb6, 0x1a, 0x81, 0xe7, 0x31, + 0x63, 0x2e, 0xbb, 0x0d, 0x2f, 0x81, 0x67, 0xd4, + 0x22, 0xe2, 0x38, 0x02, 0x25, 0x97, 0xc7, 0x88, + 0x6e, 0xdf, 0xbe, 0x2a, 0xa5, 0x73, 0x63, 0xaa}, + {0x50, 0x45, 0xe2, 0xc3, 0xbd, 0x89, 0xfc, 0x57, + 0xbd, 0x3c, 0xa3, 0x98, 0x7e, 0x7f, 0x36, 0x38, + 0x92, 0x39, 0x1f, 0x0f, 0x81, 0x1a, 0x06, 0x51, + 0x1f, 0x8d, 0x6a, 0xff, 0x47, 0x16, 0x06, 0x9c}}, + {{0x33, 0x95, 0xa2, 0x6f, 0x27, 0x5f, 0x9c, 0x9c, + 0x64, 0x45, 0xcb, 0xd1, 0x3c, 0xee, 0x5e, 0x5f, + 0x48, 0xa6, 0xaf, 0xe3, 0x79, 0xcf, 0xb1, 0xe2, + 0xbf, 0x55, 0x0e, 0xa2, 0x3b, 0x62, 0xf0, 0xe4}, + {0x14, 0xe8, 0x06, 0xe3, 0xbe, 0x7e, 0x67, 0x01, + 0xc5, 0x21, 0x67, 0xd8, 0x54, 0xb5, 0x7f, 0xa4, + 0xf9, 0x75, 0x70, 0x1c, 0xfd, 0x79, 0xdb, 0x86, + 0xad, 0x37, 0x85, 0x83, 0x56, 0x4e, 0xf0, 0xbf}}, + {{0xbc, 0xa6, 0xe0, 0x56, 0x4e, 0xef, 0xfa, 0xf5, + 0x1d, 0x5d, 0x3f, 0x2a, 0x5b, 0x19, 0xab, 0x51, + 0xc5, 0x8b, 0xdd, 0x98, 0x28, 0x35, 0x2f, 0xc3, + 0x81, 0x4f, 0x5c, 0xe5, 0x70, 0xb9, 0xeb, 0x62}, + {0xc4, 0x6d, 0x26, 0xb0, 0x17, 0x6b, 0xfe, 0x6c, + 0x12, 0xf8, 0xe7, 0xc1, 0xf5, 0x2f, 0xfa, 0x91, + 0x13, 0x27, 0xbd, 0x73, 0xcc, 0x33, 0x31, 0x1c, + 0x39, 0xe3, 0x27, 0x6a, 0x95, 0xcf, 0xc5, 0xfb}}, + {{0x30, 0xb2, 0x99, 0x84, 0xf0, 0x18, 0x2a, 0x6e, + 0x1e, 0x27, 0xed, 0xa2, 0x29, 0x99, 0x41, 0x56, + 0xe8, 0xd4, 0x0d, 0xef, 0x99, 0x9c, 0xf3, 0x58, + 0x29, 0x55, 0x1a, 0xc0, 0x68, 0xd6, 0x74, 0xa4}, + {0x07, 0x9c, 0xe7, 0xec, 0xf5, 0x36, 0x73, 0x41, + 0xa3, 0x1c, 0xe5, 0x93, 0x97, 0x6a, 0xfd, 0xf7, + 0x53, 0x18, 0xab, 0xaf, 0xeb, 0x85, 0xbd, 0x92, + 0x90, 0xab, 0x3c, 0xbf, 0x30, 0x82, 0xad, 0xf6}}, + {{0xc6, 0x87, 0x8a, 0x2a, 0xea, 0xc0, 0xa9, 0xec, + 0x6d, 0xd3, 0xdc, 0x32, 0x23, 0xce, 0x62, 0x19, + 0xa4, 0x7e, 0xa8, 0xdd, 0x1c, 0x33, 0xae, 0xd3, + 0x4f, 0x62, 0x9f, 0x52, 0xe7, 0x65, 0x46, 0xf4}, + {0x97, 0x51, 0x27, 0x67, 0x2d, 0xa2, 0x82, 0x87, + 0x98, 0xd3, 0xb6, 0x14, 0x7f, 0x51, 0xd3, 0x9a, + 0x0b, 0xd0, 0x76, 0x81, 0xb2, 0x4f, 0x58, 0x92, + 0xa4, 0x86, 0xa1, 0xa7, 0x09, 0x1d, 0xef, 0x9b}}, + {{0xb3, 0x0f, 0x2b, 0x69, 0x0d, 0x06, 0x90, 0x64, + 0xbd, 0x43, 0x4c, 0x10, 0xe8, 0x98, 0x1c, 0xa3, + 0xe1, 0x68, 0xe9, 0x79, 0x6c, 0x29, 0x51, 0x3f, + 0x41, 0xdc, 0xdf, 0x1f, 0xf3, 0x60, 0xbe, 0x33}, + {0xa1, 0x5f, 0xf7, 0x1d, 0xb4, 0x3e, 0x9b, 0x3c, + 0xe7, 0xbd, 0xb6, 0x06, 0xd5, 0x60, 0x06, 0x6d, + 0x50, 0xd2, 0xf4, 0x1a, 0x31, 0x08, 0xf2, 0xea, + 0x8e, 0xef, 0x5f, 0x7d, 0xb6, 0xd0, 0xc0, 0x27}}, + {{0x62, 0x9a, 0xd9, 0xbb, 0x38, 0x36, 0xce, 0xf7, + 0x5d, 0x2f, 0x13, 0xec, 0xc8, 0x2d, 0x02, 0x8a, + 0x2e, 0x72, 0xf0, 0xe5, 0x15, 0x9d, 0x72, 0xae, + 0xfc, 0xb3, 0x4f, 0x02, 0xea, 0xe1, 0x09, 0xfe}, + {0x00, 0x00, 0x00, 0x00, 0xfa, 0x0a, 0x3d, 0xbc, + 0xad, 0x16, 0x0c, 0xb6, 0xe7, 0x7c, 0x8b, 0x39, + 0x9a, 0x43, 0xbb, 0xe3, 0xc2, 0x55, 0x15, 0x14, + 0x75, 0xac, 0x90, 0x9b, 0x7f, 0x9a, 0x92, 0x00}}, + {{0x8b, 0xac, 0x70, 0x86, 0x29, 0x8f, 0x00, 0x23, + 0x7b, 0x45, 0x30, 0xaa, 0xb8, 0x4c, 0xc7, 0x8d, + 0x4e, 0x47, 0x85, 0xc6, 0x19, 0xe3, 0x96, 0xc2, + 0x9a, 0xa0, 0x12, 0xed, 0x6f, 0xd7, 0x76, 0x16}, + {0x45, 0xaf, 0x7e, 0x33, 0xc7, 0x7f, 0x10, 0x6c, + 0x7c, 0x9f, 0x29, 0xc1, 0xa8, 0x7e, 0x15, 0x84, + 0xe7, 0x7d, 0xc0, 0x6d, 0xab, 0x71, 0x5d, 0xd0, + 0x6b, 0x9f, 0x97, 0xab, 0xcb, 0x51, 0x0c, 0x9f}}, + {{0x9e, 0xc3, 0x92, 0xb4, 0x04, 0x9f, 0xc8, 0xbb, + 0xdd, 0x9e, 0xc6, 0x05, 0xfd, 0x65, 0xec, 0x94, + 0x7f, 0x2c, 0x16, 0xc4, 0x40, 0xac, 0x63, 0x7b, + 0x7d, 0xb8, 0x0c, 0xe4, 0x5b, 0xe3, 0xa7, 0x0e}, + {0x43, 0xf4, 0x44, 0xe8, 0xcc, 0xc8, 0xd4, 0x54, + 0x33, 0x37, 0x50, 0xf2, 0x87, 0x42, 0x2e, 0x00, + 0x49, 0x60, 0x62, 0x02, 0xfd, 0x1a, 0x7c, 0xdb, + 0x29, 0x6c, 0x6d, 0x54, 0x53, 0x08, 0xd1, 0xc8}}, + {{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}, + {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}}, + {{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}, + {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}}, + {{0x27, 0x59, 0xc7, 0x35, 0x60, 0x71, 0xa6, 0xf1, + 0x79, 0xa5, 0xfd, 0x79, 0x16, 0xf3, 0x41, 0xf0, + 0x57, 0xb4, 0x02, 0x97, 0x32, 0xe7, 0xde, 0x59, + 0xe2, 0x2d, 0x9b, 0x11, 0xea, 0x2c, 0x35, 0x92}, + {0x27, 0x59, 0xc7, 0x35, 0x60, 0x71, 0xa6, 0xf1, + 0x79, 0xa5, 0xfd, 0x79, 0x16, 0xf3, 0x41, 0xf0, + 0x57, 0xb4, 0x02, 0x97, 0x32, 0xe7, 0xde, 0x59, + 0xe2, 0x2d, 0x9b, 0x11, 0xea, 0x2c, 0x35, 0x92}}, + {{0x28, 0x56, 0xac, 0x0e, 0x4f, 0x98, 0x09, 0xf0, + 0x49, 0xfa, 0x7f, 0x84, 0xac, 0x7e, 0x50, 0x5b, + 0x17, 0x43, 0x14, 0x89, 0x9c, 0x53, 0xa8, 0x94, + 0x30, 0xf2, 0x11, 0x4d, 0x92, 0x14, 0x27, 0xe8}, + {0x39, 0x7a, 0x84, 0x56, 0x79, 0x9d, 0xec, 0x26, + 0x2c, 0x53, 0xc1, 0x94, 0xc9, 0x8d, 0x9e, 0x9d, + 0x32, 0x1f, 0xdd, 0x84, 0x04, 0xe8, 0xe2, 0x0a, + 0x6b, 0xbe, 0xbb, 0x42, 0x40, 0x67, 0x30, 0x6c}}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x45, 0x51, 0x23, 0x19, 0x50, 0xb7, 0x5f, 0xc4, + 0x40, 0x2d, 0xa1, 0x73, 0x2f, 0xc9, 0xbe, 0xbd}, + {0x27, 0x59, 0xc7, 0x35, 0x60, 0x71, 0xa6, 0xf1, + 0x79, 0xa5, 0xfd, 0x79, 0x16, 0xf3, 0x41, 0xf0, + 0x57, 0xb4, 0x02, 0x97, 0x32, 0xe7, 0xde, 0x59, + 0xe2, 0x2d, 0x9b, 0x11, 0xea, 0x2c, 0x35, 0x92}}, + {{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}, + {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}}, + {{0x1c, 0xc4, 0xf7, 0xda, 0x0f, 0x65, 0xca, 0x39, + 0x70, 0x52, 0x92, 0x8e, 0xc3, 0xc8, 0x15, 0xea, + 0x7f, 0x10, 0x9e, 0x77, 0x4b, 0x6e, 0x2d, 0xdf, + 0xe8, 0x30, 0x9d, 0xda, 0xe8, 0x9a, 0x65, 0xae}, + {0x02, 0xb0, 0x16, 0xb1, 0x1d, 0xc8, 0x57, 0x7b, + 0xa2, 0x3a, 0xa2, 0xa3, 0x38, 0x5c, 0x8f, 0xeb, + 0x66, 0x37, 0x91, 0xa8, 0x5f, 0xef, 0x04, 0xf6, + 0x59, 0x75, 0xe1, 0xee, 0x92, 0xf6, 0x0e, 0x30}}, + {{0x8d, 0x76, 0x14, 0xa4, 0x14, 0x06, 0x9f, 0x9a, + 0xdf, 0x4a, 0x85, 0xa7, 0x6b, 0xbf, 0x29, 0x6f, + 0xbc, 0x34, 0x87, 0x5d, 0xeb, 0xbb, 0x2e, 0xa9, + 0xc9, 0x1f, 0x58, 0xd6, 0x9a, 0x82, 0xa0, 0x56}, + {0xd4, 0xb9, 0xdb, 0x88, 0x1d, 0x04, 0xe9, 0x93, + 0x8d, 0x3f, 0x20, 0xd5, 0x86, 0xa8, 0x83, 0x07, + 0xdb, 0x09, 0xd8, 0x22, 0x1f, 0x7f, 0xf1, 0x71, + 0xc8, 0xe7, 0x5d, 0x47, 0xaf, 0x8b, 0x72, 0xe9}}, + {{0x83, 0xb9, 0x39, 0xb2, 0xa4, 0xdf, 0x46, 0x87, + 0xc2, 0xb8, 0xf1, 0xe6, 0x4c, 0xd1, 0xe2, 0xa9, + 0xe4, 0x70, 0x30, 0x34, 0xbc, 0x52, 0x7c, 0x55, + 0xa6, 0xec, 0x80, 0xa4, 0xe5, 0xd2, 0xdc, 0x73}, + {0x08, 0xf1, 0x03, 0xcf, 0x16, 0x73, 0xe8, 0x7d, + 0xb6, 0x7e, 0x9b, 0xc0, 0xb4, 0xc2, 0xa5, 0x86, + 0x02, 0x77, 0xd5, 0x27, 0x86, 0xa5, 0x15, 0xfb, + 0xae, 0x9b, 0x8c, 0xa9, 0xf9, 0xf8, 0xa8, 0x4a}}, + {{0x8b, 0x00, 0x49, 0xdb, 0xfa, 0xf0, 0x1b, 0xa2, + 0xed, 0x8a, 0x9a, 0x7a, 0x36, 0x78, 0x4a, 0xc7, + 0xf7, 0xad, 0x39, 0xd0, 0x6c, 0x65, 0x7a, 0x41, + 0xce, 0xd6, 0xd6, 0x4c, 0x20, 0x21, 0x6b, 0xc7}, + {0xc6, 0xca, 0x78, 0x1d, 0x32, 0x6c, 0x6c, 0x06, + 0x91, 0xf2, 0x1a, 0xe8, 0x43, 0x16, 0xea, 0x04, + 0x3c, 0x1f, 0x07, 0x85, 0xf7, 0x09, 0x22, 0x08, + 0xba, 0x13, 0xfd, 0x78, 0x1e, 0x3f, 0x6f, 0x62}}, + {{0x25, 0x9b, 0x7c, 0xb0, 0xac, 0x72, 0x6f, 0xb2, + 0xe3, 0x53, 0x84, 0x7a, 0x1a, 0x9a, 0x98, 0x9b, + 0x44, 0xd3, 0x59, 0xd0, 0x8e, 0x57, 0x41, 0x40, + 0x78, 0xa7, 0x30, 0x2f, 0x4c, 0x9c, 0xb9, 0x68}, + {0xb7, 0x75, 0x03, 0x63, 0x61, 0xc2, 0x48, 0x6e, + 0x12, 0x3d, 0xbf, 0x4b, 0x27, 0xdf, 0xb1, 0x7a, + 0xff, 0x4e, 0x31, 0x07, 0x83, 0xf4, 0x62, 0x5b, + 0x19, 0xa5, 0xac, 0xa0, 0x32, 0x58, 0x0d, 0xa7}}, + {{0x43, 0x4f, 0x10, 0xa4, 0xca, 0xdb, 0x38, 0x67, + 0xfa, 0xae, 0x96, 0xb5, 0x6d, 0x97, 0xff, 0x1f, + 0xb6, 0x83, 0x43, 0xd3, 0xa0, 0x2d, 0x70, 0x7a, + 0x64, 0x05, 0x4c, 0xa7, 0xc1, 0xa5, 0x21, 0x51}, + {0xe4, 0xf1, 0x23, 0x84, 0xe1, 0xb5, 0x9d, 0xf2, + 0xb8, 0x73, 0x8b, 0x45, 0x2b, 0x35, 0x46, 0x38, + 0x10, 0x2b, 0x50, 0xf8, 0x8b, 0x35, 0xcd, 0x34, + 0xc8, 0x0e, 0xf6, 0xdb, 0x09, 0x35, 0xf0, 0xda}} + }; + secp256k1_scalar_set_int(&one, 1); + for (i = 0; i < 32; i++) { + secp256k1_scalar_set_b32(&x, chal[i][0], &overflow); + CHECK(!overflow); + secp256k1_scalar_set_b32(&y, chal[i][1], &overflow); + CHECK(!overflow); + secp256k1_scalar_set_b32(&r1, res[i][0], &overflow); + CHECK(!overflow); + secp256k1_scalar_set_b32(&r2, res[i][1], &overflow); + CHECK(!overflow); + secp256k1_scalar_mul(&z, &x, &y); + CHECK(!secp256k1_scalar_check_overflow(&z)); + CHECK(secp256k1_scalar_eq(&r1, &z)); + if (!secp256k1_scalar_is_zero(&y)) { + secp256k1_scalar_inverse(&zz, &y); + CHECK(!secp256k1_scalar_check_overflow(&zz)); +#if defined(USE_SCALAR_INV_NUM) + secp256k1_scalar_inverse_var(&zzv, &y); + CHECK(secp256k1_scalar_eq(&zzv, &zz)); +#endif + secp256k1_scalar_mul(&z, &z, &zz); + CHECK(!secp256k1_scalar_check_overflow(&z)); + CHECK(secp256k1_scalar_eq(&x, &z)); + secp256k1_scalar_mul(&zz, &zz, &y); + CHECK(!secp256k1_scalar_check_overflow(&zz)); + CHECK(secp256k1_scalar_eq(&one, &zz)); + } + secp256k1_scalar_mul(&z, &x, &x); + CHECK(!secp256k1_scalar_check_overflow(&z)); + secp256k1_scalar_sqr(&zz, &x); + CHECK(!secp256k1_scalar_check_overflow(&zz)); + CHECK(secp256k1_scalar_eq(&zz, &z)); + CHECK(secp256k1_scalar_eq(&r2, &zz)); + } + } } /***** FIELD TESTS *****/ -void random_fe(secp256k1_fe_t *x) { +void random_fe(secp256k1_fe *x) { unsigned char bin[32]; do { secp256k1_rand256(bin); @@ -671,7 +1420,17 @@ void random_fe(secp256k1_fe_t *x) { } while(1); } -void random_fe_non_zero(secp256k1_fe_t *nz) { +void random_fe_test(secp256k1_fe *x) { + unsigned char bin[32]; + do { + secp256k1_rand256_test(bin); + if (secp256k1_fe_set_b32(x, bin)) { + return; + } + } while(1); +} + +void random_fe_non_zero(secp256k1_fe *nz) { int tries = 10; while (--tries >= 0) { random_fe(nz); @@ -684,25 +1443,25 @@ void random_fe_non_zero(secp256k1_fe_t *nz) { CHECK(tries >= 0); } -void random_fe_non_square(secp256k1_fe_t *ns) { - secp256k1_fe_t r; +void random_fe_non_square(secp256k1_fe *ns) { + secp256k1_fe r; random_fe_non_zero(ns); 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_t bn = *b; +int check_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) { + secp256k1_fe an = *a; + secp256k1_fe bn = *b; secp256k1_fe_normalize_weak(&an); secp256k1_fe_normalize_var(&bn); return secp256k1_fe_equal_var(&an, &bn); } -int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) { - secp256k1_fe_t x; - secp256k1_fe_t one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); +int check_fe_inverse(const secp256k1_fe *a, const secp256k1_fe *ai) { + secp256k1_fe x; + secp256k1_fe one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); secp256k1_fe_mul(&x, a, ai); return check_fe_equal(&x, &one); } @@ -714,17 +1473,17 @@ void run_field_convert(void) { 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40 }; - static const secp256k1_fe_storage_t fes = SECP256K1_FE_STORAGE_CONST( + static const secp256k1_fe_storage fes = SECP256K1_FE_STORAGE_CONST( 0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL, 0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL ); - static const secp256k1_fe_t fe = SECP256K1_FE_CONST( + static const secp256k1_fe fe = SECP256K1_FE_CONST( 0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL, 0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL ); - secp256k1_fe_t fe2; + secp256k1_fe fe2; unsigned char b322[32]; - secp256k1_fe_storage_t fes2; + secp256k1_fe_storage fes2; /* Check conversions to fe. */ CHECK(secp256k1_fe_set_b32(&fe2, b32)); CHECK(secp256k1_fe_equal_var(&fe, &fe2)); @@ -737,15 +1496,24 @@ void run_field_convert(void) { CHECK(memcmp(&fes2, &fes, sizeof(fes)) == 0); } +int fe_memcmp(const secp256k1_fe *a, const secp256k1_fe *b) { + secp256k1_fe t = *b; +#ifdef VERIFY + t.magnitude = a->magnitude; + t.normalized = a->normalized; +#endif + return memcmp(a, &t, sizeof(secp256k1_fe)); +} + void run_field_misc(void) { - secp256k1_fe_t x; - secp256k1_fe_t y; - secp256k1_fe_t z; - secp256k1_fe_t q; - secp256k1_fe_t fe5 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 5); - int i; + secp256k1_fe x; + secp256k1_fe y; + secp256k1_fe z; + secp256k1_fe q; + secp256k1_fe fe5 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 5); + int i, j; for (i = 0; i < 5*count; i++) { - secp256k1_fe_storage_t xs, ys, zs; + secp256k1_fe_storage xs, ys, zs; random_fe(&x); random_fe_non_zero(&y); /* Test the fe equality and comparison operations. */ @@ -756,14 +1524,27 @@ void run_field_misc(void) { /* Test fe conditional move; z is not normalized here. */ q = x; secp256k1_fe_cmov(&x, &z, 0); + VERIFY_CHECK(!x.normalized && x.magnitude == z.magnitude); secp256k1_fe_cmov(&x, &x, 1); - CHECK(memcmp(&x, &z, sizeof(x)) != 0); - CHECK(memcmp(&x, &q, sizeof(x)) == 0); + CHECK(fe_memcmp(&x, &z) != 0); + CHECK(fe_memcmp(&x, &q) == 0); secp256k1_fe_cmov(&q, &z, 1); - CHECK(memcmp(&q, &z, sizeof(q)) == 0); - /* Test storage conversion and conditional moves. */ - secp256k1_fe_normalize(&z); + VERIFY_CHECK(!q.normalized && q.magnitude == z.magnitude); + CHECK(fe_memcmp(&q, &z) == 0); + secp256k1_fe_normalize_var(&x); + secp256k1_fe_normalize_var(&z); CHECK(!secp256k1_fe_equal_var(&x, &z)); + secp256k1_fe_normalize_var(&q); + secp256k1_fe_cmov(&q, &z, (i&1)); + VERIFY_CHECK(q.normalized && q.magnitude == 1); + for (j = 0; j < 6; j++) { + secp256k1_fe_negate(&z, &z, j+1); + secp256k1_fe_normalize_var(&q); + secp256k1_fe_cmov(&q, &z, (j&1)); + VERIFY_CHECK(!q.normalized && q.magnitude == (j+2)); + } + secp256k1_fe_normalize_var(&z); + /* Test storage conversion and conditional moves. */ secp256k1_fe_to_storage(&xs, &x); secp256k1_fe_to_storage(&ys, &y); secp256k1_fe_to_storage(&zs, &z); @@ -797,7 +1578,7 @@ void run_field_misc(void) { } void run_field_inv(void) { - secp256k1_fe_t x, xi, xii; + secp256k1_fe x, xi, xii; int i; for (i = 0; i < 10*count; i++) { random_fe_non_zero(&x); @@ -809,7 +1590,7 @@ void run_field_inv(void) { } void run_field_inv_var(void) { - secp256k1_fe_t x, xi, xii; + secp256k1_fe x, xi, xii; int i; for (i = 0; i < 10*count; i++) { random_fe_non_zero(&x); @@ -821,13 +1602,13 @@ void run_field_inv_var(void) { } void run_field_inv_all_var(void) { - secp256k1_fe_t x[16], xi[16], xii[16]; + secp256k1_fe x[16], xi[16], xii[16]; int i; /* Check it's safe to call for 0 elements */ secp256k1_fe_inv_all_var(0, xi, x); for (i = 0; i < count; i++) { size_t j; - size_t len = (secp256k1_rand32() & 15) + 1; + size_t len = secp256k1_rand_int(15) + 1; for (j = 0; j < len; j++) { random_fe_non_zero(&x[j]); } @@ -843,7 +1624,7 @@ void run_field_inv_all_var(void) { } void run_sqr(void) { - secp256k1_fe_t x, s; + secp256k1_fe x, s; { int i; @@ -858,8 +1639,8 @@ void run_sqr(void) { } } -void test_sqrt(const secp256k1_fe_t *a, const secp256k1_fe_t *k) { - secp256k1_fe_t r1, r2; +void test_sqrt(const secp256k1_fe *a, const secp256k1_fe *k) { + secp256k1_fe r1, r2; int v = secp256k1_fe_sqrt_var(&r1, a); CHECK((v == 0) == (k == NULL)); @@ -873,7 +1654,7 @@ void test_sqrt(const secp256k1_fe_t *a, const secp256k1_fe_t *k) { } void run_sqrt(void) { - secp256k1_fe_t ns, x, s, t; + secp256k1_fe ns, x, s, t; int i; /* Check sqrt(0) is 0 */ @@ -908,19 +1689,19 @@ void run_sqrt(void) { /***** GROUP TESTS *****/ -void ge_equals_ge(const secp256k1_ge_t *a, const secp256k1_ge_t *b) { +void ge_equals_ge(const secp256k1_ge *a, const secp256k1_ge *b) { CHECK(a->infinity == b->infinity); if (a->infinity) { return; } CHECK(secp256k1_fe_equal_var(&a->x, &b->x)); - CHECK(secp256k1_fe_equal_var(&b->y, &b->y)); + CHECK(secp256k1_fe_equal_var(&a->y, &b->y)); } /* This compares jacobian points including their Z, not just their geometric meaning. */ -int gej_xyz_equals_gej(const secp256k1_gej_t *a, const secp256k1_gej_t *b) { - secp256k1_gej_t a2; - secp256k1_gej_t b2; +int gej_xyz_equals_gej(const secp256k1_gej *a, const secp256k1_gej *b) { + secp256k1_gej a2; + secp256k1_gej b2; int ret = 1; ret &= a->infinity == b->infinity; if (ret && !a->infinity) { @@ -939,9 +1720,9 @@ int gej_xyz_equals_gej(const secp256k1_gej_t *a, const secp256k1_gej_t *b) { return ret; } -void ge_equals_gej(const secp256k1_ge_t *a, const secp256k1_gej_t *b) { - secp256k1_fe_t z2s; - secp256k1_fe_t u1, u2, s1, s2; +void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) { + secp256k1_fe z2s; + secp256k1_fe u1, u2, s1, s2; CHECK(a->infinity == b->infinity); if (a->infinity) { return; @@ -958,21 +1739,39 @@ void ge_equals_gej(const secp256k1_ge_t *a, const secp256k1_gej_t *b) { void test_ge(void) { int i, i1; +#ifdef USE_ENDOMORPHISM + int runs = 6; +#else int runs = 4; +#endif /* Points: (infinity, p1, p1, -p1, -p1, p2, p2, -p2, -p2, p3, p3, -p3, -p3, p4, p4, -p4, -p4). * The second in each pair of identical points uses a random Z coordinate in the Jacobian form. * All magnitudes are randomized. - * All 17*17 combinations of points are added to eachother, using all applicable methods. + * All 17*17 combinations of points are added to each other, using all applicable methods. + * + * When the endomorphism code is compiled in, p5 = lambda*p1 and p6 = lambda^2*p1 are added as well. */ - secp256k1_ge_t *ge = (secp256k1_ge_t *)malloc(sizeof(secp256k1_ge_t) * (1 + 4 * runs)); - secp256k1_gej_t *gej = (secp256k1_gej_t *)malloc(sizeof(secp256k1_gej_t) * (1 + 4 * runs)); + secp256k1_ge *ge = (secp256k1_ge *)malloc(sizeof(secp256k1_ge) * (1 + 4 * runs)); + secp256k1_gej *gej = (secp256k1_gej *)malloc(sizeof(secp256k1_gej) * (1 + 4 * runs)); + secp256k1_fe *zinv = (secp256k1_fe *)malloc(sizeof(secp256k1_fe) * (1 + 4 * runs)); + secp256k1_fe zf; + secp256k1_fe zfi2, zfi3; + secp256k1_gej_set_infinity(&gej[0]); secp256k1_ge_clear(&ge[0]); secp256k1_ge_set_gej_var(&ge[0], &gej[0]); for (i = 0; i < runs; i++) { int j; - secp256k1_ge_t g; + secp256k1_ge g; random_group_element_test(&g); +#ifdef USE_ENDOMORPHISM + if (i >= runs - 2) { + secp256k1_ge_mul_lambda(&g, &ge[1]); + } + if (i >= runs - 1) { + secp256k1_ge_mul_lambda(&g, &g); + } +#endif ge[1 + 4 * i] = g; ge[2 + 4 * i] = g; secp256k1_ge_neg(&ge[3 + 4 * i], &g); @@ -990,18 +1789,65 @@ void test_ge(void) { } } + /* Compute z inverses. */ + { + secp256k1_fe *zs = malloc(sizeof(secp256k1_fe) * (1 + 4 * runs)); + for (i = 0; i < 4 * runs + 1; i++) { + if (i == 0) { + /* The point at infinity does not have a meaningful z inverse. Any should do. */ + do { + random_field_element_test(&zs[i]); + } while(secp256k1_fe_is_zero(&zs[i])); + } else { + zs[i] = gej[i].z; + } + } + secp256k1_fe_inv_all_var(4 * runs + 1, zinv, zs); + free(zs); + } + + /* Generate random zf, and zfi2 = 1/zf^2, zfi3 = 1/zf^3 */ + do { + random_field_element_test(&zf); + } while(secp256k1_fe_is_zero(&zf)); + random_field_element_magnitude(&zf); + secp256k1_fe_inv_var(&zfi3, &zf); + secp256k1_fe_sqr(&zfi2, &zfi3); + secp256k1_fe_mul(&zfi3, &zfi3, &zfi2); + for (i1 = 0; i1 < 1 + 4 * runs; i1++) { int i2; for (i2 = 0; i2 < 1 + 4 * runs; i2++) { /* Compute reference result using gej + gej (var). */ - secp256k1_gej_t refj, resj; - secp256k1_ge_t ref; - secp256k1_gej_add_var(&refj, &gej[i1], &gej[i2]); + secp256k1_gej refj, resj; + secp256k1_ge ref; + secp256k1_fe zr; + secp256k1_gej_add_var(&refj, &gej[i1], &gej[i2], secp256k1_gej_is_infinity(&gej[i1]) ? NULL : &zr); + /* Check Z ratio. */ + if (!secp256k1_gej_is_infinity(&gej[i1]) && !secp256k1_gej_is_infinity(&refj)) { + secp256k1_fe zrz; secp256k1_fe_mul(&zrz, &zr, &gej[i1].z); + CHECK(secp256k1_fe_equal_var(&zrz, &refj.z)); + } secp256k1_ge_set_gej_var(&ref, &refj); - /* Test gej + ge (var). */ - secp256k1_gej_add_ge_var(&resj, &gej[i1], &ge[i2]); + /* Test gej + ge with Z ratio result (var). */ + secp256k1_gej_add_ge_var(&resj, &gej[i1], &ge[i2], secp256k1_gej_is_infinity(&gej[i1]) ? NULL : &zr); ge_equals_gej(&ref, &resj); + if (!secp256k1_gej_is_infinity(&gej[i1]) && !secp256k1_gej_is_infinity(&resj)) { + secp256k1_fe zrz; secp256k1_fe_mul(&zrz, &zr, &gej[i1].z); + CHECK(secp256k1_fe_equal_var(&zrz, &resj.z)); + } + + /* Test gej + ge (var, with additional Z factor). */ + { + secp256k1_ge ge2_zfi = ge[i2]; /* the second term with x and y rescaled for z = 1/zf */ + secp256k1_fe_mul(&ge2_zfi.x, &ge2_zfi.x, &zfi2); + secp256k1_fe_mul(&ge2_zfi.y, &ge2_zfi.y, &zfi3); + random_field_element_magnitude(&ge2_zfi.x); + random_field_element_magnitude(&ge2_zfi.y); + secp256k1_gej_add_zinv_var(&resj, &gej[i1], &ge2_zfi, &zf); + ge_equals_gej(&ref, &resj); + } /* Test gej + ge (const). */ if (i2 != 0) { @@ -1012,10 +1858,15 @@ void test_ge(void) { /* Test doubling (var). */ if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 == ((i2 + 3)%4)/2)) { - /* Normal doubling. */ - secp256k1_gej_double_var(&resj, &gej[i1]); + secp256k1_fe zr2; + /* Normal doubling with Z ratio result. */ + secp256k1_gej_double_var(&resj, &gej[i1], &zr2); ge_equals_gej(&ref, &resj); - secp256k1_gej_double_var(&resj, &gej[i2]); + /* Check Z ratio. */ + secp256k1_fe_mul(&zr2, &zr2, &gej[i1].z); + CHECK(secp256k1_fe_equal_var(&zr2, &resj.z)); + /* Normal doubling. */ + secp256k1_gej_double_var(&resj, &gej[i2], NULL); ge_equals_gej(&ref, &resj); } @@ -1040,41 +1891,121 @@ void test_ge(void) { /* Test adding all points together in random order equals infinity. */ { - secp256k1_gej_t sum = SECP256K1_GEJ_CONST_INFINITY; - secp256k1_gej_t *gej_shuffled = (secp256k1_gej_t *)malloc((4 * runs + 1) * sizeof(secp256k1_gej_t)); + secp256k1_gej sum = SECP256K1_GEJ_CONST_INFINITY; + secp256k1_gej *gej_shuffled = (secp256k1_gej *)malloc((4 * runs + 1) * sizeof(secp256k1_gej)); for (i = 0; i < 4 * runs + 1; i++) { gej_shuffled[i] = gej[i]; } for (i = 0; i < 4 * runs + 1; i++) { - int swap = i + secp256k1_rand32() % (4 * runs + 1 - i); + int swap = i + secp256k1_rand_int(4 * runs + 1 - i); if (swap != i) { - secp256k1_gej_t t = gej_shuffled[i]; + secp256k1_gej t = gej_shuffled[i]; gej_shuffled[i] = gej_shuffled[swap]; gej_shuffled[swap] = t; } } for (i = 0; i < 4 * runs + 1; i++) { - secp256k1_gej_add_var(&sum, &sum, &gej_shuffled[i]); + secp256k1_gej_add_var(&sum, &sum, &gej_shuffled[i], NULL); } CHECK(secp256k1_gej_is_infinity(&sum)); free(gej_shuffled); } - /* Test batch gej -> ge conversion. */ + /* Test batch gej -> ge conversion with and without known z ratios. */ { - secp256k1_ge_t *ge_set_all = (secp256k1_ge_t *)malloc((4 * runs + 1) * sizeof(secp256k1_ge_t)); - secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej); + secp256k1_fe *zr = (secp256k1_fe *)malloc((4 * runs + 1) * sizeof(secp256k1_fe)); + secp256k1_ge *ge_set_table = (secp256k1_ge *)malloc((4 * runs + 1) * sizeof(secp256k1_ge)); + secp256k1_ge *ge_set_all = (secp256k1_ge *)malloc((4 * runs + 1) * sizeof(secp256k1_ge)); for (i = 0; i < 4 * runs + 1; i++) { - secp256k1_fe_t s; + /* Compute gej[i + 1].z / gez[i].z (with gej[n].z taken to be 1). */ + if (i < 4 * runs) { + secp256k1_fe_mul(&zr[i + 1], &zinv[i], &gej[i + 1].z); + } + } + secp256k1_ge_set_table_gej_var(4 * runs + 1, ge_set_table, gej, zr); + secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej, &ctx->error_callback); + for (i = 0; i < 4 * runs + 1; i++) { + secp256k1_fe s; random_fe_non_zero(&s); secp256k1_gej_rescale(&gej[i], &s); + ge_equals_gej(&ge_set_table[i], &gej[i]); ge_equals_gej(&ge_set_all[i], &gej[i]); } + free(ge_set_table); free(ge_set_all); + free(zr); } free(ge); free(gej); + free(zinv); +} + +void test_add_neg_y_diff_x(void) { + /* The point of this test is to check that we can add two points + * whose y-coordinates are negatives of each other but whose x + * coordinates differ. If the x-coordinates were the same, these + * points would be negatives of each other and their sum is + * infinity. This is cool because it "covers up" any degeneracy + * in the addition algorithm that would cause the xy coordinates + * of the sum to be wrong (since infinity has no xy coordinates). + * HOWEVER, if the x-coordinates are different, infinity is the + * wrong answer, and such degeneracies are exposed. This is the + * root of https://github.com/bitcoin/secp256k1/issues/257 which + * this test is a regression test for. + * + * These points were generated in sage as + * # secp256k1 params + * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) + * C = EllipticCurve ([F (0), F (7)]) + * G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798) + * N = FiniteField(G.order()) + * + * # endomorphism values (lambda is 1^{1/3} in N, beta is 1^{1/3} in F) + * x = polygen(N) + * lam = (1 - x^3).roots()[1][0] + * + * # random "bad pair" + * P = C.random_element() + * Q = -int(lam) * P + * print " P: %x %x" % P.xy() + * print " Q: %x %x" % Q.xy() + * print "P + Q: %x %x" % (P + Q).xy() + */ + secp256k1_gej aj = SECP256K1_GEJ_CONST( + 0x8d24cd95, 0x0a355af1, 0x3c543505, 0x44238d30, + 0x0643d79f, 0x05a59614, 0x2f8ec030, 0xd58977cb, + 0x001e337a, 0x38093dcd, 0x6c0f386d, 0x0b1293a8, + 0x4d72c879, 0xd7681924, 0x44e6d2f3, 0x9190117d + ); + secp256k1_gej bj = SECP256K1_GEJ_CONST( + 0xc7b74206, 0x1f788cd9, 0xabd0937d, 0x164a0d86, + 0x95f6ff75, 0xf19a4ce9, 0xd013bd7b, 0xbf92d2a7, + 0xffe1cc85, 0xc7f6c232, 0x93f0c792, 0xf4ed6c57, + 0xb28d3786, 0x2897e6db, 0xbb192d0b, 0x6e6feab2 + ); + secp256k1_gej sumj = SECP256K1_GEJ_CONST( + 0x671a63c0, 0x3efdad4c, 0x389a7798, 0x24356027, + 0xb3d69010, 0x278625c3, 0x5c86d390, 0x184a8f7a, + 0x5f6409c2, 0x2ce01f2b, 0x511fd375, 0x25071d08, + 0xda651801, 0x70e95caf, 0x8f0d893c, 0xbed8fbbe + ); + secp256k1_ge b; + secp256k1_gej resj; + secp256k1_ge res; + secp256k1_ge_set_gej(&b, &bj); + + secp256k1_gej_add_var(&resj, &aj, &bj, NULL); + secp256k1_ge_set_gej(&res, &resj); + ge_equals_gej(&res, &sumj); + + secp256k1_gej_add_ge(&resj, &aj, &b); + secp256k1_ge_set_gej(&res, &resj); + ge_equals_gej(&res, &sumj); + + secp256k1_gej_add_ge_var(&resj, &aj, &b, NULL); + secp256k1_ge_set_gej(&res, &resj); + ge_equals_gej(&res, &sumj); } void run_ge(void) { @@ -1082,36 +2013,125 @@ void run_ge(void) { for (i = 0; i < count * 32; i++) { test_ge(); } + test_add_neg_y_diff_x(); +} + +void test_ec_combine(void) { + secp256k1_scalar sum = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + secp256k1_pubkey data[6]; + const secp256k1_pubkey* d[6]; + secp256k1_pubkey sd; + secp256k1_pubkey sd2; + secp256k1_gej Qj; + secp256k1_ge Q; + int i; + for (i = 1; i <= 6; i++) { + secp256k1_scalar s; + random_scalar_order_test(&s); + secp256k1_scalar_add(&sum, &sum, &s); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &s); + secp256k1_ge_set_gej(&Q, &Qj); + secp256k1_pubkey_save(&data[i - 1], &Q); + d[i - 1] = &data[i - 1]; + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &sum); + secp256k1_ge_set_gej(&Q, &Qj); + secp256k1_pubkey_save(&sd, &Q); + CHECK(secp256k1_ec_pubkey_combine(ctx, &sd2, d, i) == 1); + CHECK(memcmp(&sd, &sd2, sizeof(sd)) == 0); + } +} + +void run_ec_combine(void) { + int i; + for (i = 0; i < count * 8; i++) { + test_ec_combine(); + } +} + +void test_group_decompress(const secp256k1_fe* x) { + /* The input itself, normalized. */ + secp256k1_fe fex = *x; + secp256k1_fe tmp; + /* Results of set_xquad_var, set_xo_var(..., 0), set_xo_var(..., 1). */ + secp256k1_ge ge_quad, ge_even, ge_odd; + /* Return values of the above calls. */ + int res_quad, res_even, res_odd; + + secp256k1_fe_normalize_var(&fex); + + res_quad = secp256k1_ge_set_xquad_var(&ge_quad, &fex); + res_even = secp256k1_ge_set_xo_var(&ge_even, &fex, 0); + res_odd = secp256k1_ge_set_xo_var(&ge_odd, &fex, 1); + + CHECK(res_quad == res_even); + CHECK(res_quad == res_odd); + + if (res_quad) { + secp256k1_fe_normalize_var(&ge_quad.x); + secp256k1_fe_normalize_var(&ge_odd.x); + secp256k1_fe_normalize_var(&ge_even.x); + secp256k1_fe_normalize_var(&ge_quad.y); + secp256k1_fe_normalize_var(&ge_odd.y); + secp256k1_fe_normalize_var(&ge_even.y); + + /* No infinity allowed. */ + CHECK(!ge_quad.infinity); + CHECK(!ge_even.infinity); + CHECK(!ge_odd.infinity); + + /* Check that the x coordinates check out. */ + CHECK(secp256k1_fe_equal_var(&ge_quad.x, x)); + CHECK(secp256k1_fe_equal_var(&ge_even.x, x)); + CHECK(secp256k1_fe_equal_var(&ge_odd.x, x)); + + /* Check that the Y coordinate result in ge_quad is a square. */ + CHECK(secp256k1_fe_sqrt_var(&tmp, &ge_quad.y)); + secp256k1_fe_sqr(&tmp, &tmp); + CHECK(secp256k1_fe_equal_var(&tmp, &ge_quad.y)); + + /* Check odd/even Y in ge_odd, ge_even. */ + CHECK(secp256k1_fe_is_odd(&ge_odd.y)); + CHECK(!secp256k1_fe_is_odd(&ge_even.y)); + } +} + +void run_group_decompress(void) { + int i; + for (i = 0; i < count * 4; i++) { + secp256k1_fe fe; + random_fe_test(&fe); + test_group_decompress(&fe); + } } /***** ECMULT TESTS *****/ void run_ecmult_chain(void) { /* random starting point A (on the curve) */ - secp256k1_gej_t a = SECP256K1_GEJ_CONST( + secp256k1_gej a = SECP256K1_GEJ_CONST( 0x8b30bbe9, 0xae2a9906, 0x96b22f67, 0x0709dff3, 0x727fd8bc, 0x04d3362c, 0x6c7bf458, 0xe2846004, 0xa357ae91, 0x5c4a6528, 0x1309edf2, 0x0504740f, 0x0eb33439, 0x90216b4f, 0x81063cb6, 0x5f2f7e0f ); /* two random initial factors xn and gn */ - secp256k1_scalar_t xn = SECP256K1_SCALAR_CONST( + secp256k1_scalar xn = SECP256K1_SCALAR_CONST( 0x84cc5452, 0xf7fde1ed, 0xb4d38a8c, 0xe9b1b84c, 0xcef31f14, 0x6e569be9, 0x705d357a, 0x42985407 ); - secp256k1_scalar_t gn = SECP256K1_SCALAR_CONST( + secp256k1_scalar gn = SECP256K1_SCALAR_CONST( 0xa1e58d22, 0x553dcd42, 0xb2398062, 0x5d4c57a9, 0x6e9323d4, 0x2b3152e5, 0xca2c3990, 0xedc7c9de ); /* two small multipliers to be applied to xn and gn in every iteration: */ - static const secp256k1_scalar_t xf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x1337); - static const secp256k1_scalar_t gf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x7113); + static const secp256k1_scalar xf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x1337); + static const secp256k1_scalar gf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x7113); /* accumulators with the resulting coefficients to A and G */ - secp256k1_scalar_t ae = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_scalar_t ge = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + secp256k1_scalar ae = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); + secp256k1_scalar ge = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); /* actual points */ - secp256k1_gej_t x = a; - secp256k1_gej_t x2; + secp256k1_gej x; + secp256k1_gej x2; int i; /* the point being computed */ @@ -1131,7 +2151,7 @@ void run_ecmult_chain(void) { /* verify */ if (i == 19999) { /* expected result after 19999 iterations */ - secp256k1_gej_t rp = SECP256K1_GEJ_CONST( + secp256k1_gej rp = SECP256K1_GEJ_CONST( 0xD6E96687, 0xF9B10D09, 0x2A6F3543, 0x9D86CEBE, 0xA4535D0D, 0x409F5358, 0x6440BD74, 0xB933E830, 0xB95CBCA2, 0xC77DA786, 0x539BE8FD, 0x53354D2D, @@ -1139,30 +2159,32 @@ void run_ecmult_chain(void) { ); secp256k1_gej_neg(&rp, &rp); - secp256k1_gej_add_var(&rp, &rp, &x); + secp256k1_gej_add_var(&rp, &rp, &x, NULL); CHECK(secp256k1_gej_is_infinity(&rp)); } } /* redo the computation, but directly with the resulting ae and ge coefficients: */ secp256k1_ecmult(&ctx->ecmult_ctx, &x2, &a, &ae, &ge); secp256k1_gej_neg(&x2, &x2); - secp256k1_gej_add_var(&x2, &x2, &x); + secp256k1_gej_add_var(&x2, &x2, &x, NULL); CHECK(secp256k1_gej_is_infinity(&x2)); } -void test_point_times_order(const secp256k1_gej_t *point) { +void test_point_times_order(const secp256k1_gej *point) { /* X * (point + G) + (order-X) * (pointer + G) = 0 */ - secp256k1_scalar_t x; - secp256k1_scalar_t nx; - secp256k1_gej_t res1, res2; - secp256k1_ge_t res3; + secp256k1_scalar x; + secp256k1_scalar nx; + secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + secp256k1_scalar one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); + secp256k1_gej res1, res2; + secp256k1_ge res3; unsigned char pub[65]; - int psize = 65; + size_t psize = 65; random_scalar_order_test(&x); secp256k1_scalar_negate(&nx, &x); secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &x, &x); /* calc res1 = x * point + x * G; */ secp256k1_ecmult(&ctx->ecmult_ctx, &res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */ - secp256k1_gej_add_var(&res1, &res1, &res2); + secp256k1_gej_add_var(&res1, &res1, &res2, NULL); CHECK(secp256k1_gej_is_infinity(&res1)); CHECK(secp256k1_gej_is_valid_var(&res1) == 0); secp256k1_ge_set_gej(&res3, &res1); @@ -1171,19 +2193,29 @@ void test_point_times_order(const secp256k1_gej_t *point) { CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 0) == 0); psize = 65; CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 1) == 0); + /* check zero/one edge cases */ + secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &zero, &zero); + secp256k1_ge_set_gej(&res3, &res1); + CHECK(secp256k1_ge_is_infinity(&res3)); + secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &one, &zero); + secp256k1_ge_set_gej(&res3, &res1); + ge_equals_gej(&res3, point); + secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &zero, &one); + secp256k1_ge_set_gej(&res3, &res1); + ge_equals_ge(&res3, &secp256k1_ge_const_g); } void run_point_times_order(void) { int i; - secp256k1_fe_t x = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 2); - static const secp256k1_fe_t xr = SECP256K1_FE_CONST( + secp256k1_fe x = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 2); + static const secp256k1_fe xr = SECP256K1_FE_CONST( 0x7603CB59, 0xB0EF6C63, 0xFE608479, 0x2A0C378C, 0xDB3233A8, 0x0F8A9A09, 0xA877DEAD, 0x31B38C45 ); for (i = 0; i < 500; i++) { - secp256k1_ge_t p; + secp256k1_ge p; if (secp256k1_ge_set_xo_var(&p, &x, 1)) { - secp256k1_gej_t j; + secp256k1_gej j; CHECK(secp256k1_ge_is_valid_var(&p)); secp256k1_gej_set_ge(&j, &p); CHECK(secp256k1_gej_is_valid_var(&j)); @@ -1195,15 +2227,118 @@ void run_point_times_order(void) { CHECK(secp256k1_fe_equal_var(&x, &xr)); } -void test_wnaf(const secp256k1_scalar_t *number, int w) { - secp256k1_scalar_t x, two, t; +void ecmult_const_random_mult(void) { + /* random starting point A (on the curve) */ + secp256k1_ge a = SECP256K1_GE_CONST( + 0x6d986544, 0x57ff52b8, 0xcf1b8126, 0x5b802a5b, + 0xa97f9263, 0xb1e88044, 0x93351325, 0x91bc450a, + 0x535c59f7, 0x325e5d2b, 0xc391fbe8, 0x3c12787c, + 0x337e4a98, 0xe82a9011, 0x0123ba37, 0xdd769c7d + ); + /* random initial factor xn */ + secp256k1_scalar xn = SECP256K1_SCALAR_CONST( + 0x649d4f77, 0xc4242df7, 0x7f2079c9, 0x14530327, + 0xa31b876a, 0xd2d8ce2a, 0x2236d5c6, 0xd7b2029b + ); + /* expected xn * A (from sage) */ + secp256k1_ge expected_b = SECP256K1_GE_CONST( + 0x23773684, 0x4d209dc7, 0x098a786f, 0x20d06fcd, + 0x070a38bf, 0xc11ac651, 0x03004319, 0x1e2a8786, + 0xed8c3b8e, 0xc06dd57b, 0xd06ea66e, 0x45492b0f, + 0xb84e4e1b, 0xfb77e21f, 0x96baae2a, 0x63dec956 + ); + secp256k1_gej b; + secp256k1_ecmult_const(&b, &a, &xn); + + CHECK(secp256k1_ge_is_valid_var(&a)); + ge_equals_gej(&expected_b, &b); +} + +void ecmult_const_commutativity(void) { + secp256k1_scalar a; + secp256k1_scalar b; + secp256k1_gej res1; + secp256k1_gej res2; + secp256k1_ge mid1; + secp256k1_ge mid2; + random_scalar_order_test(&a); + random_scalar_order_test(&b); + + secp256k1_ecmult_const(&res1, &secp256k1_ge_const_g, &a); + secp256k1_ecmult_const(&res2, &secp256k1_ge_const_g, &b); + secp256k1_ge_set_gej(&mid1, &res1); + secp256k1_ge_set_gej(&mid2, &res2); + secp256k1_ecmult_const(&res1, &mid1, &b); + secp256k1_ecmult_const(&res2, &mid2, &a); + secp256k1_ge_set_gej(&mid1, &res1); + secp256k1_ge_set_gej(&mid2, &res2); + ge_equals_ge(&mid1, &mid2); +} + +void ecmult_const_mult_zero_one(void) { + secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + secp256k1_scalar one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); + secp256k1_scalar negone; + secp256k1_gej res1; + secp256k1_ge res2; + secp256k1_ge point; + secp256k1_scalar_negate(&negone, &one); + + random_group_element_test(&point); + secp256k1_ecmult_const(&res1, &point, &zero); + secp256k1_ge_set_gej(&res2, &res1); + CHECK(secp256k1_ge_is_infinity(&res2)); + secp256k1_ecmult_const(&res1, &point, &one); + secp256k1_ge_set_gej(&res2, &res1); + ge_equals_ge(&res2, &point); + secp256k1_ecmult_const(&res1, &point, &negone); + secp256k1_gej_neg(&res1, &res1); + secp256k1_ge_set_gej(&res2, &res1); + ge_equals_ge(&res2, &point); +} + +void ecmult_const_chain_multiply(void) { + /* Check known result (randomly generated test problem from sage) */ + const secp256k1_scalar scalar = SECP256K1_SCALAR_CONST( + 0x4968d524, 0x2abf9b7a, 0x466abbcf, 0x34b11b6d, + 0xcd83d307, 0x827bed62, 0x05fad0ce, 0x18fae63b + ); + const secp256k1_gej expected_point = SECP256K1_GEJ_CONST( + 0x5494c15d, 0x32099706, 0xc2395f94, 0x348745fd, + 0x757ce30e, 0x4e8c90fb, 0xa2bad184, 0xf883c69f, + 0x5d195d20, 0xe191bf7f, 0x1be3e55f, 0x56a80196, + 0x6071ad01, 0xf1462f66, 0xc997fa94, 0xdb858435 + ); + secp256k1_gej point; + secp256k1_ge res; + int i; + + secp256k1_gej_set_ge(&point, &secp256k1_ge_const_g); + for (i = 0; i < 100; ++i) { + secp256k1_ge tmp; + secp256k1_ge_set_gej(&tmp, &point); + secp256k1_ecmult_const(&point, &tmp, &scalar); + } + secp256k1_ge_set_gej(&res, &point); + ge_equals_gej(&res, &expected_point); +} + +void run_ecmult_const_tests(void) { + ecmult_const_mult_zero_one(); + ecmult_const_random_mult(); + ecmult_const_commutativity(); + ecmult_const_chain_multiply(); +} + +void test_wnaf(const secp256k1_scalar *number, int w) { + secp256k1_scalar x, two, t; int wnaf[256]; int zeroes = -1; int i; int bits; secp256k1_scalar_set_int(&x, 0); secp256k1_scalar_set_int(&two, 2); - bits = secp256k1_ecmult_wnaf(wnaf, number, w); + bits = secp256k1_ecmult_wnaf(wnaf, 256, number, w); CHECK(bits <= 256); for (i = bits-1; i >= 0; i--) { int v = wnaf[i]; @@ -1229,20 +2364,95 @@ void test_wnaf(const secp256k1_scalar_t *number, int w) { CHECK(secp256k1_scalar_eq(&x, number)); /* check that wnaf represents number */ } +void test_constant_wnaf_negate(const secp256k1_scalar *number) { + secp256k1_scalar neg1 = *number; + secp256k1_scalar neg2 = *number; + int sign1 = 1; + int sign2 = 1; + + if (!secp256k1_scalar_get_bits(&neg1, 0, 1)) { + secp256k1_scalar_negate(&neg1, &neg1); + sign1 = -1; + } + sign2 = secp256k1_scalar_cond_negate(&neg2, secp256k1_scalar_is_even(&neg2)); + CHECK(sign1 == sign2); + CHECK(secp256k1_scalar_eq(&neg1, &neg2)); +} + +void test_constant_wnaf(const secp256k1_scalar *number, int w) { + secp256k1_scalar x, shift; + int wnaf[256] = {0}; + int i; +#ifdef USE_ENDOMORPHISM + int skew; +#endif + secp256k1_scalar num = *number; + + secp256k1_scalar_set_int(&x, 0); + secp256k1_scalar_set_int(&shift, 1 << w); + /* With USE_ENDOMORPHISM on we only consider 128-bit numbers */ +#ifdef USE_ENDOMORPHISM + for (i = 0; i < 16; ++i) { + secp256k1_scalar_shr_int(&num, 8); + } + skew = secp256k1_wnaf_const(wnaf, num, w); +#else + secp256k1_wnaf_const(wnaf, num, w); +#endif + + for (i = WNAF_SIZE(w); i >= 0; --i) { + secp256k1_scalar t; + int v = wnaf[i]; + CHECK(v != 0); /* check nonzero */ + CHECK(v & 1); /* check parity */ + CHECK(v > -(1 << w)); /* check range above */ + CHECK(v < (1 << w)); /* check range below */ + + secp256k1_scalar_mul(&x, &x, &shift); + 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); + } +#ifdef USE_ENDOMORPHISM + /* Skew num because when encoding 128-bit numbers as odd we use an offset */ + secp256k1_scalar_cadd_bit(&num, skew == 2, 1); +#endif + CHECK(secp256k1_scalar_eq(&x, &num)); +} + void run_wnaf(void) { int i; - secp256k1_scalar_t n; + secp256k1_scalar n = {{0}}; + + /* Sanity check: 1 and 2 are the smallest odd and even numbers and should + * have easier-to-diagnose failure modes */ + n.d[0] = 1; + test_constant_wnaf(&n, 4); + n.d[0] = 2; + test_constant_wnaf(&n, 4); + /* Random tests */ for (i = 0; i < count; i++) { random_scalar_order(&n); test_wnaf(&n, 4+(i%10)); + test_constant_wnaf_negate(&n); + test_constant_wnaf(&n, 4 + (i % 10)); } + secp256k1_scalar_set_int(&n, 0); + CHECK(secp256k1_scalar_cond_negate(&n, 1) == -1); + CHECK(secp256k1_scalar_is_zero(&n)); + CHECK(secp256k1_scalar_cond_negate(&n, 0) == 1); + CHECK(secp256k1_scalar_is_zero(&n)); } void test_ecmult_constants(void) { /* Test ecmult_gen() for [0..36) and [order-36..0). */ - secp256k1_scalar_t x; - secp256k1_gej_t r; - secp256k1_ge_t ng; + secp256k1_scalar x; + secp256k1_gej r; + secp256k1_ge ng; int i; int j; secp256k1_ge_neg(&ng, &secp256k1_ge_const_g); @@ -1276,14 +2486,14 @@ void run_ecmult_constants(void) { } void test_ecmult_gen_blind(void) { - /* Test ecmult_gen() blinding and confirm that the blinding changes, the affline points match, and the z's don't match. */ - secp256k1_scalar_t key; - secp256k1_scalar_t b; + /* Test ecmult_gen() blinding and confirm that the blinding changes, the affine points match, and the z's don't match. */ + secp256k1_scalar key; + secp256k1_scalar b; unsigned char seed32[32]; - secp256k1_gej_t pgej; - secp256k1_gej_t pgej2; - secp256k1_gej_t i; - secp256k1_ge_t pge; + secp256k1_gej pgej; + secp256k1_gej pgej2; + secp256k1_gej i; + secp256k1_ge pge; random_scalar_order_test(&key); secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pgej, &key); secp256k1_rand256(seed32); @@ -1300,8 +2510,8 @@ void test_ecmult_gen_blind(void) { void test_ecmult_gen_blind_reset(void) { /* Test ecmult_gen() blinding reset and confirm that the blinding is consistent. */ - secp256k1_scalar_t b; - secp256k1_gej_t initial; + secp256k1_scalar b; + secp256k1_gej initial; secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, 0); b = ctx->ecmult_gen_ctx.blind; initial = ctx->ecmult_gen_ctx.initial; @@ -1318,35 +2528,702 @@ void run_ecmult_gen_blind(void) { } } +#ifdef USE_ENDOMORPHISM +/***** ENDOMORPHISH TESTS *****/ +void test_scalar_split(void) { + secp256k1_scalar full; + secp256k1_scalar s1, slam; + const unsigned char zero[32] = {0}; + unsigned char tmp[32]; + + random_scalar_order_test(&full); + secp256k1_scalar_split_lambda(&s1, &slam, &full); + + /* check that both are <= 128 bits in size */ + if (secp256k1_scalar_is_high(&s1)) { + secp256k1_scalar_negate(&s1, &s1); + } + if (secp256k1_scalar_is_high(&slam)) { + secp256k1_scalar_negate(&slam, &slam); + } + + secp256k1_scalar_get_b32(tmp, &s1); + CHECK(memcmp(zero, tmp, 16) == 0); + secp256k1_scalar_get_b32(tmp, &slam); + CHECK(memcmp(zero, tmp, 16) == 0); +} + +void run_endomorphism_tests(void) { + test_scalar_split(); +} +#endif + +void ec_pubkey_parse_pointtest(const unsigned char *input, int xvalid, int yvalid) { + unsigned char pubkeyc[65]; + secp256k1_pubkey pubkey; + secp256k1_ge ge; + size_t pubkeyclen; + int32_t ecount; + ecount = 0; + secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); + for (pubkeyclen = 3; pubkeyclen <= 65; pubkeyclen++) { + /* Smaller sizes are tested exhaustively elsewhere. */ + int32_t i; + memcpy(&pubkeyc[1], input, 64); + VG_UNDEF(&pubkeyc[pubkeyclen], 65 - pubkeyclen); + for (i = 0; i < 256; i++) { + /* Try all type bytes. */ + int xpass; + int ypass; + int ysign; + pubkeyc[0] = i; + /* What sign does this point have? */ + ysign = (input[63] & 1) + 2; + /* For the current type (i) do we expect parsing to work? Handled all of compressed/uncompressed/hybrid. */ + xpass = xvalid && (pubkeyclen == 33) && ((i & 254) == 2); + /* Do we expect a parse and re-serialize as uncompressed to give a matching y? */ + ypass = xvalid && yvalid && ((i & 4) == ((pubkeyclen == 65) << 2)) && + ((i == 4) || ((i & 251) == ysign)) && ((pubkeyclen == 33) || (pubkeyclen == 65)); + if (xpass || ypass) { + /* These cases must parse. */ + unsigned char pubkeyo[65]; + size_t outl; + memset(&pubkey, 0, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + ecount = 0; + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1); + VG_CHECK(&pubkey, sizeof(pubkey)); + outl = 65; + VG_UNDEF(pubkeyo, 65); + CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyo, &outl, &pubkey, SECP256K1_EC_COMPRESSED) == 1); + VG_CHECK(pubkeyo, outl); + CHECK(outl == 33); + CHECK(memcmp(&pubkeyo[1], &pubkeyc[1], 32) == 0); + CHECK((pubkeyclen != 33) || (pubkeyo[0] == pubkeyc[0])); + if (ypass) { + /* This test isn't always done because we decode with alternative signs, so the y won't match. */ + CHECK(pubkeyo[0] == ysign); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 1); + memset(&pubkey, 0, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + secp256k1_pubkey_save(&pubkey, &ge); + VG_CHECK(&pubkey, sizeof(pubkey)); + outl = 65; + VG_UNDEF(pubkeyo, 65); + CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyo, &outl, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 1); + VG_CHECK(pubkeyo, outl); + CHECK(outl == 65); + CHECK(pubkeyo[0] == 4); + CHECK(memcmp(&pubkeyo[1], input, 64) == 0); + } + CHECK(ecount == 0); + } else { + /* These cases must fail to parse. */ + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + } + } + } + secp256k1_context_set_illegal_callback(ctx, NULL, NULL); +} + +void run_ec_pubkey_parse_test(void) { +#define SECP256K1_EC_PARSE_TEST_NVALID (12) + const unsigned char valid[SECP256K1_EC_PARSE_TEST_NVALID][64] = { + { + /* Point with leading and trailing zeros in x and y serialization. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x52, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0xef, 0xa1, 0x7b, 0x77, 0x61, 0xe1, 0xe4, 0x27, 0x06, 0x98, 0x9f, 0xb4, 0x83, + 0xb8, 0xd2, 0xd4, 0x9b, 0xf7, 0x8f, 0xae, 0x98, 0x03, 0xf0, 0x99, 0xb8, 0x34, 0xed, 0xeb, 0x00 + }, + { + /* Point with x equal to a 3rd root of unity.*/ + 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, + 0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14, + 0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee, + }, + { + /* Point with largest x. (1/2) */ + 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, 0x2c, + 0x0e, 0x99, 0x4b, 0x14, 0xea, 0x72, 0xf8, 0xc3, 0xeb, 0x95, 0xc7, 0x1e, 0xf6, 0x92, 0x57, 0x5e, + 0x77, 0x50, 0x58, 0x33, 0x2d, 0x7e, 0x52, 0xd0, 0x99, 0x5c, 0xf8, 0x03, 0x88, 0x71, 0xb6, 0x7d, + }, + { + /* Point with largest x. (2/2) */ + 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, 0x2c, + 0xf1, 0x66, 0xb4, 0xeb, 0x15, 0x8d, 0x07, 0x3c, 0x14, 0x6a, 0x38, 0xe1, 0x09, 0x6d, 0xa8, 0xa1, + 0x88, 0xaf, 0xa7, 0xcc, 0xd2, 0x81, 0xad, 0x2f, 0x66, 0xa3, 0x07, 0xfb, 0x77, 0x8e, 0x45, 0xb2, + }, + { + /* Point with smallest x. (1/2) */ + 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, + 0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14, + 0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee, + }, + { + /* Point with smallest x. (2/2) */ + 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, + 0xbd, 0xe7, 0x0d, 0xf5, 0x19, 0x39, 0xb9, 0x4c, 0x9c, 0x24, 0x97, 0x9f, 0xa7, 0xdd, 0x04, 0xeb, + 0xd9, 0xb3, 0x57, 0x2d, 0xa7, 0x80, 0x22, 0x90, 0x43, 0x8a, 0xf2, 0xa6, 0x81, 0x89, 0x54, 0x41, + }, + { + /* Point with largest y. (1/3) */ + 0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6, + 0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07, + 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, 0x2e, + }, + { + /* Point with largest y. (2/3) */ + 0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c, + 0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73, + 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, 0x2e, + }, + { + /* Point with largest y. (3/3) */ + 0x14, 0x6d, 0x3b, 0x65, 0xad, 0xd9, 0xf5, 0x4c, 0xcc, 0xa2, 0x85, 0x33, 0xc8, 0x8e, 0x2c, 0xbc, + 0x63, 0xf7, 0x44, 0x3e, 0x16, 0x58, 0x78, 0x3a, 0xb4, 0x1f, 0x8e, 0xf9, 0x7c, 0x2a, 0x10, 0xb5, + 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, 0x2e, + }, + { + /* Point with smallest y. (1/3) */ + 0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6, + 0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07, + 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, + }, + { + /* Point with smallest y. (2/3) */ + 0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c, + 0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73, + 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, + }, + { + /* Point with smallest y. (3/3) */ + 0x14, 0x6d, 0x3b, 0x65, 0xad, 0xd9, 0xf5, 0x4c, 0xcc, 0xa2, 0x85, 0x33, 0xc8, 0x8e, 0x2c, 0xbc, + 0x63, 0xf7, 0x44, 0x3e, 0x16, 0x58, 0x78, 0x3a, 0xb4, 0x1f, 0x8e, 0xf9, 0x7c, 0x2a, 0x10, 0xb5, + 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 + } + }; +#define SECP256K1_EC_PARSE_TEST_NXVALID (4) + const unsigned char onlyxvalid[SECP256K1_EC_PARSE_TEST_NXVALID][64] = { + { + /* Valid if y overflow ignored (y = 1 mod p). (1/3) */ + 0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6, + 0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07, + 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, 0x30, + }, + { + /* Valid if y overflow ignored (y = 1 mod p). (2/3) */ + 0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c, + 0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73, + 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, 0x30, + }, + { + /* Valid if y overflow ignored (y = 1 mod p). (3/3)*/ + 0x14, 0x6d, 0x3b, 0x65, 0xad, 0xd9, 0xf5, 0x4c, 0xcc, 0xa2, 0x85, 0x33, 0xc8, 0x8e, 0x2c, 0xbc, + 0x63, 0xf7, 0x44, 0x3e, 0x16, 0x58, 0x78, 0x3a, 0xb4, 0x1f, 0x8e, 0xf9, 0x7c, 0x2a, 0x10, 0xb5, + 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, 0x30, + }, + { + /* x on curve, y is from y^2 = x^3 + 8. */ + 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, 0x03 + } + }; +#define SECP256K1_EC_PARSE_TEST_NINVALID (7) + const unsigned char invalid[SECP256K1_EC_PARSE_TEST_NINVALID][64] = { + { + /* x is third root of -8, y is -1 * (x^3+7); also on the curve for y^2 = x^3 + 9. */ + 0x0a, 0x2d, 0x2b, 0xa9, 0x35, 0x07, 0xf1, 0xdf, 0x23, 0x37, 0x70, 0xc2, 0xa7, 0x97, 0x96, 0x2c, + 0xc6, 0x1f, 0x6d, 0x15, 0xda, 0x14, 0xec, 0xd4, 0x7d, 0x8d, 0x27, 0xae, 0x1c, 0xd5, 0xf8, 0x53, + 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, + }, + { + /* Valid if x overflow ignored (x = 1 mod 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, 0x30, + 0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14, + 0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee, + }, + { + /* Valid if x overflow ignored (x = 1 mod 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, 0x30, + 0xbd, 0xe7, 0x0d, 0xf5, 0x19, 0x39, 0xb9, 0x4c, 0x9c, 0x24, 0x97, 0x9f, 0xa7, 0xdd, 0x04, 0xeb, + 0xd9, 0xb3, 0x57, 0x2d, 0xa7, 0x80, 0x22, 0x90, 0x43, 0x8a, 0xf2, 0xa6, 0x81, 0x89, 0x54, 0x41, + }, + { + /* x is -1, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 5. */ + 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, 0x2e, + 0xf4, 0x84, 0x14, 0x5c, 0xb0, 0x14, 0x9b, 0x82, 0x5d, 0xff, 0x41, 0x2f, 0xa0, 0x52, 0xa8, 0x3f, + 0xcb, 0x72, 0xdb, 0x61, 0xd5, 0x6f, 0x37, 0x70, 0xce, 0x06, 0x6b, 0x73, 0x49, 0xa2, 0xaa, 0x28, + }, + { + /* x is -1, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 5. */ + 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, 0x2e, + 0x0b, 0x7b, 0xeb, 0xa3, 0x4f, 0xeb, 0x64, 0x7d, 0xa2, 0x00, 0xbe, 0xd0, 0x5f, 0xad, 0x57, 0xc0, + 0x34, 0x8d, 0x24, 0x9e, 0x2a, 0x90, 0xc8, 0x8f, 0x31, 0xf9, 0x94, 0x8b, 0xb6, 0x5d, 0x52, 0x07, + }, + { + /* x is zero, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 7. */ + 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, + 0x8f, 0x53, 0x7e, 0xef, 0xdf, 0xc1, 0x60, 0x6a, 0x07, 0x27, 0xcd, 0x69, 0xb4, 0xa7, 0x33, 0x3d, + 0x38, 0xed, 0x44, 0xe3, 0x93, 0x2a, 0x71, 0x79, 0xee, 0xcb, 0x4b, 0x6f, 0xba, 0x93, 0x60, 0xdc, + }, + { + /* x is zero, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 7. */ + 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, + 0x70, 0xac, 0x81, 0x10, 0x20, 0x3e, 0x9f, 0x95, 0xf8, 0xd8, 0x32, 0x96, 0x4b, 0x58, 0xcc, 0xc2, + 0xc7, 0x12, 0xbb, 0x1c, 0x6c, 0xd5, 0x8e, 0x86, 0x11, 0x34, 0xb4, 0x8f, 0x45, 0x6c, 0x9b, 0x53 + } + }; + const unsigned char pubkeyc[66] = { + /* Serialization of G. */ + 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, 0x00 + }; + unsigned char sout[65]; + unsigned char shortkey[2]; + secp256k1_ge ge; + secp256k1_pubkey pubkey; + size_t len; + int32_t i; + int32_t ecount; + int32_t ecount2; + ecount = 0; + /* Nothing should be reading this far into pubkeyc. */ + VG_UNDEF(&pubkeyc[65], 1); + secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); + /* Zero length claimed, fail, zeroize, no illegal arg error. */ + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(shortkey, 2); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 0) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + /* Length one claimed, fail, zeroize, no illegal arg error. */ + for (i = 0; i < 256 ; i++) { + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + shortkey[0] = i; + VG_UNDEF(&shortkey[1], 1); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 1) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + } + /* Length two claimed, fail, zeroize, no illegal arg error. */ + for (i = 0; i < 65536 ; i++) { + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + shortkey[0] = i & 255; + shortkey[1] = i >> 8; + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 2) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + } + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(&pubkey, sizeof(pubkey)); + /* 33 bytes claimed on otherwise valid input starting with 0x04, fail, zeroize output, no illegal arg error. */ + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 33) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + /* NULL pubkey, illegal arg error. Pubkey isn't rewritten before this step, since it's NULL into the parser. */ + CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, pubkeyc, 65) == 0); + CHECK(ecount == 2); + /* NULL input string. Illegal arg and zeroize output. */ + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, NULL, 65) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 1); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 2); + /* 64 bytes claimed on input starting with 0x04, fail, zeroize output, no illegal arg error. */ + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 64) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + /* 66 bytes claimed, fail, zeroize output, no illegal arg error. */ + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 66) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + /* Valid parse. */ + memset(&pubkey, 0, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 65) == 1); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + VG_UNDEF(&ge, sizeof(ge)); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 1); + VG_CHECK(&ge.x, sizeof(ge.x)); + VG_CHECK(&ge.y, sizeof(ge.y)); + VG_CHECK(&ge.infinity, sizeof(ge.infinity)); + ge_equals_ge(&secp256k1_ge_const_g, &ge); + CHECK(ecount == 0); + /* secp256k1_ec_pubkey_serialize illegal args. */ + ecount = 0; + len = 65; + CHECK(secp256k1_ec_pubkey_serialize(ctx, NULL, &len, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 0); + CHECK(ecount == 1); + CHECK(len == 0); + CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, NULL, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 0); + CHECK(ecount == 2); + len = 65; + VG_UNDEF(sout, 65); + CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, &len, NULL, SECP256K1_EC_UNCOMPRESSED) == 0); + VG_CHECK(sout, 65); + CHECK(ecount == 3); + CHECK(len == 0); + len = 65; + CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, &len, &pubkey, ~0) == 0); + CHECK(ecount == 4); + CHECK(len == 0); + len = 65; + VG_UNDEF(sout, 65); + CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, &len, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 1); + VG_CHECK(sout, 65); + CHECK(ecount == 4); + CHECK(len == 65); + /* Multiple illegal args. Should still set arg error only once. */ + ecount = 0; + ecount2 = 11; + CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, NULL, 65) == 0); + CHECK(ecount == 1); + /* Does the illegal arg callback actually change the behavior? */ + secp256k1_context_set_illegal_callback(ctx, uncounting_illegal_callback_fn, &ecount2); + CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, NULL, 65) == 0); + CHECK(ecount == 1); + CHECK(ecount2 == 10); + secp256k1_context_set_illegal_callback(ctx, NULL, NULL); + /* Try a bunch of prefabbed points with all possible encodings. */ + for (i = 0; i < SECP256K1_EC_PARSE_TEST_NVALID; i++) { + ec_pubkey_parse_pointtest(valid[i], 1, 1); + } + for (i = 0; i < SECP256K1_EC_PARSE_TEST_NXVALID; i++) { + ec_pubkey_parse_pointtest(onlyxvalid[i], 1, 0); + } + for (i = 0; i < SECP256K1_EC_PARSE_TEST_NINVALID; i++) { + ec_pubkey_parse_pointtest(invalid[i], 0, 0); + } +} + +void run_eckey_edge_case_test(void) { + const unsigned char orderc[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 + }; + const unsigned char zeros[sizeof(secp256k1_pubkey)] = {0x00}; + unsigned char ctmp[33]; + unsigned char ctmp2[33]; + secp256k1_pubkey pubkey; + secp256k1_pubkey pubkey2; + secp256k1_pubkey pubkey_one; + secp256k1_pubkey pubkey_negone; + const secp256k1_pubkey *pubkeys[3]; + size_t len; + int32_t ecount; + /* Group order is too large, reject. */ + CHECK(secp256k1_ec_seckey_verify(ctx, orderc) == 0); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, orderc) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + /* Maximum value is too large, reject. */ + memset(ctmp, 255, 32); + CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 0); + memset(&pubkey, 1, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + /* Zero is too small, reject. */ + memset(ctmp, 0, 32); + CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 0); + memset(&pubkey, 1, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + /* One must be accepted. */ + ctmp[31] = 0x01; + CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 1); + memset(&pubkey, 0, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 1); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); + pubkey_one = pubkey; + /* Group order + 1 is too large, reject. */ + memcpy(ctmp, orderc, 32); + ctmp[31] = 0x42; + CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 0); + memset(&pubkey, 1, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + /* -1 must be accepted. */ + ctmp[31] = 0x40; + CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 1); + memset(&pubkey, 0, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 1); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); + pubkey_negone = pubkey; + /* Tweak of zero leaves the value changed. */ + memset(ctmp2, 0, 32); + CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp, ctmp2) == 1); + CHECK(memcmp(orderc, ctmp, 31) == 0 && ctmp[31] == 0x40); + memcpy(&pubkey2, &pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 1); + CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); + /* Multiply tweak of zero zeroizes the output. */ + CHECK(secp256k1_ec_privkey_tweak_mul(ctx, ctmp, ctmp2) == 0); + CHECK(memcmp(zeros, ctmp, 32) == 0); + CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, ctmp2) == 0); + CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + memcpy(&pubkey, &pubkey2, sizeof(pubkey)); + /* Overflowing key tweak zeroizes. */ + memcpy(ctmp, orderc, 32); + ctmp[31] = 0x40; + CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp, orderc) == 0); + CHECK(memcmp(zeros, ctmp, 32) == 0); + memcpy(ctmp, orderc, 32); + ctmp[31] = 0x40; + CHECK(secp256k1_ec_privkey_tweak_mul(ctx, ctmp, orderc) == 0); + CHECK(memcmp(zeros, ctmp, 32) == 0); + memcpy(ctmp, orderc, 32); + ctmp[31] = 0x40; + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, orderc) == 0); + CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + memcpy(&pubkey, &pubkey2, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, orderc) == 0); + CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + memcpy(&pubkey, &pubkey2, sizeof(pubkey)); + /* Private key tweaks results in a key of zero. */ + ctmp2[31] = 1; + CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp2, ctmp) == 0); + CHECK(memcmp(zeros, ctmp2, 32) == 0); + ctmp2[31] = 1; + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 0); + CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + memcpy(&pubkey, &pubkey2, sizeof(pubkey)); + /* Tweak computation wraps and results in a key of 1. */ + ctmp2[31] = 2; + CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp2, ctmp) == 1); + CHECK(memcmp(ctmp2, zeros, 31) == 0 && ctmp2[31] == 1); + ctmp2[31] = 2; + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 1); + ctmp2[31] = 1; + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, ctmp2) == 1); + CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); + /* Tweak mul * 2 = 1+1. */ + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 1); + ctmp2[31] = 2; + CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey2, ctmp2) == 1); + CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); + /* Test argument errors. */ + ecount = 0; + secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); + CHECK(ecount == 0); + /* Zeroize pubkey on parse error. */ + memset(&pubkey, 0, 32); + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 0); + CHECK(ecount == 1); + CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + memcpy(&pubkey, &pubkey2, sizeof(pubkey)); + memset(&pubkey2, 0, 32); + CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey2, ctmp2) == 0); + CHECK(ecount == 2); + CHECK(memcmp(&pubkey2, zeros, sizeof(pubkey2)) == 0); + /* Plain argument errors. */ + ecount = 0; + CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 1); + CHECK(ecount == 0); + CHECK(secp256k1_ec_seckey_verify(ctx, NULL) == 0); + CHECK(ecount == 1); + ecount = 0; + memset(ctmp2, 0, 32); + ctmp2[31] = 4; + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, NULL, ctmp2) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, NULL) == 0); + CHECK(ecount == 2); + ecount = 0; + memset(ctmp2, 0, 32); + ctmp2[31] = 4; + CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, NULL, ctmp2) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, NULL) == 0); + CHECK(ecount == 2); + ecount = 0; + memset(ctmp2, 0, 32); + CHECK(secp256k1_ec_privkey_tweak_add(ctx, NULL, ctmp2) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp, NULL) == 0); + CHECK(ecount == 2); + ecount = 0; + memset(ctmp2, 0, 32); + ctmp2[31] = 1; + CHECK(secp256k1_ec_privkey_tweak_mul(ctx, NULL, ctmp2) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ec_privkey_tweak_mul(ctx, ctmp, NULL) == 0); + CHECK(ecount == 2); + ecount = 0; + CHECK(secp256k1_ec_pubkey_create(ctx, NULL, ctmp) == 0); + CHECK(ecount == 1); + memset(&pubkey, 1, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, NULL) == 0); + CHECK(ecount == 2); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + /* secp256k1_ec_pubkey_combine tests. */ + ecount = 0; + pubkeys[0] = &pubkey_one; + VG_UNDEF(&pubkeys[0], sizeof(secp256k1_pubkey *)); + VG_UNDEF(&pubkeys[1], sizeof(secp256k1_pubkey *)); + VG_UNDEF(&pubkeys[2], sizeof(secp256k1_pubkey *)); + memset(&pubkey, 255, sizeof(secp256k1_pubkey)); + VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 0) == 0); + VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ec_pubkey_combine(ctx, NULL, pubkeys, 1) == 0); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + CHECK(ecount == 2); + memset(&pubkey, 255, sizeof(secp256k1_pubkey)); + VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, NULL, 1) == 0); + VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + CHECK(ecount == 3); + pubkeys[0] = &pubkey_negone; + memset(&pubkey, 255, sizeof(secp256k1_pubkey)); + VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 1) == 1); + VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); + CHECK(ecount == 3); + len = 33; + CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp, &len, &pubkey, SECP256K1_EC_COMPRESSED) == 1); + CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp2, &len, &pubkey_negone, SECP256K1_EC_COMPRESSED) == 1); + CHECK(memcmp(ctmp, ctmp2, 33) == 0); + /* Result is infinity. */ + pubkeys[0] = &pubkey_one; + pubkeys[1] = &pubkey_negone; + memset(&pubkey, 255, sizeof(secp256k1_pubkey)); + VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 2) == 0); + VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + CHECK(ecount == 3); + /* Passes through infinity but comes out one. */ + pubkeys[2] = &pubkey_one; + memset(&pubkey, 255, sizeof(secp256k1_pubkey)); + VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 3) == 1); + VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); + CHECK(ecount == 3); + len = 33; + CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp, &len, &pubkey, SECP256K1_EC_COMPRESSED) == 1); + CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp2, &len, &pubkey_one, SECP256K1_EC_COMPRESSED) == 1); + CHECK(memcmp(ctmp, ctmp2, 33) == 0); + /* Adds to two. */ + pubkeys[1] = &pubkey_one; + memset(&pubkey, 255, sizeof(secp256k1_pubkey)); + VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 2) == 1); + VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); + CHECK(ecount == 3); + secp256k1_context_set_illegal_callback(ctx, NULL, NULL); +} -void random_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *key, const secp256k1_scalar_t *msg, int *recid) { - secp256k1_scalar_t nonce; +void random_sign(secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *key, const secp256k1_scalar *msg, int *recid) { + secp256k1_scalar nonce; do { random_scalar_order_test(&nonce); - } while(!secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, sig, key, msg, &nonce, recid)); + } while(!secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, sigr, sigs, key, msg, &nonce, recid)); } void test_ecdsa_sign_verify(void) { - secp256k1_gej_t pubj; - secp256k1_ge_t pub; - secp256k1_scalar_t one; - secp256k1_scalar_t msg, key; - secp256k1_ecdsa_sig_t sig; + secp256k1_gej pubj; + secp256k1_ge pub; + secp256k1_scalar one; + secp256k1_scalar msg, key; + secp256k1_scalar sigr, sigs; int recid; int getrec; random_scalar_order_test(&msg); random_scalar_order_test(&key); secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubj, &key); secp256k1_ge_set_gej(&pub, &pubj); - getrec = secp256k1_rand32()&1; - random_sign(&sig, &key, &msg, getrec?&recid:NULL); + getrec = secp256k1_rand_bits(1); + random_sign(&sigr, &sigs, &key, &msg, getrec?&recid:NULL); if (getrec) { CHECK(recid >= 0 && recid < 4); } - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &pub, &msg)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &pub, &msg)); secp256k1_scalar_set_int(&one, 1); secp256k1_scalar_add(&msg, &msg, &one); - CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &pub, &msg)); + CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &pub, &msg)); } void run_ecdsa_sign_verify(void) { @@ -1357,22 +3234,23 @@ void run_ecdsa_sign_verify(void) { } /** Dummy nonce generation function that just uses a precomputed nonce, and fails if it is not accepted. Use only for testing. */ -static int precomputed_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { +static int precomputed_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { (void)msg32; (void)key32; + (void)algo16; memcpy(nonce32, data, 32); return (counter == 0); } -static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { +static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { /* Dummy nonce generator that has a fatal error on the first counter value. */ if (counter == 0) { return 0; } - return nonce_function_rfc6979(nonce32, msg32, key32, counter - 1, data); + return nonce_function_rfc6979(nonce32, msg32, key32, algo16, data, counter - 1); } -static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { +static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { /* Dummy nonce generator that produces unacceptable nonces for the first several counter values. */ if (counter < 3) { memset(nonce32, counter==0 ? 0 : 255, 32); @@ -1394,17 +3272,17 @@ static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char } return 1; } - /* Retry rate of 6979 is negligible esp. as we only call this in determinstic tests. */ + /* Retry rate of 6979 is negligible esp. as we only call this in deterministic tests. */ /* If someone does fine a case where it retries for secp256k1, we'd like to know. */ if (counter > 5) { return 0; } - return nonce_function_rfc6979(nonce32, msg32, key32, counter - 5, data); + return nonce_function_rfc6979(nonce32, msg32, key32, algo16, data, counter - 5); } -int is_empty_compact_signature(const unsigned char *sig64) { - static const unsigned char res[64] = {0}; - return memcmp(sig64, res, 64) == 0; +int is_empty_signature(const secp256k1_ecdsa_signature *sig) { + static const unsigned char res[sizeof(secp256k1_ecdsa_signature)] = {0}; + return memcmp(sig, res, sizeof(secp256k1_ecdsa_signature)) == 0; } void test_ecdsa_end_to_end(void) { @@ -1412,26 +3290,19 @@ void test_ecdsa_end_to_end(void) { unsigned char privkey[32]; unsigned char message[32]; unsigned char privkey2[32]; - unsigned char csignature[64]; - unsigned char signature[72]; - unsigned char signature2[72]; - unsigned char signature3[72]; - unsigned char signature4[72]; - unsigned char pubkey[65]; - unsigned char recpubkey[65]; + secp256k1_ecdsa_signature signature[6]; + secp256k1_scalar r, s; + unsigned char sig[74]; + size_t siglen = 74; + unsigned char pubkeyc[65]; + size_t pubkeyclen = 65; + secp256k1_pubkey pubkey; unsigned char seckey[300]; - int signaturelen = 72; - int signaturelen2 = 72; - int signaturelen3 = 72; - int signaturelen4 = 72; - int recid = 0; - int recpubkeylen = 0; - int pubkeylen = 65; - int seckeylen = 300; + size_t seckeylen = 300; /* Generate a random key and message. */ { - secp256k1_scalar_t msg, key; + secp256k1_scalar msg, key; random_scalar_order_test(&msg); random_scalar_order_test(&key); secp256k1_scalar_get_b32(privkey, &key); @@ -1440,117 +3311,120 @@ void test_ecdsa_end_to_end(void) { /* Construct and verify corresponding public key. */ CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); - CHECK(secp256k1_ec_pubkey_create(ctx, pubkey, &pubkeylen, privkey, (secp256k1_rand32() & 3) != 0) == 1); - if (secp256k1_rand32() & 1) { - CHECK(secp256k1_ec_pubkey_decompress(ctx, pubkey, &pubkeylen)); - } - CHECK(secp256k1_ec_pubkey_verify(ctx, pubkey, pubkeylen)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); + + /* Verify exporting and importing public key. */ + CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyc, &pubkeyclen, &pubkey, secp256k1_rand_bits(1) == 1 ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED)); + memset(&pubkey, 0, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1); /* Verify private key import and export. */ - CHECK(secp256k1_ec_privkey_export(ctx, privkey, seckey, &seckeylen, secp256k1_rand32() % 2) == 1); - CHECK(secp256k1_ec_privkey_import(ctx, privkey2, seckey, seckeylen) == 1); + CHECK(ec_privkey_export_der(ctx, seckey, &seckeylen, privkey, secp256k1_rand_bits(1) == 1)); + CHECK(ec_privkey_import_der(ctx, privkey2, seckey, seckeylen) == 1); CHECK(memcmp(privkey, privkey2, 32) == 0); /* Optionally tweak the keys using addition. */ - if (secp256k1_rand32() % 3 == 0) { + if (secp256k1_rand_int(3) == 0) { int ret1; int ret2; unsigned char rnd[32]; - unsigned char pubkey2[65]; - int pubkeylen2 = 65; + secp256k1_pubkey pubkey2; secp256k1_rand256_test(rnd); ret1 = secp256k1_ec_privkey_tweak_add(ctx, privkey, rnd); - ret2 = secp256k1_ec_pubkey_tweak_add(ctx, pubkey, pubkeylen, rnd); + ret2 = secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, rnd); CHECK(ret1 == ret2); if (ret1 == 0) { return; } - CHECK(secp256k1_ec_pubkey_create(ctx, pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); - CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, privkey) == 1); + CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); } /* Optionally tweak the keys using multiplication. */ - if (secp256k1_rand32() % 3 == 0) { + if (secp256k1_rand_int(3) == 0) { int ret1; int ret2; unsigned char rnd[32]; - unsigned char pubkey2[65]; - int pubkeylen2 = 65; + secp256k1_pubkey pubkey2; secp256k1_rand256_test(rnd); ret1 = secp256k1_ec_privkey_tweak_mul(ctx, privkey, rnd); - ret2 = secp256k1_ec_pubkey_tweak_mul(ctx, pubkey, pubkeylen, rnd); + ret2 = secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, rnd); CHECK(ret1 == ret2); if (ret1 == 0) { return; } - CHECK(secp256k1_ec_pubkey_create(ctx, pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); - CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, privkey) == 1); + CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); } /* Sign. */ - CHECK(secp256k1_ecdsa_sign(ctx, message, signature, &signaturelen, privkey, NULL, NULL) == 1); - CHECK(signaturelen > 0); - CHECK(secp256k1_ecdsa_sign(ctx, message, signature2, &signaturelen2, privkey, NULL, extra) == 1); - CHECK(signaturelen2 > 0); + CHECK(secp256k1_ecdsa_sign(ctx, &signature[0], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, &signature[4], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, &signature[1], message, privkey, NULL, extra) == 1); extra[31] = 1; - CHECK(secp256k1_ecdsa_sign(ctx, message, signature3, &signaturelen3, privkey, NULL, extra) == 1); - CHECK(signaturelen3 > 0); + CHECK(secp256k1_ecdsa_sign(ctx, &signature[2], message, privkey, NULL, extra) == 1); extra[31] = 0; extra[0] = 1; - CHECK(secp256k1_ecdsa_sign(ctx, message, signature4, &signaturelen4, privkey, NULL, extra) == 1); - CHECK(signaturelen3 > 0); - CHECK((signaturelen != signaturelen2) || (memcmp(signature, signature2, signaturelen) != 0)); - CHECK((signaturelen != signaturelen3) || (memcmp(signature, signature3, signaturelen) != 0)); - CHECK((signaturelen3 != signaturelen2) || (memcmp(signature3, signature2, signaturelen3) != 0)); - CHECK((signaturelen4 != signaturelen3) || (memcmp(signature4, signature3, signaturelen4) != 0)); - CHECK((signaturelen4 != signaturelen2) || (memcmp(signature4, signature2, signaturelen4) != 0)); - CHECK((signaturelen4 != signaturelen) || (memcmp(signature4, signature, signaturelen4) != 0)); + CHECK(secp256k1_ecdsa_sign(ctx, &signature[3], message, privkey, NULL, extra) == 1); + CHECK(memcmp(&signature[0], &signature[4], sizeof(signature[0])) == 0); + CHECK(memcmp(&signature[0], &signature[1], sizeof(signature[0])) != 0); + CHECK(memcmp(&signature[0], &signature[2], sizeof(signature[0])) != 0); + CHECK(memcmp(&signature[0], &signature[3], sizeof(signature[0])) != 0); + CHECK(memcmp(&signature[1], &signature[2], sizeof(signature[0])) != 0); + CHECK(memcmp(&signature[1], &signature[3], sizeof(signature[0])) != 0); + CHECK(memcmp(&signature[2], &signature[3], sizeof(signature[0])) != 0); /* Verify. */ - CHECK(secp256k1_ecdsa_verify(ctx, message, signature, signaturelen, pubkey, pubkeylen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, message, signature2, signaturelen2, pubkey, pubkeylen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, message, signature3, signaturelen3, pubkey, pubkeylen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, message, signature4, signaturelen4, pubkey, pubkeylen) == 1); - /* Destroy signature and verify again. */ - signature[signaturelen - 1 - secp256k1_rand32() % 20] += 1 + (secp256k1_rand32() % 255); - CHECK(secp256k1_ecdsa_verify(ctx, message, signature, signaturelen, pubkey, pubkeylen) != 1); - - /* Compact sign. */ - CHECK(secp256k1_ecdsa_sign_compact(ctx, message, csignature, privkey, NULL, NULL, &recid) == 1); - CHECK(!is_empty_compact_signature(csignature)); - /* Recover. */ - CHECK(secp256k1_ecdsa_recover_compact(ctx, message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1); - CHECK(recpubkeylen == pubkeylen); - CHECK(memcmp(pubkey, recpubkey, pubkeylen) == 0); - /* Destroy signature and verify again. */ - csignature[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255); - CHECK(secp256k1_ecdsa_recover_compact(ctx, message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) != 1 || - memcmp(pubkey, recpubkey, pubkeylen) != 0); - CHECK(recpubkeylen == pubkeylen); - + CHECK(secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[1], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[2], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[3], message, &pubkey) == 1); + /* Test lower-S form, malleate, verify and fail, test again, malleate again */ + CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[0])); + secp256k1_ecdsa_signature_load(ctx, &r, &s, &signature[0]); + secp256k1_scalar_negate(&s, &s); + secp256k1_ecdsa_signature_save(&signature[5], &r, &s); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 0); + CHECK(secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5])); + CHECK(secp256k1_ecdsa_signature_normalize(ctx, &signature[5], &signature[5])); + CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5])); + CHECK(!secp256k1_ecdsa_signature_normalize(ctx, &signature[5], &signature[5])); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 1); + secp256k1_scalar_negate(&s, &s); + secp256k1_ecdsa_signature_save(&signature[5], &r, &s); + CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5])); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 1); + CHECK(memcmp(&signature[5], &signature[0], 64) == 0); + + /* Serialize/parse DER and verify again */ + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature[0]) == 1); + memset(&signature[0], 0, sizeof(signature[0])); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature[0], sig, siglen) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 1); + /* Serialize/destroy/parse DER and verify again. */ + siglen = 74; + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature[0]) == 1); + sig[secp256k1_rand_int(siglen)] += 1 + secp256k1_rand_int(255); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature[0], sig, siglen) == 0 || + secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 0); } void test_random_pubkeys(void) { - secp256k1_ge_t elem; - secp256k1_ge_t elem2; + secp256k1_ge elem; + secp256k1_ge elem2; 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; + size_t len = secp256k1_rand_bits(2) == 0 ? 65 : 33; + if (secp256k1_rand_bits(2) == 0) { + len = secp256k1_rand_bits(6); } - r>>=8; if (len == 65) { - in[0] = (r & 2) ? 4 : (r & 1? 6 : 7); + in[0] = secp256k1_rand_bits(1) ? 4 : (secp256k1_rand_bits(1) ? 6 : 7); } else { - in[0] = (r & 1) ? 2 : 3; + in[0] = secp256k1_rand_bits(1) ? 2 : 3; } - r>>=2; - if ((r & 7) == 0) { - in[0] = (r & 2040) >> 3; + if (secp256k1_rand_bits(3) == 0) { + in[0] = secp256k1_rand_bits(8); } - r>>=11; if (len > 1) { secp256k1_rand256(&in[1]); } @@ -1561,7 +3435,7 @@ void test_random_pubkeys(void) { unsigned char out[65]; unsigned char firstb; int res; - int size = len; + size_t 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)); @@ -1577,7 +3451,7 @@ void test_random_pubkeys(void) { CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size)); ge_equals_ge(&elem,&elem2); /* Check that the X9.62 hybrid type is checked. */ - in[0] = (r & 1) ? 6 : 7; + in[0] = secp256k1_rand_bits(1) ? 6 : 7; res = secp256k1_eckey_pubkey_parse(&elem2, in, size); if (firstb == 2 || firstb == 3) { if (in[0] == firstb + 4) { @@ -1608,185 +3482,505 @@ void run_ecdsa_end_to_end(void) { } } +int test_ecdsa_der_parse(const unsigned char *sig, size_t siglen, int certainly_der, int certainly_not_der) { + static const unsigned char zeroes[32] = {0}; + static const unsigned char max_scalar[32] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, + 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40 + }; + + int ret = 0; + + secp256k1_ecdsa_signature sig_der; + unsigned char roundtrip_der[2048]; + unsigned char compact_der[64]; + size_t len_der = 2048; + int parsed_der = 0, valid_der = 0, roundtrips_der = 0; + + secp256k1_ecdsa_signature sig_der_lax; + unsigned char roundtrip_der_lax[2048]; + unsigned char compact_der_lax[64]; + size_t len_der_lax = 2048; + int parsed_der_lax = 0, valid_der_lax = 0, roundtrips_der_lax = 0; + +#ifdef ENABLE_OPENSSL_TESTS + ECDSA_SIG *sig_openssl; + const unsigned char *sigptr; + unsigned char roundtrip_openssl[2048]; + int len_openssl = 2048; + int parsed_openssl, valid_openssl = 0, roundtrips_openssl = 0; +#endif + + parsed_der = secp256k1_ecdsa_signature_parse_der(ctx, &sig_der, sig, siglen); + if (parsed_der) { + ret |= (!secp256k1_ecdsa_signature_serialize_compact(ctx, compact_der, &sig_der)) << 0; + valid_der = (memcmp(compact_der, zeroes, 32) != 0) && (memcmp(compact_der + 32, zeroes, 32) != 0); + } + if (valid_der) { + ret |= (!secp256k1_ecdsa_signature_serialize_der(ctx, roundtrip_der, &len_der, &sig_der)) << 1; + roundtrips_der = (len_der == siglen) && memcmp(roundtrip_der, sig, siglen) == 0; + } + + parsed_der_lax = ecdsa_signature_parse_der_lax(ctx, &sig_der_lax, sig, siglen); + if (parsed_der_lax) { + ret |= (!secp256k1_ecdsa_signature_serialize_compact(ctx, compact_der_lax, &sig_der_lax)) << 10; + valid_der_lax = (memcmp(compact_der_lax, zeroes, 32) != 0) && (memcmp(compact_der_lax + 32, zeroes, 32) != 0); + } + if (valid_der_lax) { + ret |= (!secp256k1_ecdsa_signature_serialize_der(ctx, roundtrip_der_lax, &len_der_lax, &sig_der_lax)) << 11; + roundtrips_der_lax = (len_der_lax == siglen) && memcmp(roundtrip_der_lax, sig, siglen) == 0; + } + + if (certainly_der) { + ret |= (!parsed_der) << 2; + } + if (certainly_not_der) { + ret |= (parsed_der) << 17; + } + if (valid_der) { + ret |= (!roundtrips_der) << 3; + } + + if (valid_der) { + ret |= (!roundtrips_der_lax) << 12; + ret |= (len_der != len_der_lax) << 13; + ret |= (memcmp(roundtrip_der_lax, roundtrip_der, len_der) != 0) << 14; + } + ret |= (roundtrips_der != roundtrips_der_lax) << 15; + if (parsed_der) { + ret |= (!parsed_der_lax) << 16; + } + +#ifdef ENABLE_OPENSSL_TESTS + sig_openssl = ECDSA_SIG_new(); + sigptr = sig; + parsed_openssl = (d2i_ECDSA_SIG(&sig_openssl, &sigptr, siglen) != NULL); + if (parsed_openssl) { + valid_openssl = !BN_is_negative(sig_openssl->r) && !BN_is_negative(sig_openssl->s) && BN_num_bits(sig_openssl->r) > 0 && BN_num_bits(sig_openssl->r) <= 256 && BN_num_bits(sig_openssl->s) > 0 && BN_num_bits(sig_openssl->s) <= 256; + if (valid_openssl) { + unsigned char tmp[32] = {0}; + BN_bn2bin(sig_openssl->r, tmp + 32 - BN_num_bytes(sig_openssl->r)); + valid_openssl = memcmp(tmp, max_scalar, 32) < 0; + } + if (valid_openssl) { + unsigned char tmp[32] = {0}; + BN_bn2bin(sig_openssl->s, tmp + 32 - BN_num_bytes(sig_openssl->s)); + valid_openssl = memcmp(tmp, max_scalar, 32) < 0; + } + } + len_openssl = i2d_ECDSA_SIG(sig_openssl, NULL); + if (len_openssl <= 2048) { + unsigned char *ptr = roundtrip_openssl; + CHECK(i2d_ECDSA_SIG(sig_openssl, &ptr) == len_openssl); + roundtrips_openssl = valid_openssl && ((size_t)len_openssl == siglen) && (memcmp(roundtrip_openssl, sig, siglen) == 0); + } else { + len_openssl = 0; + } + ECDSA_SIG_free(sig_openssl); + + ret |= (parsed_der && !parsed_openssl) << 4; + ret |= (valid_der && !valid_openssl) << 5; + ret |= (roundtrips_openssl && !parsed_der) << 6; + ret |= (roundtrips_der != roundtrips_openssl) << 7; + if (roundtrips_openssl) { + ret |= (len_der != (size_t)len_openssl) << 8; + ret |= (memcmp(roundtrip_der, roundtrip_openssl, len_der) != 0) << 9; + } +#endif + return ret; +} + +static void assign_big_endian(unsigned char *ptr, size_t ptrlen, uint32_t val) { + size_t i; + for (i = 0; i < ptrlen; i++) { + int shift = ptrlen - 1 - i; + if (shift >= 4) { + ptr[i] = 0; + } else { + ptr[i] = (val >> shift) & 0xFF; + } + } +} + +static void damage_array(unsigned char *sig, size_t *len) { + int pos; + int action = secp256k1_rand_bits(3); + if (action < 1) { + /* Delete a byte. */ + pos = secp256k1_rand_int(*len); + memmove(sig + pos, sig + pos + 1, *len - pos - 1); + (*len)--; + return; + } else if (action < 2) { + /* Insert a byte. */ + pos = secp256k1_rand_int(1 + *len); + memmove(sig + pos + 1, sig + pos, *len - pos); + sig[pos] = secp256k1_rand_bits(8); + (*len)++; + return; + } else if (action < 4) { + /* Modify a byte. */ + sig[secp256k1_rand_int(*len)] += 1 + secp256k1_rand_int(255); + return; + } else { /* action < 8 */ + /* Modify a bit. */ + sig[secp256k1_rand_int(*len)] ^= 1 << secp256k1_rand_bits(3); + return; + } +} + +static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly_der, int* certainly_not_der) { + int der; + int nlow[2], nlen[2], nlenlen[2], nhbit[2], nhbyte[2], nzlen[2]; + size_t tlen, elen, glen; + int indet; + int n; + + *len = 0; + der = secp256k1_rand_bits(2) == 0; + *certainly_der = der; + *certainly_not_der = 0; + indet = der ? 0 : secp256k1_rand_int(10) == 0; + + for (n = 0; n < 2; n++) { + /* We generate two classes of numbers: nlow==1 "low" ones (up to 32 bytes), nlow==0 "high" ones (32 bytes with 129 top bits set, or larger than 32 bytes) */ + nlow[n] = der ? 1 : (secp256k1_rand_bits(3) != 0); + /* The length of the number in bytes (the first byte of which will always be nonzero) */ + nlen[n] = nlow[n] ? secp256k1_rand_int(33) : 32 + secp256k1_rand_int(200) * secp256k1_rand_int(8) / 8; + CHECK(nlen[n] <= 232); + /* The top bit of the number. */ + nhbit[n] = (nlow[n] == 0 && nlen[n] == 32) ? 1 : (nlen[n] == 0 ? 0 : secp256k1_rand_bits(1)); + /* The top byte of the number (after the potential hardcoded 16 0xFF characters for "high" 32 bytes numbers) */ + nhbyte[n] = nlen[n] == 0 ? 0 : (nhbit[n] ? 128 + secp256k1_rand_bits(7) : 1 + secp256k1_rand_int(127)); + /* The number of zero bytes in front of the number (which is 0 or 1 in case of DER, otherwise we extend up to 300 bytes) */ + nzlen[n] = der ? ((nlen[n] == 0 || nhbit[n]) ? 1 : 0) : (nlow[n] ? secp256k1_rand_int(3) : secp256k1_rand_int(300 - nlen[n]) * secp256k1_rand_int(8) / 8); + if (nzlen[n] > ((nlen[n] == 0 || nhbit[n]) ? 1 : 0)) { + *certainly_not_der = 1; + } + CHECK(nlen[n] + nzlen[n] <= 300); + /* The length of the length descriptor for the number. 0 means short encoding, anything else is long encoding. */ + nlenlen[n] = nlen[n] + nzlen[n] < 128 ? 0 : (nlen[n] + nzlen[n] < 256 ? 1 : 2); + if (!der) { + /* nlenlen[n] max 127 bytes */ + int add = secp256k1_rand_int(127 - nlenlen[n]) * secp256k1_rand_int(16) * secp256k1_rand_int(16) / 256; + nlenlen[n] += add; + if (add != 0) { + *certainly_not_der = 1; + } + } + CHECK(nlen[n] + nzlen[n] + nlenlen[n] <= 427); + } + + /* The total length of the data to go, so far */ + tlen = 2 + nlenlen[0] + nlen[0] + nzlen[0] + 2 + nlenlen[1] + nlen[1] + nzlen[1]; + CHECK(tlen <= 856); + + /* The length of the garbage inside the tuple. */ + elen = (der || indet) ? 0 : secp256k1_rand_int(980 - tlen) * secp256k1_rand_int(8) / 8; + if (elen != 0) { + *certainly_not_der = 1; + } + tlen += elen; + CHECK(tlen <= 980); + + /* The length of the garbage after the end of the tuple. */ + glen = der ? 0 : secp256k1_rand_int(990 - tlen) * secp256k1_rand_int(8) / 8; + if (glen != 0) { + *certainly_not_der = 1; + } + CHECK(tlen + glen <= 990); + + /* Write the tuple header. */ + sig[(*len)++] = 0x30; + if (indet) { + /* Indeterminate length */ + sig[(*len)++] = 0x80; + *certainly_not_der = 1; + } else { + int tlenlen = tlen < 128 ? 0 : (tlen < 256 ? 1 : 2); + if (!der) { + int add = secp256k1_rand_int(127 - tlenlen) * secp256k1_rand_int(16) * secp256k1_rand_int(16) / 256; + tlenlen += add; + if (add != 0) { + *certainly_not_der = 1; + } + } + if (tlenlen == 0) { + /* Short length notation */ + sig[(*len)++] = tlen; + } else { + /* Long length notation */ + sig[(*len)++] = 128 + tlenlen; + assign_big_endian(sig + *len, tlenlen, tlen); + *len += tlenlen; + } + tlen += tlenlen; + } + tlen += 2; + CHECK(tlen + glen <= 1119); + + for (n = 0; n < 2; n++) { + /* Write the integer header. */ + sig[(*len)++] = 0x02; + if (nlenlen[n] == 0) { + /* Short length notation */ + sig[(*len)++] = nlen[n] + nzlen[n]; + } else { + /* Long length notation. */ + sig[(*len)++] = 128 + nlenlen[n]; + assign_big_endian(sig + *len, nlenlen[n], nlen[n] + nzlen[n]); + *len += nlenlen[n]; + } + /* Write zero padding */ + while (nzlen[n] > 0) { + sig[(*len)++] = 0x00; + nzlen[n]--; + } + if (nlen[n] == 32 && !nlow[n]) { + /* Special extra 16 0xFF bytes in "high" 32-byte numbers */ + int i; + for (i = 0; i < 16; i++) { + sig[(*len)++] = 0xFF; + } + nlen[n] -= 16; + } + /* Write first byte of number */ + if (nlen[n] > 0) { + sig[(*len)++] = nhbyte[n]; + nlen[n]--; + } + /* Generate remaining random bytes of number */ + secp256k1_rand_bytes_test(sig + *len, nlen[n]); + *len += nlen[n]; + nlen[n] = 0; + } + + /* Generate random garbage inside tuple. */ + secp256k1_rand_bytes_test(sig + *len, elen); + *len += elen; + + /* Generate end-of-contents bytes. */ + if (indet) { + sig[(*len)++] = 0; + sig[(*len)++] = 0; + tlen += 2; + } + CHECK(tlen + glen <= 1121); + + /* Generate random garbage outside tuple. */ + secp256k1_rand_bytes_test(sig + *len, glen); + *len += glen; + tlen += glen; + CHECK(tlen <= 1121); + CHECK(tlen == *len); +} + +void run_ecdsa_der_parse(void) { + int i,j; + for (i = 0; i < 200 * count; i++) { + unsigned char buffer[2048]; + size_t buflen = 0; + int certainly_der = 0; + int certainly_not_der = 0; + random_ber_signature(buffer, &buflen, &certainly_der, &certainly_not_der); + for (j = 0; j < 16; j++) { + int ret = 0; + if (j > 0) { + damage_array(buffer, &buflen); + /* We don't know anything anymore about the DERness of the result */ + certainly_der = 0; + certainly_not_der = 0; + } + ret = test_ecdsa_der_parse(buffer, buflen, certainly_der, certainly_not_der); + if (ret != 0) { + size_t k; + fprintf(stderr, "Failure %x on ", ret); + for (k = 0; k < buflen; k++) { + fprintf(stderr, "%02x ", buffer[k]); + } + fprintf(stderr, "\n"); + } + CHECK(ret == 0); + } + } +} + /* 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 t; - int pubkeylen = 65; - /* 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; - int recid; + secp256k1_ecdsa_signature sig; - CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 0)); - CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 1)); - CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 2)); - CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 3)); + /* Test the case where ECDSA recomputes a point that is infinity. */ + { + secp256k1_gej keyj; + secp256k1_ge key; + secp256k1_scalar msg; + secp256k1_scalar sr, ss; + secp256k1_scalar_set_int(&ss, 1); + secp256k1_scalar_negate(&ss, &ss); + secp256k1_scalar_inverse(&ss, &ss); + secp256k1_scalar_set_int(&sr, 1); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &keyj, &sr); + secp256k1_ge_set_gej(&key, &keyj); + msg = ss; + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + } - for (recid = 0; recid < 4; recid++) { - int i; - int recid2; - /* (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, + /* Verify signature with r of zero fails. */ + { + const unsigned char pubkey_mods_zero[33] = { + 0x02, 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 }; - unsigned char sigbderalt3[40] = { - 0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, + secp256k1_ge key; + secp256k1_scalar msg; + secp256k1_scalar sr, ss; + secp256k1_scalar_set_int(&ss, 1); + secp256k1_scalar_set_int(&msg, 0); + secp256k1_scalar_set_int(&sr, 0); + CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey_mods_zero, 33)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + } + + /* Verify signature with s of zero fails. */ + { + const unsigned char pubkey[33] = { + 0x02, 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, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, + 0x01 }; - unsigned char sigbderalt4[40] = { - 0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00, + secp256k1_ge key; + secp256k1_scalar msg; + secp256k1_scalar sr, ss; + secp256k1_scalar_set_int(&ss, 0); + secp256k1_scalar_set_int(&msg, 0); + secp256k1_scalar_set_int(&sr, 1); + CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + } + + /* Verify signature with message 0 passes. */ + { + const unsigned char pubkey[33] = { + 0x02, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x02 }; - /* (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 + const unsigned char pubkey2[33] = { + 0x02, 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, + 0x43 }; - CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigb64, pubkeyb, &pubkeyblen, 1, recid)); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 1); - for (recid2 = 0; recid2 < 4; recid2++) { - unsigned char pubkey2b[33]; - int pubkey2blen = 33; - CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigb64, pubkey2b, &pubkey2blen, 1, recid2)); - /* Verifying with (order + r,4) should always fail. */ - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderlong, sizeof(sigbderlong), pubkey2b, pubkey2blen) != 1); - } - /* DER parsing tests. */ - /* Zero length r/s. */ - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder_zr, sizeof(sigcder_zr), pubkeyb, pubkeyblen) == -2); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder_zs, sizeof(sigcder_zs), pubkeyb, pubkeyblen) == -2); - /* Leading zeros. */ - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt1, sizeof(sigbderalt1), pubkeyb, pubkeyblen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt2, sizeof(sigbderalt2), pubkeyb, pubkeyblen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == 1); - sigbderalt3[4] = 1; - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == -2); - sigbderalt4[7] = 1; - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == -2); - /* Damage signature. */ - sigbder[7]++; - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0); - sigbder[7]--; - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, 6, pubkeyb, pubkeyblen) == -2); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder)-1, pubkeyb, pubkeyblen) == -2); - for(i = 0; i < 8; i++) { - int c; - unsigned char orig = sigbder[i]; - /*Try every single-byte change.*/ - for (c = 0; c < 256; c++) { - if (c == orig ) { - continue; - } - sigbder[i] = c; - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == - (i==4 || i==7) ? 0 : -2 ); - } - sigbder[i] = orig; - } + secp256k1_ge key; + secp256k1_ge key2; + secp256k1_scalar msg; + secp256k1_scalar sr, ss; + secp256k1_scalar_set_int(&ss, 2); + secp256k1_scalar_set_int(&msg, 0); + secp256k1_scalar_set_int(&sr, 2); + CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); + CHECK(secp256k1_eckey_pubkey_parse(&key2, pubkey2, 33)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); + secp256k1_scalar_negate(&ss, &ss); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); + secp256k1_scalar_set_int(&ss, 1); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 0); } - /* Test the case where ECDSA recomputes a point that is infinity. */ + /* Verify signature with message 1 passes. */ { - secp256k1_gej_t keyj; - secp256k1_ge_t key; - secp256k1_scalar_t msg; - 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_ecmult_gen(&ctx->ecmult_gen_ctx, &keyj, &sig.r); - secp256k1_ge_set_gej(&key, &keyj); - msg = sig.s; - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &key, &msg) == 0); + const unsigned char pubkey[33] = { + 0x02, 0x14, 0x4e, 0x5a, 0x58, 0xef, 0x5b, 0x22, + 0x6f, 0xd2, 0xe2, 0x07, 0x6a, 0x77, 0xcf, 0x05, + 0xb4, 0x1d, 0xe7, 0x4a, 0x30, 0x98, 0x27, 0x8c, + 0x93, 0xe6, 0xe6, 0x3c, 0x0b, 0xc4, 0x73, 0x76, + 0x25 + }; + const unsigned char pubkey2[33] = { + 0x02, 0x8a, 0xd5, 0x37, 0xed, 0x73, 0xd9, 0x40, + 0x1d, 0xa0, 0x33, 0xd2, 0xdc, 0xf0, 0xaf, 0xae, + 0x34, 0xcf, 0x5f, 0x96, 0x4c, 0x73, 0x28, 0x0f, + 0x92, 0xc0, 0xf6, 0x9d, 0xd9, 0xb2, 0x09, 0x10, + 0x62 + }; + const unsigned char csr[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x45, 0x51, 0x23, 0x19, 0x50, 0xb7, 0x5f, 0xc4, + 0x40, 0x2d, 0xa1, 0x72, 0x2f, 0xc9, 0xba, 0xeb + }; + secp256k1_ge key; + secp256k1_ge key2; + secp256k1_scalar msg; + secp256k1_scalar sr, ss; + secp256k1_scalar_set_int(&ss, 1); + secp256k1_scalar_set_int(&msg, 1); + secp256k1_scalar_set_b32(&sr, csr, NULL); + CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); + CHECK(secp256k1_eckey_pubkey_parse(&key2, pubkey2, 33)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); + secp256k1_scalar_negate(&ss, &ss); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); + secp256k1_scalar_set_int(&ss, 2); + secp256k1_scalar_inverse_var(&ss, &ss); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 0); } - /* Test r/s equal to zero */ + /* Verify signature with message -1 passes. */ { - /* (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, + const unsigned char pubkey[33] = { + 0x03, 0xaf, 0x97, 0xff, 0x7d, 0x3a, 0xf6, 0xa0, + 0x02, 0x94, 0xbd, 0x9f, 0x4b, 0x2e, 0xd7, 0x52, + 0x28, 0xdb, 0x49, 0x2a, 0x65, 0xcb, 0x1e, 0x27, + 0x57, 0x9c, 0xba, 0x74, 0x20, 0xd5, 0x1d, 0x20, + 0xf1 + }; + const unsigned char csr[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x45, 0x51, 0x23, 0x19, 0x50, 0xb7, 0x5f, 0xc4, + 0x40, 0x2d, 0xa1, 0x72, 0x2f, 0xc9, 0xba, 0xee }; - unsigned char pubkeyc[65]; - int pubkeyclen = 65; - CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyc, &pubkeyclen, 0, 0) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 1); - sigcder[4] = 0; - sigc64[31] = 0; - CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0); - sigcder[4] = 1; - sigcder[7] = 0; - sigc64[31] = 1; - sigc64[63] = 0; - CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0); - } - - /*Signature where s would be zero.*/ + secp256k1_ge key; + secp256k1_scalar msg; + secp256k1_scalar sr, ss; + secp256k1_scalar_set_int(&ss, 1); + secp256k1_scalar_set_int(&msg, 1); + secp256k1_scalar_negate(&msg, &msg); + secp256k1_scalar_set_b32(&sr, csr, NULL); + CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + secp256k1_scalar_negate(&ss, &ss); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + secp256k1_scalar_set_int(&ss, 3); + secp256k1_scalar_inverse_var(&ss, &ss); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + } + + /* Signature where s would be zero. */ { - const unsigned char nonce[32] = { + secp256k1_pubkey pubkey; + size_t siglen; + int32_t ecount; + unsigned char signature[72]; + static 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, @@ -1810,21 +4004,72 @@ void test_ecdsa_edge_cases(void) { 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(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 0); - CHECK(siglen == 0); - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 0); - CHECK(siglen == 0); + ecount = 0; + secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce) == 0); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce2) == 0); msg[31] = 0xaa; + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce) == 1); + CHECK(ecount == 0); + CHECK(secp256k1_ecdsa_sign(ctx, NULL, msg, key, precomputed_nonce_function, nonce2) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, NULL, key, precomputed_nonce_function, nonce2) == 0); + CHECK(ecount == 2); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, NULL, precomputed_nonce_function, nonce2) == 0); + CHECK(ecount == 3); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce2) == 1); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, key) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, NULL, msg, &pubkey) == 0); + CHECK(ecount == 4); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, NULL, &pubkey) == 0); + CHECK(ecount == 5); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg, NULL) == 0); + CHECK(ecount == 6); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg, &pubkey) == 1); + CHECK(ecount == 6); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, NULL) == 0); + CHECK(ecount == 7); + /* That pubkeyload fails via an ARGCHECK is a little odd but makes sense because pubkeys are an opaque data type. */ + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg, &pubkey) == 0); + CHECK(ecount == 8); siglen = 72; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 1); - CHECK(siglen > 0); - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 1); - CHECK(siglen > 0); + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, NULL, &siglen, &sig) == 0); + CHECK(ecount == 9); + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, NULL, &sig) == 0); + CHECK(ecount == 10); + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, NULL) == 0); + CHECK(ecount == 11); + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, &sig) == 1); + CHECK(ecount == 11); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, NULL, signature, siglen) == 0); + CHECK(ecount == 12); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, NULL, siglen) == 0); + CHECK(ecount == 13); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, signature, siglen) == 1); + CHECK(ecount == 13); siglen = 10; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) != 1); - CHECK(siglen == 0); + /* Too little room for a signature does not fail via ARGCHECK. */ + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, &sig) == 0); + CHECK(ecount == 13); + ecount = 0; + CHECK(secp256k1_ecdsa_signature_normalize(ctx, NULL, NULL) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ecdsa_signature_serialize_compact(ctx, NULL, &sig) == 0); + CHECK(ecount == 2); + CHECK(secp256k1_ecdsa_signature_serialize_compact(ctx, signature, NULL) == 0); + CHECK(ecount == 3); + CHECK(secp256k1_ecdsa_signature_serialize_compact(ctx, signature, &sig) == 1); + CHECK(ecount == 3); + CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, NULL, signature) == 0); + CHECK(ecount == 4); + CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, &sig, NULL) == 0); + CHECK(ecount == 5); + CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, &sig, signature) == 1); + CHECK(ecount == 5); + memset(signature, 255, 64); + CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, &sig, signature) == 0); + CHECK(ecount == 5); + secp256k1_context_set_illegal_callback(ctx, NULL, NULL); } /* Nonce function corner cases. */ @@ -1833,65 +4078,43 @@ void test_ecdsa_edge_cases(void) { int i; unsigned char key[32]; unsigned char msg[32]; - unsigned char sig[72]; - unsigned char sig2[72]; - secp256k1_ecdsa_sig_t s[512]; - int siglen = 72; - int siglen2 = 72; - int recid2; + secp256k1_ecdsa_signature sig2; + secp256k1_scalar sr[512], ss; const unsigned char *extra; extra = t == 0 ? NULL : zero; memset(msg, 0, 32); msg[31] = 1; /* High key results in signature failure. */ memset(key, 0xFF, 32); - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 0); - CHECK(siglen == 0); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, NULL, extra) == 0); + CHECK(is_empty_signature(&sig)); /* Zero key results in signature failure. */ memset(key, 0, 32); - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 0); - CHECK(siglen == 0); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, NULL, extra) == 0); + CHECK(is_empty_signature(&sig)); /* Nonce function failure results in signature failure. */ key[31] = 1; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, nonce_function_test_fail, extra) == 0); - CHECK(siglen == 0); - CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, nonce_function_test_fail, extra, &recid) == 0); - CHECK(is_empty_compact_signature(sig)); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, nonce_function_test_fail, extra) == 0); + CHECK(is_empty_signature(&sig)); /* The retry loop successfully makes its way to the first good value. */ - siglen = 72; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, nonce_function_test_retry, extra) == 1); - CHECK(siglen > 0); - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, nonce_function_rfc6979, extra) == 1); - CHECK(siglen > 0); - CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0)); - CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, nonce_function_test_retry, extra, &recid) == 1); - CHECK(!is_empty_compact_signature(sig)); - CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig2, key, nonce_function_rfc6979, extra, &recid2) == 1); - CHECK(!is_empty_compact_signature(sig2)); - CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0)); - /* The default nonce function is determinstic. */ - siglen = 72; - siglen2 = 72; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 1); - CHECK(siglen > 0); - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1); - CHECK(siglen2 > 0); - CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0)); - CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, NULL, extra, &recid) == 1); - CHECK(!is_empty_compact_signature(sig)); - CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig2, key, NULL, extra, &recid2) == 1); - CHECK(!is_empty_compact_signature(sig)); - CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0)); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, nonce_function_test_retry, extra) == 1); + CHECK(!is_empty_signature(&sig)); + CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, nonce_function_rfc6979, extra) == 1); + CHECK(!is_empty_signature(&sig2)); + CHECK(memcmp(&sig, &sig2, sizeof(sig)) == 0); + /* The default nonce function is deterministic. */ + CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1); + CHECK(!is_empty_signature(&sig2)); + CHECK(memcmp(&sig, &sig2, sizeof(sig)) == 0); /* The default nonce function changes output with different messages. */ for(i = 0; i < 256; i++) { int j; - siglen2 = 72; msg[0] = i; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1); - CHECK(!is_empty_compact_signature(sig)); - CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2)); + CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1); + CHECK(!is_empty_signature(&sig2)); + secp256k1_ecdsa_signature_load(ctx, &sr[i], &ss, &sig2); for (j = 0; j < i; j++) { - CHECK(!secp256k1_scalar_eq(&s[i].r, &s[j].r)); + CHECK(!secp256k1_scalar_eq(&sr[i], &sr[j])); } } msg[0] = 0; @@ -1899,17 +4122,45 @@ void test_ecdsa_edge_cases(void) { /* The default nonce function changes output with different keys. */ for(i = 256; i < 512; i++) { int j; - siglen2 = 72; key[0] = i - 256; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1); - CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2)); + CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1); + CHECK(!is_empty_signature(&sig2)); + secp256k1_ecdsa_signature_load(ctx, &sr[i], &ss, &sig2); for (j = 0; j < i; j++) { - CHECK(!secp256k1_scalar_eq(&s[i].r, &s[j].r)); + CHECK(!secp256k1_scalar_eq(&sr[i], &sr[j])); } } key[0] = 0; } + { + /* Check that optional nonce arguments do not have equivalent effect. */ + const unsigned char zeros[32] = {0}; + unsigned char nonce[32]; + unsigned char nonce2[32]; + unsigned char nonce3[32]; + unsigned char nonce4[32]; + VG_UNDEF(nonce,32); + VG_UNDEF(nonce2,32); + VG_UNDEF(nonce3,32); + VG_UNDEF(nonce4,32); + CHECK(nonce_function_rfc6979(nonce, zeros, zeros, NULL, NULL, 0) == 1); + VG_CHECK(nonce,32); + CHECK(nonce_function_rfc6979(nonce2, zeros, zeros, zeros, NULL, 0) == 1); + VG_CHECK(nonce2,32); + CHECK(nonce_function_rfc6979(nonce3, zeros, zeros, NULL, (void *)zeros, 0) == 1); + VG_CHECK(nonce3,32); + CHECK(nonce_function_rfc6979(nonce4, zeros, zeros, zeros, (void *)zeros, 0) == 1); + VG_CHECK(nonce4,32); + CHECK(memcmp(nonce, nonce2, 32) != 0); + CHECK(memcmp(nonce, nonce3, 32) != 0); + CHECK(memcmp(nonce, nonce4, 32) != 0); + CHECK(memcmp(nonce2, nonce3, 32) != 0); + CHECK(memcmp(nonce2, nonce4, 32) != 0); + CHECK(memcmp(nonce3, nonce4, 32) != 0); + } + + /* Privkey export where pubkey is the point at infinity. */ { unsigned char privkey[300]; @@ -1919,9 +4170,10 @@ void test_ecdsa_edge_cases(void) { 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41, }; - int outlen = 300; - CHECK(!secp256k1_ec_privkey_export(ctx, seckey, privkey, &outlen, 0)); - CHECK(!secp256k1_ec_privkey_export(ctx, seckey, privkey, &outlen, 1)); + size_t outlen = 300; + CHECK(!ec_privkey_export_der(ctx, privkey, &outlen, seckey, 0)); + outlen = 300; + CHECK(!ec_privkey_export_der(ctx, privkey, &outlen, seckey, 1)); } } @@ -1930,46 +4182,48 @@ void run_ecdsa_edge_cases(void) { } #ifdef ENABLE_OPENSSL_TESTS -EC_KEY *get_openssl_key(const secp256k1_scalar_t *key) { +EC_KEY *get_openssl_key(const unsigned char *key32) { unsigned char privkey[300]; - int privkeylen; + size_t privkeylen; const unsigned char* pbegin = privkey; - int compr = secp256k1_rand32() & 1; + int compr = secp256k1_rand_bits(1); EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1); - CHECK(secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, &privkeylen, key, compr)); + CHECK(ec_privkey_export_der(ctx, privkey, &privkeylen, key32, compr)); CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen)); CHECK(EC_KEY_check_key(ec_key)); return ec_key; } void test_ecdsa_openssl(void) { - secp256k1_gej_t qj; - secp256k1_ge_t q; - secp256k1_ecdsa_sig_t sig; - secp256k1_scalar_t one; - secp256k1_scalar_t msg2; - secp256k1_scalar_t key, msg; + secp256k1_gej qj; + secp256k1_ge q; + secp256k1_scalar sigr, sigs; + secp256k1_scalar one; + secp256k1_scalar msg2; + secp256k1_scalar key, msg; EC_KEY *ec_key; unsigned int sigsize = 80; - int secp_sigsize = 80; + size_t secp_sigsize = 80; unsigned char message[32]; unsigned char signature[80]; + unsigned char key32[32]; secp256k1_rand256_test(message); secp256k1_scalar_set_b32(&msg, message, NULL); random_scalar_order_test(&key); + secp256k1_scalar_get_b32(key32, &key); secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &qj, &key); secp256k1_ge_set_gej(&q, &qj); - ec_key = get_openssl_key(&key); - CHECK(ec_key); + ec_key = get_openssl_key(key32); + CHECK(ec_key != NULL); CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key)); - CHECK(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &q, &msg)); + CHECK(secp256k1_ecdsa_sig_parse(&sigr, &sigs, signature, sigsize)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &q, &msg)); secp256k1_scalar_set_int(&one, 1); secp256k1_scalar_add(&msg2, &msg, &one); - CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &q, &msg2)); + CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &q, &msg2)); - random_sign(&sig, &key, &msg, NULL); - CHECK(secp256k1_ecdsa_sig_serialize(signature, &secp_sigsize, &sig)); + random_sign(&sigr, &sigs, &key, &msg, NULL); + CHECK(secp256k1_ecdsa_sig_serialize(signature, &secp_sigsize, &sigr, &sigs)); CHECK(ECDSA_verify(0, message, sizeof(message), signature, secp_sigsize, ec_key) == 1); EC_KEY_free(ec_key); @@ -1983,6 +4237,18 @@ void run_ecdsa_openssl(void) { } #endif +#ifdef ENABLE_MODULE_ECDH +# include "modules/ecdh/tests_impl.h" +#endif + +#ifdef ENABLE_MODULE_SCHNORR +# include "modules/schnorr/tests_impl.h" +#endif + +#ifdef ENABLE_MODULE_RECOVERY +# include "modules/recovery/tests_impl.h" +#endif + int main(int argc, char **argv) { unsigned char seed16[16] = {0}; unsigned char run32[32] = {0}; @@ -2007,7 +4273,7 @@ int main(int argc, char **argv) { } } else { FILE *frand = fopen("/dev/urandom", "r"); - if (!frand || !fread(&seed16, sizeof(seed16), 1, frand)) { + if ((frand == NULL) || !fread(&seed16, sizeof(seed16), 1, frand)) { uint64_t t = time(NULL) * (uint64_t)1337; seed16[0] ^= t; seed16[1] ^= t >> 8; @@ -2028,12 +4294,14 @@ int main(int argc, char **argv) { /* initialize */ run_context_tests(); ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - - if (secp256k1_rand32() & 1) { + if (secp256k1_rand_bits(1)) { secp256k1_rand256(run32); - CHECK(secp256k1_context_randomize(ctx, secp256k1_rand32() & 1 ? run32 : NULL)); + CHECK(secp256k1_context_randomize(ctx, secp256k1_rand_bits(1) ? run32 : NULL)); } + run_rand_bits(); + run_rand_int(); + run_sha256_tests(); run_hmac_sha256_tests(); run_rfc6979_hmac_sha256_tests(); @@ -2057,6 +4325,7 @@ int main(int argc, char **argv) { /* group tests */ run_ge(); + run_group_decompress(); /* ecmult tests */ run_wnaf(); @@ -2064,9 +4333,28 @@ int main(int argc, char **argv) { run_ecmult_chain(); run_ecmult_constants(); run_ecmult_gen_blind(); + run_ecmult_const_tests(); + run_ec_combine(); + + /* endomorphism tests */ +#ifdef USE_ENDOMORPHISM + run_endomorphism_tests(); +#endif + + /* EC point parser test */ + run_ec_pubkey_parse_test(); + + /* EC key edge cases */ + run_eckey_edge_case_test(); + +#ifdef ENABLE_MODULE_ECDH + /* ecdh tests */ + run_ecdh_tests(); +#endif /* ecdsa tests */ run_random_pubkeys(); + run_ecdsa_der_parse(); run_ecdsa_sign_verify(); run_ecdsa_end_to_end(); run_ecdsa_edge_cases(); @@ -2074,10 +4362,22 @@ int main(int argc, char **argv) { run_ecdsa_openssl(); #endif +#ifdef ENABLE_MODULE_SCHNORR + /* Schnorr tests */ + run_schnorr_tests(); +#endif + +#ifdef ENABLE_MODULE_RECOVERY + /* ECDSA pubkey recovery tests */ + run_recovery_tests(); +#endif + secp256k1_rand256(run32); printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]); /* shutdown */ secp256k1_context_destroy(ctx); + + printf("no problems found\n"); return 0; } diff --git a/src/secp256k1/src/util.h b/src/secp256k1/src/util.h index ae98639f7c..4eef4ded47 100644 --- a/src/secp256k1/src/util.h +++ b/src/secp256k1/src/util.h @@ -15,6 +15,15 @@ #include <stdint.h> #include <stdio.h> +typedef struct { + void (*fn)(const char *text, void* data); + const void* data; +} secp256k1_callback; + +static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * const cb, const char * const text) { + cb->fn(text, (void*)cb->data); +} + #ifdef DETERMINISTIC #define TEST_FAILURE(msg) do { \ fprintf(stderr, "%s\n", msg); \ @@ -47,23 +56,20 @@ } 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. */ +/* Like assert(), but when VERIFY is defined, and side-effect safe. */ #ifdef VERIFY #define VERIFY_CHECK CHECK +#define VERIFY_SETUP(stmt) do { stmt; } while(0) #else #define VERIFY_CHECK(cond) do { (void)(cond); } while(0) +#define VERIFY_SETUP(stmt) #endif -static SECP256K1_INLINE void *checked_malloc(size_t size) { +static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_t size) { void *ret = malloc(size); - CHECK(ret != NULL); + if (ret == NULL) { + secp256k1_callback_call(cb, "Out of memory"); + } return ret; } diff --git a/src/serialize.h b/src/serialize.h index 53d8af142f..5c2db9d332 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -20,7 +20,7 @@ #include <utility> #include <vector> -class CScript; +#include "prevector.h" static const unsigned int MAX_SIZE = 0x02000000; @@ -49,26 +49,26 @@ inline T* NCONST_PTR(const T* val) * @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. */ -template <class T, class TAl> -inline T* begin_ptr(std::vector<T,TAl>& v) +template <typename V> +inline typename V::value_type* begin_ptr(V& v) { return v.empty() ? NULL : &v[0]; } /** Get begin pointer of vector (const version) */ -template <class T, class TAl> -inline const T* begin_ptr(const std::vector<T,TAl>& v) +template <typename V> +inline const typename V::value_type* begin_ptr(const V& v) { return v.empty() ? NULL : &v[0]; } /** Get end pointer of vector (non-const version) */ -template <class T, class TAl> -inline T* end_ptr(std::vector<T,TAl>& v) +template <typename V> +inline typename V::value_type* end_ptr(V& v) { return v.empty() ? NULL : (&v[0] + v.size()); } /** Get end pointer of vector (const version) */ -template <class T, class TAl> -inline const T* end_ptr(const std::vector<T,TAl>& v) +template <typename V> +inline const typename V::value_type* end_ptr(const V& v) { return v.empty() ? NULL : (&v[0] + v.size()); } @@ -391,6 +391,12 @@ public: pbegin = (char*)begin_ptr(v); pend = (char*)end_ptr(v); } + template <unsigned int N, typename T, typename S, typename D> + explicit CFlatData(prevector<N, T, S, D> &v) + { + pbegin = (char*)begin_ptr(v); + pend = (char*)end_ptr(v); + } char* begin() { return pbegin; } const char* begin() const { return pbegin; } char* end() { return pend; } @@ -486,6 +492,20 @@ template<typename Stream, typename C> void Serialize(Stream& os, const std::basi template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0); /** + * prevector + * prevectors of unsigned char are a special case and are intended to be serialized as a single opaque blob. + */ +template<unsigned int N, typename T> unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const unsigned char&); +template<unsigned int N, typename T, typename V> unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const V&); +template<unsigned int N, typename T> inline unsigned int GetSerializeSize(const prevector<N, T>& v, int nType, int nVersion); +template<typename Stream, unsigned int N, typename T> void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const unsigned char&); +template<typename Stream, unsigned int N, typename T, typename V> void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const V&); +template<typename Stream, unsigned int N, typename T> inline void Serialize(Stream& os, const prevector<N, T>& v, int nType, int nVersion); +template<typename Stream, unsigned int N, typename T> void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const unsigned char&); +template<typename Stream, unsigned int N, typename T, typename V> void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const V&); +template<typename Stream, unsigned int N, typename T> inline void Unserialize(Stream& is, prevector<N, T>& v, int nType, int nVersion); + +/** * vector * vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob. */ @@ -500,13 +520,6 @@ template<typename Stream, typename T, typename A, typename V> void Unserialize_i 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 - */ -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 */ template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K, T>& item, int nType, int nVersion); @@ -588,6 +601,96 @@ void Unserialize(Stream& is, std::basic_string<C>& str, int, int) /** + * prevector + */ +template<unsigned int N, typename T> +unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const unsigned char&) +{ + return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T)); +} + +template<unsigned int N, typename T, typename V> +unsigned int GetSerializeSize_impl(const prevector<N, T>& v, int nType, int nVersion, const V&) +{ + unsigned int nSize = GetSizeOfCompactSize(v.size()); + for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi) + nSize += GetSerializeSize((*vi), nType, nVersion); + return nSize; +} + +template<unsigned int N, typename T> +inline unsigned int GetSerializeSize(const prevector<N, T>& v, int nType, int nVersion) +{ + return GetSerializeSize_impl(v, nType, nVersion, T()); +} + + +template<typename Stream, unsigned int N, typename T> +void Serialize_impl(Stream& os, const prevector<N, T>& 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, unsigned int N, typename T, typename V> +void Serialize_impl(Stream& os, const prevector<N, T>& v, int nType, int nVersion, const V&) +{ + WriteCompactSize(os, v.size()); + for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi) + ::Serialize(os, (*vi), nType, nVersion); +} + +template<typename Stream, unsigned int N, typename T> +inline void Serialize(Stream& os, const prevector<N, T>& v, int nType, int nVersion) +{ + Serialize_impl(os, v, nType, nVersion, T()); +} + + +template<typename Stream, unsigned int N, typename T> +void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const unsigned char&) +{ + // Limit size per read so bogus size value won't cause out of memory + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + while (i < nSize) + { + unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); + v.resize(i + blk); + is.read((char*)&v[i], blk * sizeof(T)); + i += blk; + } +} + +template<typename Stream, unsigned int N, typename T, typename V> +void Unserialize_impl(Stream& is, prevector<N, T>& v, int nType, int nVersion, const V&) +{ + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + unsigned int nMid = 0; + while (nMid < nSize) + { + nMid += 5000000 / sizeof(T); + if (nMid > nSize) + nMid = nSize; + v.resize(nMid); + for (; i < nMid; i++) + Unserialize(is, v[i], nType, nVersion); + } +} + +template<typename Stream, unsigned int N, typename T> +inline void Unserialize(Stream& is, prevector<N, T>& v, int nType, int nVersion) +{ + Unserialize_impl(is, v, nType, nVersion, T()); +} + + + +/** * vector */ template<typename T, typename A> @@ -678,28 +781,6 @@ inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersio /** - * 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); -} - -template<typename Stream> -void Serialize(Stream& os, const CScript& v, int nType, int nVersion) -{ - Serialize(os, (const std::vector<unsigned char>&)v, nType, nVersion); -} - -template<typename Stream> -void Unserialize(Stream& is, CScript& v, int nType, int nVersion) -{ - Unserialize(is, (std::vector<unsigned char>&)v, nType, nVersion); -} - - - -/** * pair */ template<typename K, typename T> diff --git a/src/streams.h b/src/streams.h index fa1e18defe..0fc6135a6a 100644 --- a/src/streams.h +++ b/src/streams.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -296,6 +296,29 @@ public: data.insert(data.end(), begin(), end()); clear(); } + + /** + * XOR the contents of this stream with a certain key. + * + * @param[in] key The key used to XOR the data in this stream. + */ + void Xor(const std::vector<unsigned char>& key) + { + if (key.size() == 0) { + return; + } + + for (size_type i = 0, j = 0; i != size(); i++) { + vch[i] ^= key[j++]; + + // This potentially acts on very many bytes of data, so it's + // important that we calculate `j`, i.e. the `key` index in this + // way instead of doing a %, which would effectively be a division + // for each byte Xor'd -- much slower than need be. + if (j == key.size()) + j = 0; + } + } }; diff --git a/src/support/allocators/secure.h b/src/support/allocators/secure.h index 5e7bb66ea2..1ec40fe830 100644 --- a/src/support/allocators/secure.h +++ b/src/support/allocators/secure.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/support/allocators/zeroafterfree.h b/src/support/allocators/zeroafterfree.h index 41e23392e8..28a940ad1b 100644 --- a/src/support/allocators/zeroafterfree.h +++ b/src/support/allocators/zeroafterfree.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/support/pagelocker.cpp b/src/support/pagelocker.cpp index 440e0a5193..7cea2d88c5 100644 --- a/src/support/pagelocker.cpp +++ b/src/support/pagelocker.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/support/pagelocker.h b/src/support/pagelocker.h index 88b95cce73..6b3979e551 100644 --- a/src/support/pagelocker.h +++ b/src/support/pagelocker.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/sync.cpp b/src/sync.cpp index 1837e8d53d..8df8ae43f4 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2012 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/sync.h b/src/sync.h index 68a9443084..34dd8c228e 100644 --- a/src/sync.h +++ b/src/sync.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index 0a23c430ed..1b7d368e13 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index da296a0461..95342498fa 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -49,7 +49,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning) CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); // Should get banned - SendMessages(&dummyNode1, false); + SendMessages(&dummyNode1); BOOST_CHECK(CNode::IsBanned(addr1)); BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned @@ -57,11 +57,11 @@ BOOST_AUTO_TEST_CASE(DoS_banning) CNode dummyNode2(INVALID_SOCKET, addr2, "", true); dummyNode2.nVersion = 1; Misbehaving(dummyNode2.GetId(), 50); - SendMessages(&dummyNode2, false); + SendMessages(&dummyNode2); BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet... BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be Misbehaving(dummyNode2.GetId(), 50); - SendMessages(&dummyNode2, false); + SendMessages(&dummyNode2); BOOST_CHECK(CNode::IsBanned(addr2)); } @@ -73,13 +73,13 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); - SendMessages(&dummyNode1, false); + SendMessages(&dummyNode1); BOOST_CHECK(!CNode::IsBanned(addr1)); Misbehaving(dummyNode1.GetId(), 10); - SendMessages(&dummyNode1, false); + SendMessages(&dummyNode1); BOOST_CHECK(!CNode::IsBanned(addr1)); Misbehaving(dummyNode1.GetId(), 1); - SendMessages(&dummyNode1, false); + SendMessages(&dummyNode1); BOOST_CHECK(CNode::IsBanned(addr1)); mapArgs.erase("-banscore"); } @@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) dummyNode.nVersion = 1; Misbehaving(dummyNode.GetId(), 100); - SendMessages(&dummyNode, false); + SendMessages(&dummyNode); BOOST_CHECK(CNode::IsBanned(addr)); SetMockTime(nStartTime+60*60); diff --git a/src/test/README.md b/src/test/README.md index e36112bd4f..b2d6be14f1 100644 --- a/src/test/README.md +++ b/src/test/README.md @@ -16,6 +16,8 @@ their tests in a test suite called "<source_filename>_tests". For an examples of this pattern, examine uint160_tests.cpp and uint256_tests.cpp. +Add the source files to /src/Makefile.test.include to add them to the build. + For further reading, I found the following website to be helpful in explaining how the boost unit test framework works: [http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/](http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/). diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp index 0c2ade48d6..dad191c684 100644 --- a/src/test/accounting_tests.cpp +++ b/src/test/accounting_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) ae.nTime = 1333333333; ae.strOtherAccount = "b"; ae.strComment = ""; - walletdb.WriteAccountingEntry(ae); + pwalletMain->AddAccountingEntry(ae, walletdb); wtx.mapValue["comment"] = "z"; pwalletMain->AddToWallet(wtx, false, &walletdb); @@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) ae.nTime = 1333333336; ae.strOtherAccount = "c"; - walletdb.WriteAccountingEntry(ae); + pwalletMain->AddAccountingEntry(ae, walletdb); GetResults(walletdb, results); @@ -71,7 +71,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) ae.nTime = 1333333330; ae.strOtherAccount = "d"; ae.nOrderPos = pwalletMain->IncOrderPosNext(); - walletdb.WriteAccountingEntry(ae); + pwalletMain->AddAccountingEntry(ae, walletdb); GetResults(walletdb, results); @@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) ae.nTime = 1333333334; ae.strOtherAccount = "e"; ae.nOrderPos = -1; - walletdb.WriteAccountingEntry(ae); + pwalletMain->AddAccountingEntry(ae, walletdb); GetResults(walletdb, results); diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp new file mode 100644 index 0000000000..a1e6a204fc --- /dev/null +++ b/src/test/addrman_tests.cpp @@ -0,0 +1,180 @@ +// Copyright (c) 2012-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "addrman.h" +#include "test/test_bitcoin.h" +#include <string> +#include <boost/test/unit_test.hpp> + +#include "random.h" + +using namespace std; + +class CAddrManTest : public CAddrMan{}; + +BOOST_FIXTURE_TEST_SUITE(addrman_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(addrman_simple) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + CNetAddr source = CNetAddr("252.2.2.2:8333"); + + // Test 1: Does Addrman respond correctly when empty. + BOOST_CHECK(addrman.size() == 0); + CAddrInfo addr_null = addrman.Select(); + BOOST_CHECK(addr_null.ToString() == "[::]:0"); + + // Test 2: Does Addrman::Add work as expected. + CService addr1 = CService("250.1.1.1:8333"); + addrman.Add(CAddress(addr1), source); + BOOST_CHECK(addrman.size() == 1); + CAddrInfo addr_ret1 = addrman.Select(); + BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); + + // Test 3: Does IP address deduplication work correctly. + // Expected dup IP should not be added. + CService addr1_dup = CService("250.1.1.1:8333"); + addrman.Add(CAddress(addr1_dup), source); + BOOST_CHECK(addrman.size() == 1); + + + // Test 5: New table has one addr and we add a diff addr we should + // have two addrs. + CService addr2 = CService("250.1.1.2:8333"); + addrman.Add(CAddress(addr2), source); + BOOST_CHECK(addrman.size() == 2); + + // Test 6: AddrMan::Clear() should empty the new table. + addrman.Clear(); + BOOST_CHECK(addrman.size() == 0); + CAddrInfo addr_null2 = addrman.Select(); + BOOST_CHECK(addr_null2.ToString() == "[::]:0"); +} + +BOOST_AUTO_TEST_CASE(addrman_ports) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + CNetAddr source = CNetAddr("252.2.2.2:8333"); + + BOOST_CHECK(addrman.size() == 0); + + // Test 7; Addr with same IP but diff port does not replace existing addr. + CService addr1 = CService("250.1.1.1:8333"); + addrman.Add(CAddress(addr1), source); + BOOST_CHECK(addrman.size() == 1); + + CService addr1_port = CService("250.1.1.1:8334"); + addrman.Add(CAddress(addr1_port), source); + BOOST_CHECK(addrman.size() == 1); + CAddrInfo addr_ret2 = addrman.Select(); + BOOST_CHECK(addr_ret2.ToString() == "250.1.1.1:8333"); + + // Test 8: Add same IP but diff port to tried table, it doesn't get added. + // Perhaps this is not ideal behavior but it is the current behavior. + addrman.Good(CAddress(addr1_port)); + BOOST_CHECK(addrman.size() == 1); + bool newOnly = true; + CAddrInfo addr_ret3 = addrman.Select(newOnly); + BOOST_CHECK(addr_ret3.ToString() == "250.1.1.1:8333"); +} + + +BOOST_AUTO_TEST_CASE(addrman_select) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + CNetAddr source = CNetAddr("252.2.2.2:8333"); + + // Test 9: Select from new with 1 addr in new. + CService addr1 = CService("250.1.1.1:8333"); + addrman.Add(CAddress(addr1), source); + BOOST_CHECK(addrman.size() == 1); + + bool newOnly = true; + CAddrInfo addr_ret1 = addrman.Select(newOnly); + BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); + + + // Test 10: move addr to tried, select from new expected nothing returned. + addrman.Good(CAddress(addr1)); + BOOST_CHECK(addrman.size() == 1); + CAddrInfo addr_ret2 = addrman.Select(newOnly); + BOOST_CHECK(addr_ret2.ToString() == "[::]:0"); + + CAddrInfo addr_ret3 = addrman.Select(); + BOOST_CHECK(addr_ret3.ToString() == "250.1.1.1:8333"); +} + +BOOST_AUTO_TEST_CASE(addrman_new_collisions) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + CNetAddr source = CNetAddr("252.2.2.2:8333"); + + BOOST_CHECK(addrman.size() == 0); + + for (unsigned int i = 1; i < 4; i++){ + CService addr = CService("250.1.1."+boost::to_string(i)); + addrman.Add(CAddress(addr), source); + + //Test 11: No collision in new table yet. + BOOST_CHECK(addrman.size() == i); + } + + //Test 12: new table collision! + CService addr1 = CService("250.1.1.4"); + addrman.Add(CAddress(addr1), source); + BOOST_CHECK(addrman.size() == 3); + + CService addr2 = CService("250.1.1.5"); + addrman.Add(CAddress(addr2), source); + BOOST_CHECK(addrman.size() == 4); +} + +BOOST_AUTO_TEST_CASE(addrman_tried_collisions) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + CNetAddr source = CNetAddr("252.2.2.2:8333"); + + BOOST_CHECK(addrman.size() == 0); + + for (unsigned int i = 1; i < 75; i++){ + CService addr = CService("250.1.1."+boost::to_string(i)); + addrman.Add(CAddress(addr), source); + addrman.Good(CAddress(addr)); + + //Test 13: No collision in tried table yet. + BOOST_TEST_MESSAGE(addrman.size()); + BOOST_CHECK(addrman.size() == i); + } + + //Test 14: tried table collision! + CService addr1 = CService("250.1.1.76"); + addrman.Add(CAddress(addr1), source); + BOOST_CHECK(addrman.size() == 74); + + CService addr2 = CService("250.1.1.77"); + addrman.Add(CAddress(addr2), source); + BOOST_CHECK(addrman.size() == 75); +} + + +BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index dd3c51d09b..0895ef3326 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -217,10 +217,12 @@ BOOST_AUTO_TEST_CASE(PartitionAlert) // use them } + strMiscWarning = ""; + // Test 1: chain with blocks every nPowTargetSpacing seconds, // as normal, no worries: PartitionCheck(falseFunc, csDummy, &indexDummy[99], nPowTargetSpacing); - BOOST_CHECK(strMiscWarning.empty()); + BOOST_CHECK_MESSAGE(strMiscWarning.empty(), strMiscWarning); // Test 2: go 3.5 hours without a block, expect a warning: now += 3*60*60+30*60; diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index 2108efece5..613f6c12d7 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 17d6bed6d2..53ab7e95ee 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp index 8ec8861425..6422b3a88f 100644 --- a/src/test/base32_tests.cpp +++ b/src/test/base32_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 9845df697f..e5a2e28b2e 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp index 54c081b0ef..ccad94d946 100644 --- a/src/test/base64_tests.cpp +++ b/src/test/base64_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/bignum.h b/src/test/bignum.h deleted file mode 100644 index e7aeee9db6..0000000000 --- a/src/test/bignum.h +++ /dev/null @@ -1,180 +0,0 @@ -// 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_TEST_BIGNUM_H -#define BITCOIN_TEST_BIGNUM_H - -#include <algorithm> -#include <limits> -#include <stdexcept> -#include <stdint.h> -#include <string> -#include <vector> - -#include <openssl/bn.h> - -class bignum_error : public std::runtime_error -{ -public: - explicit bignum_error(const std::string& str) : std::runtime_error(str) {} -}; - - -/** C++ wrapper for BIGNUM (OpenSSL bignum) */ -class CBigNum : public BIGNUM -{ -public: - CBigNum() - { - BN_init(this); - } - - CBigNum(const CBigNum& b) - { - BN_init(this); - if (!BN_copy(this, &b)) - { - BN_clear_free(this); - throw bignum_error("CBigNum::CBigNum(const CBigNum&): BN_copy failed"); - } - } - - CBigNum& operator=(const CBigNum& b) - { - if (!BN_copy(this, &b)) - throw bignum_error("CBigNum::operator=: BN_copy failed"); - return (*this); - } - - ~CBigNum() - { - BN_clear_free(this); - } - - CBigNum(long long n) { BN_init(this); setint64(n); } - - explicit CBigNum(const std::vector<unsigned char>& vch) - { - BN_init(this); - setvch(vch); - } - - int getint() const - { - BN_ULONG n = BN_get_word(this); - if (!BN_is_negative(this)) - return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n); - else - return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n); - } - - void setint64(int64_t sn) - { - unsigned char pch[sizeof(sn) + 6]; - unsigned char* p = pch + 4; - bool fNegative; - uint64_t n; - - if (sn < (int64_t)0) - { - // Since the minimum signed integer cannot be represented as positive so long as its type is signed, - // and it's not well-defined what happens if you make it unsigned before negating it, - // we instead increment the negative integer by 1, convert it, then increment the (now positive) unsigned integer by 1 to compensate - n = -(sn + 1); - ++n; - fNegative = true; - } else { - n = sn; - fNegative = false; - } - - bool fLeadingZeroes = true; - for (int i = 0; i < 8; i++) - { - unsigned char c = (n >> 56) & 0xff; - n <<= 8; - if (fLeadingZeroes) - { - if (c == 0) - continue; - if (c & 0x80) - *p++ = (fNegative ? 0x80 : 0); - else if (fNegative) - c |= 0x80; - fLeadingZeroes = false; - } - *p++ = c; - } - unsigned int nSize = p - (pch + 4); - pch[0] = (nSize >> 24) & 0xff; - pch[1] = (nSize >> 16) & 0xff; - pch[2] = (nSize >> 8) & 0xff; - pch[3] = (nSize) & 0xff; - BN_mpi2bn(pch, p - pch, this); - } - - void setvch(const std::vector<unsigned char>& vch) - { - std::vector<unsigned char> vch2(vch.size() + 4); - unsigned int nSize = vch.size(); - // BIGNUM's byte stream format expects 4 bytes of - // big endian size data info at the front - vch2[0] = (nSize >> 24) & 0xff; - vch2[1] = (nSize >> 16) & 0xff; - vch2[2] = (nSize >> 8) & 0xff; - vch2[3] = (nSize >> 0) & 0xff; - // swap data to big endian - reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4); - BN_mpi2bn(&vch2[0], vch2.size(), this); - } - - std::vector<unsigned char> getvch() const - { - unsigned int nSize = BN_bn2mpi(this, NULL); - if (nSize <= 4) - return std::vector<unsigned char>(); - std::vector<unsigned char> vch(nSize); - BN_bn2mpi(this, &vch[0]); - vch.erase(vch.begin(), vch.begin() + 4); - reverse(vch.begin(), vch.end()); - return vch; - } - - friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b); -}; - - - -inline const CBigNum operator+(const CBigNum& a, const CBigNum& b) -{ - CBigNum r; - if (!BN_add(&r, &a, &b)) - throw bignum_error("CBigNum::operator+: BN_add failed"); - return r; -} - -inline const CBigNum operator-(const CBigNum& a, const CBigNum& b) -{ - CBigNum r; - if (!BN_sub(&r, &a, &b)) - throw bignum_error("CBigNum::operator-: BN_sub failed"); - return r; -} - -inline const CBigNum operator-(const CBigNum& a) -{ - CBigNum r(a); - BN_set_negative(&r, !BN_is_negative(&r)); - return r; -} - -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); } -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); } -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 // BITCOIN_TEST_BIGNUM_H diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 69084213a2..ce29e692db 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 6b30d6aa8a..98f9de7673 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp index f7e2470617..c945a95adc 100644 --- a/src/test/checkblock_tests.cpp +++ b/src/test/checkblock_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2014 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 13d848311a..3fe536f91a 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -6,6 +6,8 @@ #include "random.h" #include "uint256.h" #include "test/test_bitcoin.h" +#include "main.h" +#include "consensus/validation.h" #include <vector> #include <map> @@ -45,15 +47,18 @@ public: 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); + if (it->second.flags & CCoinsCacheEntry::DIRTY) { + // Same optimization used in CCoinsViewDB is to only write dirty entries. + 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; + if (!hashBlock.IsNull()) + hashBestBlock_ = hashBlock; return true; } @@ -160,13 +165,22 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test) } if (insecure_rand() % 100 == 0) { + // Every 100 iterations, flush an intermediate cache + if (stack.size() > 1 && insecure_rand() % 2 == 0) { + unsigned int flushIndex = insecure_rand() % (stack.size() - 1); + stack[flushIndex]->Flush(); + } + } + if (insecure_rand() % 100 == 0) { // Every 100 iterations, change the cache stack. if (stack.size() > 0 && insecure_rand() % 2 == 0) { + //Remove the top cache stack.back()->Flush(); delete stack.back(); stack.pop_back(); } if (stack.size() == 0 || (stack.size() < 4 && insecure_rand() % 2)) { + //Add a new cache CCoinsView* tip = &base; if (stack.size() > 0) { tip = stack.back(); @@ -197,4 +211,140 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test) BOOST_CHECK(missed_an_entry); } +// This test is similar to the previous test +// except the emphasis is on testing the functionality of UpdateCoins +// random txs are created and UpdateCoins is used to update the cache stack +// In particular it is tested that spending a duplicate coinbase tx +// has the expected effect (the other duplicate is overwitten at all cache levels) +BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) +{ + bool spent_a_duplicate_coinbase = 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<CCoinsViewCacheTest*> stack; // A stack of CCoinsViewCaches on top. + stack.push_back(new CCoinsViewCacheTest(&base)); // Start with one cache. + + // Track the txids we've used and whether they have been spent or not + std::map<uint256, CAmount> coinbaseids; + std::set<uint256> alltxids; + std::set<uint256> duplicateids; + + for (unsigned int i = 0; i < NUM_SIMULATION_ITERATIONS; i++) { + { + CMutableTransaction tx; + tx.vin.resize(1); + tx.vout.resize(1); + tx.vout[0].nValue = i; //Keep txs unique unless intended to duplicate + unsigned int height = insecure_rand(); + + // 1/10 times create a coinbase + if (insecure_rand() % 10 == 0 || coinbaseids.size() < 10) { + // 1/100 times create a duplicate coinbase + if (insecure_rand() % 10 == 0 && coinbaseids.size()) { + std::map<uint256, CAmount>::iterator coinbaseIt = coinbaseids.lower_bound(GetRandHash()); + if (coinbaseIt == coinbaseids.end()) { + coinbaseIt = coinbaseids.begin(); + } + //Use same random value to have same hash and be a true duplicate + tx.vout[0].nValue = coinbaseIt->second; + assert(tx.GetHash() == coinbaseIt->first); + duplicateids.insert(coinbaseIt->first); + } + else { + coinbaseids[tx.GetHash()] = tx.vout[0].nValue; + } + assert(CTransaction(tx).IsCoinBase()); + } + // 9/10 times create a regular tx + else { + uint256 prevouthash; + // equally likely to spend coinbase or non coinbase + std::set<uint256>::iterator txIt = alltxids.lower_bound(GetRandHash()); + if (txIt == alltxids.end()) { + txIt = alltxids.begin(); + } + prevouthash = *txIt; + + // Construct the tx to spend the coins of prevouthash + tx.vin[0].prevout.hash = prevouthash; + tx.vin[0].prevout.n = 0; + + // Update the expected result of prevouthash to know these coins are spent + CCoins& oldcoins = result[prevouthash]; + oldcoins.Clear(); + + // It is of particular importance here that once we spend a coinbase tx hash + // it is no longer available to be duplicated (or spent again) + // BIP 34 in conjunction with enforcing BIP 30 (at least until BIP 34 was active) + // results in the fact that no coinbases were duplicated after they were already spent + alltxids.erase(prevouthash); + coinbaseids.erase(prevouthash); + + // The test is designed to ensure spending a duplicate coinbase will work properly + // if that ever happens and not resurrect the previously overwritten coinbase + if (duplicateids.count(prevouthash)) + spent_a_duplicate_coinbase = true; + + assert(!CTransaction(tx).IsCoinBase()); + } + // Track this tx to possibly spend later + alltxids.insert(tx.GetHash()); + + // Update the expected result to know about the new output coins + CCoins &coins = result[tx.GetHash()]; + coins.FromTx(tx, height); + + CValidationState dummy; + UpdateCoins(tx, dummy, *(stack.back()), height); + } + + // 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); + } else { + BOOST_CHECK(it->second.IsPruned()); + } + } + } + + if (insecure_rand() % 100 == 0) { + // Every 100 iterations, flush an intermediate cache + if (stack.size() > 1 && insecure_rand() % 2 == 0) { + unsigned int flushIndex = insecure_rand() % (stack.size() - 1); + stack[flushIndex]->Flush(); + } + } + 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(); + } + stack.push_back(new CCoinsViewCacheTest(tip)); + } + } + } + + // Clean up the stack. + while (stack.size() > 0) { + delete stack.back(); + stack.pop_back(); + } + + // Verify coverage. + BOOST_CHECK(spent_a_duplicate_coinbase); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp index 376ae93681..35e4458bba 100644 --- a/src/test/compress_tests.cpp +++ b/src/test/compress_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index aeb2a5caa3..0b46d718d1 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 7afa2abf49..7ce7e0879c 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -160,12 +160,12 @@ ["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "disabled"], ["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "disabled"], -["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"], -["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"], +["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"], ["Ensure 100% coverage of discouraged NOPS"], ["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP2", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index a4e15faeaf..e5f0d17b04 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -232,8 +232,8 @@ ["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC"], -["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"], -["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"], +["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"], ["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "Discourage NOPx flag allows OP_NOP"], @@ -442,7 +442,7 @@ ["NOP", "CODESEPARATOR 1", "P2SH,STRICTENC"], ["NOP", "NOP1 1", "P2SH,STRICTENC"], -["NOP", "NOP2 1", "P2SH,STRICTENC"], +["NOP", "CHECKLOCKTIMEVERIFY 1", "P2SH,STRICTENC"], ["NOP", "NOP3 1", "P2SH,STRICTENC"], ["NOP", "NOP4 1", "P2SH,STRICTENC"], ["NOP", "NOP5 1", "P2SH,STRICTENC"], diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 5cad5af7c3..9025841949 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -64,9 +64,13 @@ [[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]], "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff655151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000", "P2SH"], -["Null txin"], -[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "HASH160 0x14 0x02dae7dbbda56097959cba59b1989dd3e47937bf EQUAL"]], -"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6e49304602210086f39e028e46dafa8e1e3be63906465f4cf038fbe5ed6403dc3e74ae876e6431022100c4625c675cfc5c7e3a0e0d7eaec92ac24da20c73a88eb40d09253e51ac6def5201232103a183ddc41e84753aca47723c965d1b5c8b0e2b537963518355e6dd6cf8415e50acffffffff010000000000000000015100000000", "P2SH"], +["Null txin, but without being a coinbase (because there are two inputs)"], +[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"], + ["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], +"01000000020000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff00010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010000000000000000015100000000", "P2SH"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"], + ["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]], +"010000000200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0000000000000000000000000000000000000000000000000000000000000000ffffffff00ffffffff010000000000000000015100000000", "P2SH"], ["Same as the transactions in valid with one input SIGHASH_ALL and one SIGHASH_ANYONECANPAY, but we set the _ANYONECANPAY sequence number, invalidating the SIGHASH_ALL signature"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"], @@ -123,66 +127,66 @@ ["CHECKLOCKTIMEVERIFY tests"], ["By-height locks, with argument just beyond tx nLockTime"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000fe64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], ["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument missing"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000001b1010000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument negative with by-blockheight nLockTime=0"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument negative with by-blocktime nLockTime=500,000,000"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000004005194b1010000000100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Input locked"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b1ffffffff0100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Another input being unlocked isn't sufficient; the CHECKLOCKTIMEVERIFY-using input must be unlocked"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"] , +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"] , ["0000000000000000000000000000000000000000000000000000000000000200", 1, "1"]], "010000000200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00020000000000000000000000000000000000000000000000000000000000000100000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument/tx height/time mismatch, both versions"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b100000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument 2^32 with nLockTime=2^32-1"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"], ["Same, but with nLockTime=2^31-1"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffff7f", "P2SH,CHECKLOCKTIMEVERIFY"], ["6 byte non-minimally-encoded arguments are invalid even if their contents are valid"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Failure due to failing CHECKLOCKTIMEVERIFY in scriptSig"], @@ -193,5 +197,9 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xc5b93064159b3b2d6ab506a41b1f50463771b988 EQUAL"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000030251b1000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], +["A transaction with a non-standard DER signature."], +[[["b1dbc81696c8a9c0fccd0693ab66d7c368dbc38c0def4e800685560ddd1b2132", 0, "DUP HASH160 0x14 0x4b3bd7eba3bc0284fd3007be7f3be275e94f5826 EQUALVERIFY CHECKSIG"]], +"010000000132211bdd0d568506804eef0d8cc3db68c3d766ab9306cdfcc0a9c89616c8dbb1000000006c493045022100c7bb0faea0522e74ff220c20c022d2cb6033f8d167fb89e75a50e237a35fd6d202203064713491b1f8ad5f79e623d0219ad32510bfaa1009ab30cbee77b59317d6e30001210237af13eb2d84e4545af287b919c2282019c9691cc509e78e196a9d8274ed1be0ffffffff0100000000000000001976a914f1b3ed2eda9a2ebe5a9374f692877cdf87c0f95b88ac00000000", "P2SH,DERSIG"], + ["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 9744a3c848..76d29bcf26 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -190,35 +190,35 @@ ["CHECKLOCKTIMEVERIFY tests"], ["By-height locks, with argument == 0 and == tx nLockTime"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], ["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"], ["Any non-maxint nSequence is fine"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["The argument can be calculated rather than created directly by a PUSHDATA"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 1ADD NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 1ADD CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], ["Perhaps even by an ADD producing a 5-byte result that is out of bounds for other opcodes"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 2147483647 ADD NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 2147483647 ADD CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"], ["5 byte non-minimally-encoded arguments are valid"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Valid CHECKLOCKTIMEVERIFY in scriptSig"], @@ -229,5 +229,9 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xc5b93064159b3b2d6ab506a41b1f50463771b988 EQUAL"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000030251b1000000000100000000000000000001000000", "P2SH,CHECKLOCKTIMEVERIFY"], +["A transaction with a non-standard DER signature."], +[[["b1dbc81696c8a9c0fccd0693ab66d7c368dbc38c0def4e800685560ddd1b2132", 0, "DUP HASH160 0x14 0x4b3bd7eba3bc0284fd3007be7f3be275e94f5826 EQUALVERIFY CHECKSIG"]], +"010000000132211bdd0d568506804eef0d8cc3db68c3d766ab9306cdfcc0a9c89616c8dbb1000000006c493045022100c7bb0faea0522e74ff220c20c022d2cb6033f8d167fb89e75a50e237a35fd6d202203064713491b1f8ad5f79e623d0219ad32510bfaa1009ab30cbee77b59317d6e30001210237af13eb2d84e4545af287b919c2282019c9691cc509e78e196a9d8274ed1be0ffffffff0100000000000000001976a914f1b3ed2eda9a2ebe5a9374f692877cdf87c0f95b88ac00000000", "P2SH"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp new file mode 100644 index 0000000000..e399315870 --- /dev/null +++ b/src/test/dbwrapper_tests.cpp @@ -0,0 +1,207 @@ +// Copyright (c) 2012-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "dbwrapper.h" +#include "uint256.h" +#include "random.h" +#include "test/test_bitcoin.h" + +#include <boost/assign/std/vector.hpp> // for 'operator+=()' +#include <boost/assert.hpp> +#include <boost/test/unit_test.hpp> + +using namespace std; +using namespace boost::assign; // bring 'operator+=()' into scope +using namespace boost::filesystem; + +// Test if a string consists entirely of null characters +bool is_null_key(const vector<unsigned char>& key) { + bool isnull = true; + + for (unsigned int i = 0; i < key.size(); i++) + isnull &= (key[i] == '\x00'); + + return isnull; +} + +BOOST_FIXTURE_TEST_SUITE(dbwrapper_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(dbwrapper) +{ + // Perform tests both obfuscated and non-obfuscated. + for (int i = 0; i < 2; i++) { + bool obfuscate = (bool)i; + path ph = temp_directory_path() / unique_path(); + CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); + char key = 'k'; + uint256 in = GetRandHash(); + uint256 res; + + // Ensure that we're doing real obfuscation when obfuscate=true + BOOST_CHECK(obfuscate != is_null_key(dbw.GetObfuscateKey())); + + BOOST_CHECK(dbw.Write(key, in)); + BOOST_CHECK(dbw.Read(key, res)); + BOOST_CHECK_EQUAL(res.ToString(), in.ToString()); + } +} + +// Test batch operations +BOOST_AUTO_TEST_CASE(dbwrapper_batch) +{ + // Perform tests both obfuscated and non-obfuscated. + for (int i = 0; i < 2; i++) { + bool obfuscate = (bool)i; + path ph = temp_directory_path() / unique_path(); + CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); + + char key = 'i'; + uint256 in = GetRandHash(); + char key2 = 'j'; + uint256 in2 = GetRandHash(); + char key3 = 'k'; + uint256 in3 = GetRandHash(); + + uint256 res; + CDBBatch batch(&dbw.GetObfuscateKey()); + + batch.Write(key, in); + batch.Write(key2, in2); + batch.Write(key3, in3); + + // Remove key3 before it's even been written + batch.Erase(key3); + + dbw.WriteBatch(batch); + + BOOST_CHECK(dbw.Read(key, res)); + BOOST_CHECK_EQUAL(res.ToString(), in.ToString()); + BOOST_CHECK(dbw.Read(key2, res)); + BOOST_CHECK_EQUAL(res.ToString(), in2.ToString()); + + // key3 never should've been written + BOOST_CHECK(dbw.Read(key3, res) == false); + } +} + +BOOST_AUTO_TEST_CASE(dbwrapper_iterator) +{ + // Perform tests both obfuscated and non-obfuscated. + for (int i = 0; i < 2; i++) { + bool obfuscate = (bool)i; + path ph = temp_directory_path() / unique_path(); + CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); + + // The two keys are intentionally chosen for ordering + char key = 'j'; + uint256 in = GetRandHash(); + BOOST_CHECK(dbw.Write(key, in)); + char key2 = 'k'; + uint256 in2 = GetRandHash(); + BOOST_CHECK(dbw.Write(key2, in2)); + + boost::scoped_ptr<CDBIterator> it(const_cast<CDBWrapper*>(&dbw)->NewIterator()); + + // Be sure to seek past the obfuscation key (if it exists) + it->Seek(key); + + char key_res; + uint256 val_res; + + it->GetKey(key_res); + it->GetValue(val_res); + BOOST_CHECK_EQUAL(key_res, key); + BOOST_CHECK_EQUAL(val_res.ToString(), in.ToString()); + + it->Next(); + + it->GetKey(key_res); + it->GetValue(val_res); + BOOST_CHECK_EQUAL(key_res, key2); + BOOST_CHECK_EQUAL(val_res.ToString(), in2.ToString()); + + it->Next(); + BOOST_CHECK_EQUAL(it->Valid(), false); + } +} + +// Test that we do not obfuscation if there is existing data. +BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) +{ + // We're going to share this path between two wrappers + path ph = temp_directory_path() / unique_path(); + create_directories(ph); + + // Set up a non-obfuscated wrapper to write some initial data. + CDBWrapper* dbw = new CDBWrapper(ph, (1 << 10), false, false, false); + char key = 'k'; + uint256 in = GetRandHash(); + uint256 res; + + BOOST_CHECK(dbw->Write(key, in)); + BOOST_CHECK(dbw->Read(key, res)); + BOOST_CHECK_EQUAL(res.ToString(), in.ToString()); + + // Call the destructor to free leveldb LOCK + delete dbw; + + // Now, set up another wrapper that wants to obfuscate the same directory + CDBWrapper odbw(ph, (1 << 10), false, false, true); + + // Check that the key/val we wrote with unobfuscated wrapper exists and + // is readable. + uint256 res2; + BOOST_CHECK(odbw.Read(key, res2)); + BOOST_CHECK_EQUAL(res2.ToString(), in.ToString()); + + BOOST_CHECK(!odbw.IsEmpty()); // There should be existing data + BOOST_CHECK(is_null_key(odbw.GetObfuscateKey())); // The key should be an empty string + + uint256 in2 = GetRandHash(); + uint256 res3; + + // Check that we can write successfully + BOOST_CHECK(odbw.Write(key, in2)); + BOOST_CHECK(odbw.Read(key, res3)); + BOOST_CHECK_EQUAL(res3.ToString(), in2.ToString()); +} + +// Ensure that we start obfuscating during a reindex. +BOOST_AUTO_TEST_CASE(existing_data_reindex) +{ + // We're going to share this path between two wrappers + path ph = temp_directory_path() / unique_path(); + create_directories(ph); + + // Set up a non-obfuscated wrapper to write some initial data. + CDBWrapper* dbw = new CDBWrapper(ph, (1 << 10), false, false, false); + char key = 'k'; + uint256 in = GetRandHash(); + uint256 res; + + BOOST_CHECK(dbw->Write(key, in)); + BOOST_CHECK(dbw->Read(key, res)); + BOOST_CHECK_EQUAL(res.ToString(), in.ToString()); + + // Call the destructor to free leveldb LOCK + delete dbw; + + // Simulate a -reindex by wiping the existing data store + CDBWrapper odbw(ph, (1 << 10), false, true, true); + + // Check that the key/val we wrote with unobfuscated wrapper doesn't exist + uint256 res2; + BOOST_CHECK(!odbw.Read(key, res2)); + BOOST_CHECK(!is_null_key(odbw.GetObfuscateKey())); + + uint256 in2 = GetRandHash(); + uint256 res3; + + // Check that we can write successfully + BOOST_CHECK(odbw.Write(key, in2)); + BOOST_CHECK(odbw.Read(key, res3)); + BOOST_CHECK_EQUAL(res3.ToString(), in2.ToString()); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index eb61a2884d..9f59de3ef5 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index e5d2e5a439..35079d1614 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 13ca949469..4978c95130 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index 21ae46d6e9..dbfbdd934f 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -72,5 +72,4 @@ BOOST_AUTO_TEST_CASE(test_combiner_all) Test.disconnect(&ReturnTrue); BOOST_CHECK(Test()); } - BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index 5bf1e98e8f..1347d23656 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -17,6 +17,7 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) { // Test CTxMemPool::remove functionality + TestMemPoolEntryHelper entry; // Parent transaction with three children, // and three grand-children: CMutableTransaction txParent; @@ -60,17 +61,17 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) BOOST_CHECK_EQUAL(removed.size(), 0); // Just the parent: - testPool.addUnchecked(txParent.GetHash(), CTxMemPoolEntry(txParent, 0, 0, 0.0, 1)); + testPool.addUnchecked(txParent.GetHash(), entry.FromTx(txParent)); testPool.remove(txParent, removed, true); BOOST_CHECK_EQUAL(removed.size(), 1); removed.clear(); // Parent, children, grandchildren: - testPool.addUnchecked(txParent.GetHash(), CTxMemPoolEntry(txParent, 0, 0, 0.0, 1)); + testPool.addUnchecked(txParent.GetHash(), entry.FromTx(txParent)); for (int i = 0; i < 3; i++) { - testPool.addUnchecked(txChild[i].GetHash(), CTxMemPoolEntry(txChild[i], 0, 0, 0.0, 1)); - testPool.addUnchecked(txGrandChild[i].GetHash(), CTxMemPoolEntry(txGrandChild[i], 0, 0, 0.0, 1)); + testPool.addUnchecked(txChild[i].GetHash(), entry.FromTx(txChild[i])); + testPool.addUnchecked(txGrandChild[i].GetHash(), entry.FromTx(txGrandChild[i])); } // Remove Child[0], GrandChild[0] should be removed: testPool.remove(txChild[0], removed, true); @@ -90,8 +91,8 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) // Add children and grandchildren, but NOT the parent (simulate the parent being in a block) for (int i = 0; i < 3; i++) { - testPool.addUnchecked(txChild[i].GetHash(), CTxMemPoolEntry(txChild[i], 0, 0, 0.0, 1)); - testPool.addUnchecked(txGrandChild[i].GetHash(), CTxMemPoolEntry(txGrandChild[i], 0, 0, 0.0, 1)); + testPool.addUnchecked(txChild[i].GetHash(), entry.FromTx(txChild[i])); + testPool.addUnchecked(txGrandChild[i].GetHash(), entry.FromTx(txGrandChild[i])); } // Now remove the parent, as might happen if a block-re-org occurs but the parent cannot be // put into the mempool (maybe because it is non-standard): @@ -101,12 +102,13 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) removed.clear(); } +template<int index> void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder) { BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size()); - CTxMemPool::indexed_transaction_set::nth_index<1>::type::iterator it = pool.mapTx.get<1>().begin(); + typename CTxMemPool::indexed_transaction_set::nth_index<index>::type::iterator it = pool.mapTx.get<index>().begin(); int count=0; - for (; it != pool.mapTx.get<1>().end(); ++it, ++count) { + for (; it != pool.mapTx.get<index>().end(); ++it, ++count) { BOOST_CHECK_EQUAL(it->GetTx().GetHash().ToString(), sortedOrder[count]); } } @@ -114,51 +116,55 @@ void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder) BOOST_AUTO_TEST_CASE(MempoolIndexingTest) { CTxMemPool pool(CFeeRate(0)); + TestMemPoolEntryHelper entry; + entry.hadNoDependencies = true; /* 3rd highest fee */ CMutableTransaction tx1 = CMutableTransaction(); tx1.vout.resize(1); tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx1.vout[0].nValue = 10 * COIN; - pool.addUnchecked(tx1.GetHash(), CTxMemPoolEntry(tx1, 10000LL, 0, 10.0, 1, true)); + pool.addUnchecked(tx1.GetHash(), entry.Fee(10000LL).Priority(10.0).FromTx(tx1)); /* highest fee */ CMutableTransaction tx2 = CMutableTransaction(); tx2.vout.resize(1); tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx2.vout[0].nValue = 2 * COIN; - pool.addUnchecked(tx2.GetHash(), CTxMemPoolEntry(tx2, 20000LL, 0, 9.0, 1, true)); + pool.addUnchecked(tx2.GetHash(), entry.Fee(20000LL).Priority(9.0).FromTx(tx2)); /* lowest fee */ CMutableTransaction tx3 = CMutableTransaction(); tx3.vout.resize(1); tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx3.vout[0].nValue = 5 * COIN; - pool.addUnchecked(tx3.GetHash(), CTxMemPoolEntry(tx3, 0LL, 0, 100.0, 1, true)); + pool.addUnchecked(tx3.GetHash(), entry.Fee(0LL).Priority(100.0).FromTx(tx3)); /* 2nd highest fee */ CMutableTransaction tx4 = CMutableTransaction(); tx4.vout.resize(1); tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx4.vout[0].nValue = 6 * COIN; - pool.addUnchecked(tx4.GetHash(), CTxMemPoolEntry(tx4, 15000LL, 0, 1.0, 1, true)); + pool.addUnchecked(tx4.GetHash(), entry.Fee(15000LL).Priority(1.0).FromTx(tx4)); /* equal fee rate to tx1, but newer */ CMutableTransaction tx5 = CMutableTransaction(); tx5.vout.resize(1); tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx5.vout[0].nValue = 11 * COIN; - pool.addUnchecked(tx5.GetHash(), CTxMemPoolEntry(tx5, 10000LL, 1, 10.0, 1, true)); + entry.nTime = 1; + entry.dPriority = 10.0; + pool.addUnchecked(tx5.GetHash(), entry.Fee(10000LL).FromTx(tx5)); BOOST_CHECK_EQUAL(pool.size(), 5); std::vector<std::string> sortedOrder; sortedOrder.resize(5); - sortedOrder[0] = tx2.GetHash().ToString(); // 20000 - sortedOrder[1] = tx4.GetHash().ToString(); // 15000 + sortedOrder[0] = tx3.GetHash().ToString(); // 0 + sortedOrder[1] = tx5.GetHash().ToString(); // 10000 sortedOrder[2] = tx1.GetHash().ToString(); // 10000 - sortedOrder[3] = tx5.GetHash().ToString(); // 10000 - sortedOrder[4] = tx3.GetHash().ToString(); // 0 - CheckSort(pool, sortedOrder); + sortedOrder[3] = tx4.GetHash().ToString(); // 15000 + sortedOrder[4] = tx2.GetHash().ToString(); // 20000 + CheckSort<1>(pool, sortedOrder); /* low fee but with high fee child */ /* tx6 -> tx7 -> tx8, tx9 -> tx10 */ @@ -166,11 +172,11 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) tx6.vout.resize(1); tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx6.vout[0].nValue = 20 * COIN; - pool.addUnchecked(tx6.GetHash(), CTxMemPoolEntry(tx6, 0LL, 1, 10.0, 1, true)); + pool.addUnchecked(tx6.GetHash(), entry.Fee(0LL).FromTx(tx6)); BOOST_CHECK_EQUAL(pool.size(), 6); // Check that at this point, tx6 is sorted low - sortedOrder.push_back(tx6.GetHash().ToString()); - CheckSort(pool, sortedOrder); + sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString()); + CheckSort<1>(pool, sortedOrder); CTxMemPool::setEntries setAncestors; setAncestors.insert(pool.mapTx.find(tx6.GetHash())); @@ -186,18 +192,17 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) CTxMemPool::setEntries setAncestorsCalculated; std::string dummy; - CTxMemPoolEntry entry7(tx7, 2000000LL, 1, 10.0, 1, true); - BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry7, setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true); + BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry.Fee(2000000LL).FromTx(tx7), setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true); BOOST_CHECK(setAncestorsCalculated == setAncestors); - pool.addUnchecked(tx7.GetHash(), CTxMemPoolEntry(tx7, 2000000LL, 1, 10.0, 1, true), setAncestors); + pool.addUnchecked(tx7.GetHash(), entry.FromTx(tx7), setAncestors); BOOST_CHECK_EQUAL(pool.size(), 7); // Now tx6 should be sorted higher (high fee child): tx7, tx6, tx2, ... - sortedOrder.erase(sortedOrder.end()-1); - sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString()); - sortedOrder.insert(sortedOrder.begin(), tx7.GetHash().ToString()); - CheckSort(pool, sortedOrder); + sortedOrder.erase(sortedOrder.begin()); + sortedOrder.push_back(tx6.GetHash().ToString()); + sortedOrder.push_back(tx7.GetHash().ToString()); + CheckSort<1>(pool, sortedOrder); /* low fee child of tx7 */ CMutableTransaction tx8 = CMutableTransaction(); @@ -208,11 +213,11 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) tx8.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx8.vout[0].nValue = 10 * COIN; setAncestors.insert(pool.mapTx.find(tx7.GetHash())); - pool.addUnchecked(tx8.GetHash(), CTxMemPoolEntry(tx8, 0LL, 2, 10.0, 1, true), setAncestors); + pool.addUnchecked(tx8.GetHash(), entry.Fee(0LL).Time(2).FromTx(tx8), setAncestors); // Now tx8 should be sorted low, but tx6/tx both high - sortedOrder.push_back(tx8.GetHash().ToString()); - CheckSort(pool, sortedOrder); + sortedOrder.insert(sortedOrder.begin(), tx8.GetHash().ToString()); + CheckSort<1>(pool, sortedOrder); /* low fee child of tx7 */ CMutableTransaction tx9 = CMutableTransaction(); @@ -222,12 +227,12 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) tx9.vout.resize(1); tx9.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx9.vout[0].nValue = 1 * COIN; - pool.addUnchecked(tx9.GetHash(), CTxMemPoolEntry(tx9, 0LL, 3, 10.0, 1, true), setAncestors); + pool.addUnchecked(tx9.GetHash(), entry.Fee(0LL).Time(3).FromTx(tx9), setAncestors); // tx9 should be sorted low BOOST_CHECK_EQUAL(pool.size(), 9); - sortedOrder.push_back(tx9.GetHash().ToString()); - CheckSort(pool, sortedOrder); + sortedOrder.insert(sortedOrder.begin(), tx9.GetHash().ToString()); + CheckSort<1>(pool, sortedOrder); std::vector<std::string> snapshotOrder = sortedOrder; @@ -245,32 +250,31 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) tx10.vout[0].nValue = 10 * COIN; setAncestorsCalculated.clear(); - CTxMemPoolEntry entry10(tx10, 200000LL, 4, 10.0, 1, true); - BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry10, setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true); + BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry.Fee(200000LL).Time(4).FromTx(tx10), setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true); BOOST_CHECK(setAncestorsCalculated == setAncestors); - pool.addUnchecked(tx10.GetHash(), CTxMemPoolEntry(tx10, 200000LL, 4, 10.0, 1, true), setAncestors); + pool.addUnchecked(tx10.GetHash(), entry.FromTx(tx10), setAncestors); /** * tx8 and tx9 should both now be sorted higher * Final order after tx10 is added: * - * tx7 = 2.2M (4 txs) - * tx6 = 2.2M (5 txs) - * tx10 = 200k (1 tx) - * tx8 = 200k (2 txs) - * tx9 = 200k (2 txs) - * tx2 = 20000 (1) - * tx4 = 15000 (1) - * tx1 = 10000 (1) - * tx5 = 10000 (1) * tx3 = 0 (1) + * tx5 = 10000 (1) + * tx1 = 10000 (1) + * tx4 = 15000 (1) + * tx2 = 20000 (1) + * tx9 = 200k (2 txs) + * tx8 = 200k (2 txs) + * tx10 = 200k (1 tx) + * tx6 = 2.2M (5 txs) + * tx7 = 2.2M (4 txs) */ - sortedOrder.erase(sortedOrder.end()-2, sortedOrder.end()); // take out tx8, tx9 from the end - sortedOrder.insert(sortedOrder.begin()+2, tx10.GetHash().ToString()); // tx10 is after tx6 - sortedOrder.insert(sortedOrder.begin()+3, tx9.GetHash().ToString()); - sortedOrder.insert(sortedOrder.begin()+3, tx8.GetHash().ToString()); - CheckSort(pool, sortedOrder); + sortedOrder.erase(sortedOrder.begin(), sortedOrder.begin()+2); // take out tx9, tx8 from the beginning + sortedOrder.insert(sortedOrder.begin()+5, tx9.GetHash().ToString()); + sortedOrder.insert(sortedOrder.begin()+6, tx8.GetHash().ToString()); + sortedOrder.insert(sortedOrder.begin()+7, tx10.GetHash().ToString()); // tx10 is just before tx6 + CheckSort<1>(pool, sortedOrder); // there should be 10 transactions in the mempool BOOST_CHECK_EQUAL(pool.size(), 10); @@ -278,7 +282,195 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) // Now try removing tx10 and verify the sort order returns to normal std::list<CTransaction> removed; pool.remove(pool.mapTx.find(tx10.GetHash())->GetTx(), removed, true); - CheckSort(pool, snapshotOrder); + CheckSort<1>(pool, snapshotOrder); + + pool.remove(pool.mapTx.find(tx9.GetHash())->GetTx(), removed, true); + pool.remove(pool.mapTx.find(tx8.GetHash())->GetTx(), removed, true); + /* Now check the sort on the mining score index. + * Final order should be: + * + * tx7 (2M) + * tx2 (20k) + * tx4 (15000) + * tx1/tx5 (10000) + * tx3/6 (0) + * (Ties resolved by hash) + */ + sortedOrder.clear(); + sortedOrder.push_back(tx7.GetHash().ToString()); + sortedOrder.push_back(tx2.GetHash().ToString()); + sortedOrder.push_back(tx4.GetHash().ToString()); + if (tx1.GetHash() < tx5.GetHash()) { + sortedOrder.push_back(tx5.GetHash().ToString()); + sortedOrder.push_back(tx1.GetHash().ToString()); + } else { + sortedOrder.push_back(tx1.GetHash().ToString()); + sortedOrder.push_back(tx5.GetHash().ToString()); + } + if (tx3.GetHash() < tx6.GetHash()) { + sortedOrder.push_back(tx6.GetHash().ToString()); + sortedOrder.push_back(tx3.GetHash().ToString()); + } else { + sortedOrder.push_back(tx3.GetHash().ToString()); + sortedOrder.push_back(tx6.GetHash().ToString()); + } + CheckSort<3>(pool, sortedOrder); +} + + +BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) +{ + CTxMemPool pool(CFeeRate(1000)); + TestMemPoolEntryHelper entry; + entry.dPriority = 10.0; + + CMutableTransaction tx1 = CMutableTransaction(); + tx1.vin.resize(1); + tx1.vin[0].scriptSig = CScript() << OP_1; + tx1.vout.resize(1); + tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL; + tx1.vout[0].nValue = 10 * COIN; + pool.addUnchecked(tx1.GetHash(), entry.Fee(10000LL).FromTx(tx1, &pool)); + + CMutableTransaction tx2 = CMutableTransaction(); + tx2.vin.resize(1); + tx2.vin[0].scriptSig = CScript() << OP_2; + tx2.vout.resize(1); + tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL; + tx2.vout[0].nValue = 10 * COIN; + pool.addUnchecked(tx2.GetHash(), entry.Fee(5000LL).FromTx(tx2, &pool)); + + pool.TrimToSize(pool.DynamicMemoryUsage()); // should do nothing + BOOST_CHECK(pool.exists(tx1.GetHash())); + BOOST_CHECK(pool.exists(tx2.GetHash())); + + pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4); // should remove the lower-feerate transaction + BOOST_CHECK(pool.exists(tx1.GetHash())); + BOOST_CHECK(!pool.exists(tx2.GetHash())); + + pool.addUnchecked(tx2.GetHash(), entry.FromTx(tx2, &pool)); + CMutableTransaction tx3 = CMutableTransaction(); + tx3.vin.resize(1); + tx3.vin[0].prevout = COutPoint(tx2.GetHash(), 0); + tx3.vin[0].scriptSig = CScript() << OP_2; + tx3.vout.resize(1); + tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL; + tx3.vout[0].nValue = 10 * COIN; + pool.addUnchecked(tx3.GetHash(), entry.Fee(20000LL).FromTx(tx3, &pool)); + + pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4); // tx3 should pay for tx2 (CPFP) + BOOST_CHECK(!pool.exists(tx1.GetHash())); + BOOST_CHECK(pool.exists(tx2.GetHash())); + BOOST_CHECK(pool.exists(tx3.GetHash())); + + pool.TrimToSize(::GetSerializeSize(CTransaction(tx1), SER_NETWORK, PROTOCOL_VERSION)); // mempool is limited to tx1's size in memory usage, so nothing fits + BOOST_CHECK(!pool.exists(tx1.GetHash())); + BOOST_CHECK(!pool.exists(tx2.GetHash())); + BOOST_CHECK(!pool.exists(tx3.GetHash())); + + CFeeRate maxFeeRateRemoved(25000, ::GetSerializeSize(CTransaction(tx3), SER_NETWORK, PROTOCOL_VERSION) + ::GetSerializeSize(CTransaction(tx2), SER_NETWORK, PROTOCOL_VERSION)); + BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + 1000); + + CMutableTransaction tx4 = CMutableTransaction(); + tx4.vin.resize(2); + tx4.vin[0].prevout.SetNull(); + tx4.vin[0].scriptSig = CScript() << OP_4; + tx4.vin[1].prevout.SetNull(); + tx4.vin[1].scriptSig = CScript() << OP_4; + tx4.vout.resize(2); + tx4.vout[0].scriptPubKey = CScript() << OP_4 << OP_EQUAL; + tx4.vout[0].nValue = 10 * COIN; + tx4.vout[1].scriptPubKey = CScript() << OP_4 << OP_EQUAL; + tx4.vout[1].nValue = 10 * COIN; + + CMutableTransaction tx5 = CMutableTransaction(); + tx5.vin.resize(2); + tx5.vin[0].prevout = COutPoint(tx4.GetHash(), 0); + tx5.vin[0].scriptSig = CScript() << OP_4; + tx5.vin[1].prevout.SetNull(); + tx5.vin[1].scriptSig = CScript() << OP_5; + tx5.vout.resize(2); + tx5.vout[0].scriptPubKey = CScript() << OP_5 << OP_EQUAL; + tx5.vout[0].nValue = 10 * COIN; + tx5.vout[1].scriptPubKey = CScript() << OP_5 << OP_EQUAL; + tx5.vout[1].nValue = 10 * COIN; + + CMutableTransaction tx6 = CMutableTransaction(); + tx6.vin.resize(2); + tx6.vin[0].prevout = COutPoint(tx4.GetHash(), 1); + tx6.vin[0].scriptSig = CScript() << OP_4; + tx6.vin[1].prevout.SetNull(); + tx6.vin[1].scriptSig = CScript() << OP_6; + tx6.vout.resize(2); + tx6.vout[0].scriptPubKey = CScript() << OP_6 << OP_EQUAL; + tx6.vout[0].nValue = 10 * COIN; + tx6.vout[1].scriptPubKey = CScript() << OP_6 << OP_EQUAL; + tx6.vout[1].nValue = 10 * COIN; + + CMutableTransaction tx7 = CMutableTransaction(); + tx7.vin.resize(2); + tx7.vin[0].prevout = COutPoint(tx5.GetHash(), 0); + tx7.vin[0].scriptSig = CScript() << OP_5; + tx7.vin[1].prevout = COutPoint(tx6.GetHash(), 0); + tx7.vin[1].scriptSig = CScript() << OP_6; + tx7.vout.resize(2); + tx7.vout[0].scriptPubKey = CScript() << OP_7 << OP_EQUAL; + tx7.vout[0].nValue = 10 * COIN; + tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL; + tx7.vout[1].nValue = 10 * COIN; + + pool.addUnchecked(tx4.GetHash(), entry.Fee(7000LL).FromTx(tx4, &pool)); + pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5, &pool)); + pool.addUnchecked(tx6.GetHash(), entry.Fee(1100LL).FromTx(tx6, &pool)); + pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7, &pool)); + + // we only require this remove, at max, 2 txn, because its not clear what we're really optimizing for aside from that + pool.TrimToSize(pool.DynamicMemoryUsage() - 1); + BOOST_CHECK(pool.exists(tx4.GetHash())); + BOOST_CHECK(pool.exists(tx6.GetHash())); + BOOST_CHECK(!pool.exists(tx7.GetHash())); + + if (!pool.exists(tx5.GetHash())) + pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5, &pool)); + pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7, &pool)); + + pool.TrimToSize(pool.DynamicMemoryUsage() / 2); // should maximize mempool size by only removing 5/7 + BOOST_CHECK(pool.exists(tx4.GetHash())); + BOOST_CHECK(!pool.exists(tx5.GetHash())); + BOOST_CHECK(pool.exists(tx6.GetHash())); + BOOST_CHECK(!pool.exists(tx7.GetHash())); + + pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5, &pool)); + pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7, &pool)); + + std::vector<CTransaction> vtx; + std::list<CTransaction> conflicts; + SetMockTime(42); + SetMockTime(42 + CTxMemPool::ROLLING_FEE_HALFLIFE); + BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + 1000); + // ... we should keep the same min fee until we get a block + pool.removeForBlock(vtx, 1, conflicts); + SetMockTime(42 + 2*CTxMemPool::ROLLING_FEE_HALFLIFE); + BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), (maxFeeRateRemoved.GetFeePerK() + 1000)/2); + // ... then feerate should drop 1/2 each halflife + + SetMockTime(42 + 2*CTxMemPool::ROLLING_FEE_HALFLIFE + CTxMemPool::ROLLING_FEE_HALFLIFE/2); + BOOST_CHECK_EQUAL(pool.GetMinFee(pool.DynamicMemoryUsage() * 5 / 2).GetFeePerK(), (maxFeeRateRemoved.GetFeePerK() + 1000)/4); + // ... with a 1/2 halflife when mempool is < 1/2 its target size + + SetMockTime(42 + 2*CTxMemPool::ROLLING_FEE_HALFLIFE + CTxMemPool::ROLLING_FEE_HALFLIFE/2 + CTxMemPool::ROLLING_FEE_HALFLIFE/4); + BOOST_CHECK_EQUAL(pool.GetMinFee(pool.DynamicMemoryUsage() * 9 / 2).GetFeePerK(), (maxFeeRateRemoved.GetFeePerK() + 1000)/8); + // ... with a 1/4 halflife when mempool is < 1/4 its target size + + SetMockTime(42 + 7*CTxMemPool::ROLLING_FEE_HALFLIFE + CTxMemPool::ROLLING_FEE_HALFLIFE/2 + CTxMemPool::ROLLING_FEE_HALFLIFE/4); + BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), 1000); + // ... but feerate should never drop below 1000 + + SetMockTime(42 + 8*CTxMemPool::ROLLING_FEE_HALFLIFE + CTxMemPool::ROLLING_FEE_HALFLIFE/2 + CTxMemPool::ROLLING_FEE_HALFLIFE/4); + BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), 0); + // ... unless it has gone all the way to 0 (after getting past 1000/2) + + SetMockTime(0); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/merkle_tests.cpp b/src/test/merkle_tests.cpp new file mode 100644 index 0000000000..1e31f2e679 --- /dev/null +++ b/src/test/merkle_tests.cpp @@ -0,0 +1,136 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "consensus/merkle.h" +#include "test/test_bitcoin.h" +#include "random.h" + +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(merkle_tests, TestingSetup) + +// Older version of the merkle root computation code, for comparison. +static uint256 BlockBuildMerkleTree(const CBlock& block, bool* fMutated, std::vector<uint256>& vMerkleTree) +{ + vMerkleTree.clear(); + vMerkleTree.reserve(block.vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes. + for (std::vector<CTransaction>::const_iterator it(block.vtx.begin()); it != block.vtx.end(); ++it) + vMerkleTree.push_back(it->GetHash()); + int j = 0; + bool mutated = false; + for (int nSize = block.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(vMerkleTree[j+i].begin(), vMerkleTree[j+i].end(), + vMerkleTree[j+i2].begin(), vMerkleTree[j+i2].end())); + } + j += nSize; + } + if (fMutated) { + *fMutated = mutated; + } + return (vMerkleTree.empty() ? uint256() : vMerkleTree.back()); +} + +// Older version of the merkle branch computation code, for comparison. +static std::vector<uint256> BlockGetMerkleBranch(const CBlock& block, const std::vector<uint256>& vMerkleTree, int nIndex) +{ + std::vector<uint256> vMerkleBranch; + int j = 0; + for (int nSize = block.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; +} + +static inline int ctz(uint32_t i) { + if (i == 0) return 0; + int j = 0; + while (!(i & 1)) { + j++; + i >>= 1; + } + return j; +} + +BOOST_AUTO_TEST_CASE(merkle_test) +{ + for (int i = 0; i < 32; i++) { + // Try 32 block sizes: all sizes from 0 to 16 inclusive, and then 15 random sizes. + int ntx = (i <= 16) ? i : 17 + (insecure_rand() % 4000); + // Try up to 3 mutations. + for (int mutate = 0; mutate <= 3; mutate++) { + int duplicate1 = mutate >= 1 ? 1 << ctz(ntx) : 0; // The last how many transactions to duplicate first. + if (duplicate1 >= ntx) break; // Duplication of the entire tree results in a different root (it adds a level). + int ntx1 = ntx + duplicate1; // The resulting number of transactions after the first duplication. + int duplicate2 = mutate >= 2 ? 1 << ctz(ntx1) : 0; // Likewise for the second mutation. + if (duplicate2 >= ntx1) break; + int ntx2 = ntx1 + duplicate2; + int duplicate3 = mutate >= 3 ? 1 << ctz(ntx2) : 0; // And for the the third mutation. + if (duplicate3 >= ntx2) break; + int ntx3 = ntx2 + duplicate3; + // Build a block with ntx different transactions. + CBlock block; + block.vtx.resize(ntx); + for (int j = 0; j < ntx; j++) { + CMutableTransaction mtx; + mtx.nLockTime = j; + block.vtx[j] = mtx; + } + // Compute the root of the block before mutating it. + bool unmutatedMutated = false; + uint256 unmutatedRoot = BlockMerkleRoot(block, &unmutatedMutated); + BOOST_CHECK(unmutatedMutated == false); + // Optionally mutate by duplicating the last transactions, resulting in the same merkle root. + block.vtx.resize(ntx3); + for (int j = 0; j < duplicate1; j++) { + block.vtx[ntx + j] = block.vtx[ntx + j - duplicate1]; + } + for (int j = 0; j < duplicate2; j++) { + block.vtx[ntx1 + j] = block.vtx[ntx1 + j - duplicate2]; + } + for (int j = 0; j < duplicate3; j++) { + block.vtx[ntx2 + j] = block.vtx[ntx2 + j - duplicate3]; + } + // Compute the merkle root and merkle tree using the old mechanism. + bool oldMutated = false; + std::vector<uint256> merkleTree; + uint256 oldRoot = BlockBuildMerkleTree(block, &oldMutated, merkleTree); + // Compute the merkle root using the new mechanism. + bool newMutated = false; + uint256 newRoot = BlockMerkleRoot(block, &newMutated); + BOOST_CHECK(oldRoot == newRoot); + BOOST_CHECK(newRoot == unmutatedRoot); + BOOST_CHECK((newRoot == uint256()) == (ntx == 0)); + BOOST_CHECK(oldMutated == newMutated); + BOOST_CHECK(newMutated == !!mutate); + // If no mutation was done (once for every ntx value), try up to 16 branches. + if (mutate == 0) { + for (int loop = 0; loop < std::min(ntx, 16); loop++) { + // If ntx <= 16, try all branches. Otherise, try 16 random ones. + int mtx = loop; + if (ntx > 16) { + mtx = insecure_rand() % ntx; + } + std::vector<uint256> newBranch = BlockMerkleBranch(block, mtx); + std::vector<uint256> oldBranch = BlockGetMerkleBranch(block, merkleTree, mtx); + BOOST_CHECK(oldBranch == newBranch); + BOOST_CHECK(ComputeMerkleRootFromBranch(block.vtx[mtx].GetHash(), newBranch, mtx) == oldRoot); + } + } + } + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 91a3a5738e..71b52409b3 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -1,9 +1,11 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "chainparams.h" #include "coins.h" +#include "consensus/consensus.h" +#include "consensus/merkle.h" #include "consensus/validation.h" #include "main.h" #include "miner.h" @@ -58,17 +60,22 @@ struct { // NOTE: These tests rely on CreateNewBlock doing its own self-validation! BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { + const CChainParams& chainparams = Params(CBaseChainParams::MAIN); CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; CBlockTemplate *pblocktemplate; CMutableTransaction tx,tx2; CScript script; uint256 hash; + TestMemPoolEntryHelper entry; + entry.nFee = 11; + entry.dPriority = 111.0; + entry.nHeight = 11; LOCK(cs_main); fCheckpointsEnabled = false; // Simple block creation, nothing special yet: - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) @@ -87,17 +94,17 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) pblock->vtx[0] = CTransaction(txCoinbase); if (txFirst.size() < 2) txFirst.push_back(new CTransaction(pblock->vtx[0])); - pblock->hashMerkleRoot = pblock->ComputeMerkleRoot(); + pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); pblock->nNonce = blockinfo[i].nonce; CValidationState state; - BOOST_CHECK(ProcessNewBlock(state, NULL, pblock, true, NULL)); + BOOST_CHECK(ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL)); BOOST_CHECK(state.IsValid()); pblock->hashPrevBlock = pblock->GetHash(); } delete pblocktemplate; // Just to make sure we can still make simple blocks - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; // block sigops > limit: 1000 CHECKMULTISIG + 1 @@ -112,10 +119,26 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { tx.vout[0].nValue -= 1000000; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase + // If we don't set the # of sig ops in the CTxMemPoolEntry, template creation fails + mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); + mempool.clear(); + + tx.vin[0].prevout.hash = txFirst[0]->GetHash(); + tx.vout[0].nValue = 5000000000LL; + for (unsigned int i = 0; i < 1001; ++i) + { + tx.vout[0].nValue -= 1000000; + hash = tx.GetHash(); + bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase + // If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes + mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOps(20).FromTx(tx)); + tx.vin[0].prevout.hash = hash; + } + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -132,18 +155,18 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { tx.vout[0].nValue -= 10000000; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase + mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; mempool.clear(); - // orphan in mempool + // orphan in mempool, template creation fails hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); - delete pblocktemplate; + mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).FromTx(tx)); + BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); // child with higher priority than parent @@ -151,7 +174,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].prevout.hash = txFirst[1]->GetHash(); tx.vout[0].nValue = 4900000000LL; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + mempool.addUnchecked(hash, entry.Fee(100000000LL).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vin[0].prevout.hash = hash; tx.vin.resize(2); tx.vin[1].scriptSig = CScript() << OP_1; @@ -159,23 +182,23 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[1].prevout.n = 0; tx.vout[0].nValue = 5900000000LL; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + mempool.addUnchecked(hash, entry.Fee(400000000LL).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; mempool.clear(); - // coinbase in mempool + // coinbase in mempool, template creation fails tx.vin.resize(1); tx.vin[0].prevout.SetNull(); tx.vin[0].scriptSig = CScript() << OP_0 << OP_1; tx.vout[0].nValue = 0; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); - delete pblocktemplate; + // give it a fee so it'll get mined + mempool.addUnchecked(hash, entry.Fee(100000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); - // invalid (pre-p2sh) txn in mempool + // invalid (pre-p2sh) txn in mempool, template creation fails tx.vin[0].prevout.hash = txFirst[0]->GetHash(); tx.vin[0].prevout.n = 0; tx.vin[0].scriptSig = CScript() << OP_1; @@ -183,37 +206,35 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) script = CScript() << OP_0; tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script)); hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + mempool.addUnchecked(hash, entry.Fee(10000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vin[0].prevout.hash = hash; - tx.vin[0].scriptSig = CScript() << (std::vector<unsigned char>)script; + tx.vin[0].scriptSig = CScript() << std::vector<unsigned char>(script.begin(), script.end()); tx.vout[0].nValue -= 1000000; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); - delete pblocktemplate; + mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); - // double spend txn pair in mempool + // double spend txn pair in mempool, template creation fails tx.vin[0].prevout.hash = txFirst[0]->GetHash(); tx.vin[0].scriptSig = CScript() << OP_1; tx.vout[0].nValue = 4900000000LL; tx.vout[0].scriptPubKey = CScript() << OP_1; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); - delete pblocktemplate; + mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); // subsidy changing int nHeight = chainActive.Height(); chainActive.Tip()->nHeight = 209999; - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; chainActive.Tip()->nHeight = 210000; - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; chainActive.Tip()->nHeight = nHeight; @@ -228,8 +249,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].scriptPubKey = CScript() << OP_1; tx.nLockTime = chainActive.Tip()->nHeight+1; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(!CheckFinalTx(tx)); + mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + BOOST_CHECK(!CheckFinalTx(tx, LOCKTIME_MEDIAN_TIME_PAST)); // time locked tx2.vin.resize(1); @@ -242,10 +263,10 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx2.vout[0].scriptPubKey = CScript() << OP_1; tx2.nLockTime = chainActive.Tip()->GetMedianTimePast()+1; hash = tx2.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11)); - BOOST_CHECK(!CheckFinalTx(tx2)); + mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx2)); + BOOST_CHECK(!CheckFinalTx(tx2, LOCKTIME_MEDIAN_TIME_PAST)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); // Neither tx should have make it into the template. BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1); @@ -260,8 +281,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) //BOOST_CHECK(CheckFinalTx(tx)); //BOOST_CHECK(CheckFinalTx(tx2)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); - BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3); + BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); + BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 2); delete pblocktemplate; chainActive.Tip()->nHeight--; diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp deleted file mode 100644 index 2b68f8899e..0000000000 --- a/src/test/mruset_tests.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "mruset.h" - -#include "random.h" -#include "util.h" -#include "test/test_bitcoin.h" - -#include <set> - -#include <boost/test/unit_test.hpp> - -#define NUM_TESTS 16 -#define MAX_SIZE 100 - -using namespace std; - -BOOST_FIXTURE_TEST_SUITE(mruset_tests, BasicTestingSetup) - -BOOST_AUTO_TEST_CASE(mruset_test) -{ - // The mruset being tested. - mruset<int> mru(5000); - - // Run the test 10 times. - for (int test = 0; test < 10; test++) { - // Reset mru. - mru.clear(); - - // A deque + set to simulate the mruset. - std::deque<int> rep; - std::set<int> all; - - // Insert 10000 random integers below 15000. - for (int j=0; j<10000; j++) { - int add = GetRandInt(15000); - mru.insert(add); - - // Add the number to rep/all as well. - if (all.count(add) == 0) { - all.insert(add); - rep.push_back(add); - if (all.size() == 5001) { - all.erase(rep.front()); - rep.pop_front(); - } - } - - // Do a full comparison between mru and the simulated mru every 1000 and every 5001 elements. - if (j % 1000 == 0 || j % 5001 == 0) { - mruset<int> mru2 = mru; // Also try making a copy - - // Check that all elements that should be in there, are in there. - BOOST_FOREACH(int x, rep) { - BOOST_CHECK(mru.count(x)); - BOOST_CHECK(mru2.count(x)); - } - - // Check that all elements that are in there, should be in there. - BOOST_FOREACH(int x, mru) { - BOOST_CHECK(all.count(x)); - } - - // Check that all elements that are in there, should be in there. - BOOST_FOREACH(int x, mru2) { - BOOST_CHECK(all.count(x)); - } - - for (int t = 0; t < 10; t++) { - int r = GetRandInt(15000); - BOOST_CHECK(all.count(r) == mru.count(r)); - BOOST_CHECK(all.count(r) == mru2.count(r)); - } - } - } - } -} - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index b1ef0ed24a..4168f75e9a 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index d9f3c3e467..113b9437e0 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -1,7 +1,8 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "consensus/merkle.h" #include "merkleblock.h" #include "serialize.h" #include "streams.h" @@ -48,7 +49,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1) } // calculate actual merkle root and height - uint256 merkleRoot1 = block.ComputeMerkleRoot(); + uint256 merkleRoot1 = BlockMerkleRoot(block); std::vector<uint256> vTxid(nTx, uint256()); for (unsigned int j=0; j<nTx; j++) vTxid[j] = block.vtx[j].GetHash(); diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index cb64ee7c69..644c3da213 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -16,6 +16,7 @@ BOOST_FIXTURE_TEST_SUITE(policyestimator_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) { CTxMemPool mpool(CFeeRate(1000)); + TestMemPoolEntryHelper entry; CAmount basefee(2000); double basepri = 1e6; CAmount deltaFee(100); @@ -63,7 +64,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx tx.vin[0].prevout.n = 10000*blocknum+100*j+k; // make transaction unique uint256 hash = tx.GetHash(); - mpool.addUnchecked(hash, CTxMemPoolEntry(tx, feeV[k/4][j], GetTime(), priV[k/4][j], blocknum, mpool.HasNoInputsOf(tx))); + mpool.addUnchecked(hash, entry.Fee(feeV[k/4][j]).Time(GetTime()).Priority(priV[k/4][j]).Height(blocknum).FromTx(tx, &mpool)); txHashes[j].push_back(hash); } } @@ -83,11 +84,18 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) block.clear(); if (blocknum == 30) { // At this point we should need to combine 5 buckets to get enough data points - // So estimateFee(1) should fail and estimateFee(2) should return somewhere around - // 8*baserate + // So estimateFee(1,2,3) should fail and estimateFee(4) should return somewhere around + // 8*baserate. estimateFee(4) %'s are 100,100,100,100,90 = average 98% BOOST_CHECK(mpool.estimateFee(1) == CFeeRate(0)); - BOOST_CHECK(mpool.estimateFee(2).GetFeePerK() < 8*baseRate.GetFeePerK() + deltaFee); - BOOST_CHECK(mpool.estimateFee(2).GetFeePerK() > 8*baseRate.GetFeePerK() - deltaFee); + BOOST_CHECK(mpool.estimateFee(2) == CFeeRate(0)); + BOOST_CHECK(mpool.estimateFee(3) == CFeeRate(0)); + BOOST_CHECK(mpool.estimateFee(4).GetFeePerK() < 8*baseRate.GetFeePerK() + deltaFee); + BOOST_CHECK(mpool.estimateFee(4).GetFeePerK() > 8*baseRate.GetFeePerK() - deltaFee); + int answerFound; + BOOST_CHECK(mpool.estimateSmartFee(1, &answerFound) == mpool.estimateFee(4) && answerFound == 4); + BOOST_CHECK(mpool.estimateSmartFee(3, &answerFound) == mpool.estimateFee(4) && answerFound == 4); + BOOST_CHECK(mpool.estimateSmartFee(4, &answerFound) == mpool.estimateFee(4) && answerFound == 4); + BOOST_CHECK(mpool.estimateSmartFee(8, &answerFound) == mpool.estimateFee(8) && answerFound == 8); } } @@ -96,9 +104,9 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) // Highest feerate is 10*baseRate and gets in all blocks, // second highest feerate is 9*baseRate and gets in 9/10 blocks = 90%, // third highest feerate is 8*base rate, and gets in 8/10 blocks = 80%, - // so estimateFee(1) should return 9*baseRate. - // Third highest feerate has 90% chance of being included by 2 blocks, - // so estimateFee(2) should return 8*baseRate etc... + // so estimateFee(1) should return 10*baseRate. + // Second highest feerate has 100% chance of being included by 2 blocks, + // so estimateFee(2) should return 9*baseRate etc... for (int i = 1; i < 10;i++) { origFeeEst.push_back(mpool.estimateFee(i).GetFeePerK()); origPriEst.push_back(mpool.estimatePriority(i)); @@ -106,10 +114,11 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) BOOST_CHECK(origFeeEst[i-1] <= origFeeEst[i-2]); BOOST_CHECK(origPriEst[i-1] <= origPriEst[i-2]); } - BOOST_CHECK(origFeeEst[i-1] < (10-i)*baseRate.GetFeePerK() + deltaFee); - BOOST_CHECK(origFeeEst[i-1] > (10-i)*baseRate.GetFeePerK() - deltaFee); - BOOST_CHECK(origPriEst[i-1] < pow(10,10-i) * basepri + deltaPri); - BOOST_CHECK(origPriEst[i-1] > pow(10,10-i) * basepri - deltaPri); + int mult = 11-i; + BOOST_CHECK(origFeeEst[i-1] < mult*baseRate.GetFeePerK() + deltaFee); + BOOST_CHECK(origFeeEst[i-1] > mult*baseRate.GetFeePerK() - deltaFee); + BOOST_CHECK(origPriEst[i-1] < pow(10,mult) * basepri + deltaPri); + BOOST_CHECK(origPriEst[i-1] > pow(10,mult) * basepri - deltaPri); } // Mine 50 more blocks with no transactions happening, estimates shouldn't change @@ -132,16 +141,19 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx tx.vin[0].prevout.n = 10000*blocknum+100*j+k; uint256 hash = tx.GetHash(); - mpool.addUnchecked(hash, CTxMemPoolEntry(tx, feeV[k/4][j], GetTime(), priV[k/4][j], blocknum, mpool.HasNoInputsOf(tx))); + mpool.addUnchecked(hash, entry.Fee(feeV[k/4][j]).Time(GetTime()).Priority(priV[k/4][j]).Height(blocknum).FromTx(tx, &mpool)); txHashes[j].push_back(hash); } } mpool.removeForBlock(block, ++blocknum, dummyConflicted); } + int answerFound; for (int i = 1; i < 10;i++) { - BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); - BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri); + BOOST_CHECK(mpool.estimateFee(i) == CFeeRate(0) || mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); + BOOST_CHECK(mpool.estimateSmartFee(i, &answerFound).GetFeePerK() > origFeeEst[answerFound-1] - deltaFee); + BOOST_CHECK(mpool.estimatePriority(i) == -1 || mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri); + BOOST_CHECK(mpool.estimateSmartPriority(i, &answerFound) > origPriEst[answerFound-1] - deltaPri); } // Mine all those transactions @@ -161,14 +173,14 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri); } - // Mine 100 more blocks where everything is mined every block - // Estimates should be below original estimates (not possible for last estimate) - while (blocknum < 365) { + // Mine 200 more blocks where everything is mined every block + // Estimates should be below original estimates + while (blocknum < 465) { for (int j = 0; j < 10; j++) { // For each fee/pri multiple for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx tx.vin[0].prevout.n = 10000*blocknum+100*j+k; uint256 hash = tx.GetHash(); - mpool.addUnchecked(hash, CTxMemPoolEntry(tx, feeV[k/4][j], GetTime(), priV[k/4][j], blocknum, mpool.HasNoInputsOf(tx))); + mpool.addUnchecked(hash, entry.Fee(feeV[k/4][j]).Time(GetTime()).Priority(priV[k/4][j]).Height(blocknum).FromTx(tx, &mpool)); CTransaction btx; if (mpool.lookup(hash, btx)) block.push_back(btx); @@ -177,10 +189,22 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) mpool.removeForBlock(block, ++blocknum, dummyConflicted); block.clear(); } - for (int i = 1; i < 9; i++) { + for (int i = 1; i < 10; i++) { BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] - deltaFee); BOOST_CHECK(mpool.estimatePriority(i) < origPriEst[i-1] - deltaPri); } + + // Test that if the mempool is limited, estimateSmartFee won't return a value below the mempool min fee + // and that estimateSmartPriority returns essentially an infinite value + mpool.addUnchecked(tx.GetHash(), entry.Fee(feeV[0][5]).Time(GetTime()).Priority(priV[1][5]).Height(blocknum).FromTx(tx, &mpool)); + // evict that transaction which should set a mempool min fee of minRelayTxFee + feeV[0][5] + mpool.TrimToSize(1); + BOOST_CHECK(mpool.GetMinFee(1).GetFeePerK() > feeV[0][5]); + for (int i = 1; i < 10; i++) { + BOOST_CHECK(mpool.estimateSmartFee(i).GetFeePerK() >= mpool.estimateFee(i).GetFeePerK()); + BOOST_CHECK(mpool.estimateSmartFee(i).GetFeePerK() >= mpool.GetMinFee(1).GetFeePerK()); + BOOST_CHECK(mpool.estimateSmartPriority(i) == INF_PRIORITY); + } } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp new file mode 100644 index 0000000000..01a45b540d --- /dev/null +++ b/src/test/prevector_tests.cpp @@ -0,0 +1,217 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <vector> +#include "prevector.h" +#include "random.h" + +#include "serialize.h" +#include "streams.h" + +#include "test/test_bitcoin.h" + +#include <boost/test/unit_test.hpp> + +BOOST_FIXTURE_TEST_SUITE(PrevectorTests, TestingSetup) + +template<unsigned int N, typename T> +class prevector_tester { + typedef std::vector<T> realtype; + realtype real_vector; + + typedef prevector<N, T> pretype; + pretype pre_vector; + + typedef typename pretype::size_type Size; + + void test() { + const pretype& const_pre_vector = pre_vector; + BOOST_CHECK_EQUAL(real_vector.size(), pre_vector.size()); + BOOST_CHECK_EQUAL(real_vector.empty(), pre_vector.empty()); + for (Size s = 0; s < real_vector.size(); s++) { + BOOST_CHECK(real_vector[s] == pre_vector[s]); + BOOST_CHECK(&(pre_vector[s]) == &(pre_vector.begin()[s])); + BOOST_CHECK(&(pre_vector[s]) == &*(pre_vector.begin() + s)); + BOOST_CHECK(&(pre_vector[s]) == &*((pre_vector.end() + s) - real_vector.size())); + } + // BOOST_CHECK(realtype(pre_vector) == real_vector); + BOOST_CHECK(pretype(real_vector.begin(), real_vector.end()) == pre_vector); + BOOST_CHECK(pretype(pre_vector.begin(), pre_vector.end()) == pre_vector); + size_t pos = 0; + BOOST_FOREACH(const T& v, pre_vector) { + BOOST_CHECK(v == real_vector[pos++]); + } + BOOST_REVERSE_FOREACH(const T& v, pre_vector) { + BOOST_CHECK(v == real_vector[--pos]); + } + BOOST_FOREACH(const T& v, const_pre_vector) { + BOOST_CHECK(v == real_vector[pos++]); + } + BOOST_REVERSE_FOREACH(const T& v, const_pre_vector) { + BOOST_CHECK(v == real_vector[--pos]); + } + CDataStream ss1(SER_DISK, 0); + CDataStream ss2(SER_DISK, 0); + ss1 << real_vector; + ss2 << pre_vector; + BOOST_CHECK_EQUAL(ss1.size(), ss2.size()); + for (Size s = 0; s < ss1.size(); s++) { + BOOST_CHECK_EQUAL(ss1[s], ss2[s]); + } + } + +public: + void resize(Size s) { + real_vector.resize(s); + BOOST_CHECK_EQUAL(real_vector.size(), s); + pre_vector.resize(s); + BOOST_CHECK_EQUAL(pre_vector.size(), s); + test(); + } + + void reserve(Size s) { + real_vector.reserve(s); + BOOST_CHECK(real_vector.capacity() >= s); + pre_vector.reserve(s); + BOOST_CHECK(pre_vector.capacity() >= s); + test(); + } + + void insert(Size position, const T& value) { + real_vector.insert(real_vector.begin() + position, value); + pre_vector.insert(pre_vector.begin() + position, value); + test(); + } + + void insert(Size position, Size count, const T& value) { + real_vector.insert(real_vector.begin() + position, count, value); + pre_vector.insert(pre_vector.begin() + position, count, value); + test(); + } + + template<typename I> + void insert_range(Size position, I first, I last) { + real_vector.insert(real_vector.begin() + position, first, last); + pre_vector.insert(pre_vector.begin() + position, first, last); + test(); + } + + void erase(Size position) { + real_vector.erase(real_vector.begin() + position); + pre_vector.erase(pre_vector.begin() + position); + test(); + } + + void erase(Size first, Size last) { + real_vector.erase(real_vector.begin() + first, real_vector.begin() + last); + pre_vector.erase(pre_vector.begin() + first, pre_vector.begin() + last); + test(); + } + + void update(Size pos, const T& value) { + real_vector[pos] = value; + pre_vector[pos] = value; + test(); + } + + void push_back(const T& value) { + real_vector.push_back(value); + pre_vector.push_back(value); + test(); + } + + void pop_back() { + real_vector.pop_back(); + pre_vector.pop_back(); + test(); + } + + void clear() { + real_vector.clear(); + pre_vector.clear(); + } + + void assign(Size n, const T& value) { + real_vector.assign(n, value); + pre_vector.assign(n, value); + } + + Size size() { + return real_vector.size(); + } + + Size capacity() { + return pre_vector.capacity(); + } + + void shrink_to_fit() { + pre_vector.shrink_to_fit(); + test(); + } +}; + +BOOST_AUTO_TEST_CASE(PrevectorTestInt) +{ + for (int j = 0; j < 64; j++) { + prevector_tester<8, int> test; + for (int i = 0; i < 2048; i++) { + int r = insecure_rand(); + if ((r % 4) == 0) { + test.insert(insecure_rand() % (test.size() + 1), insecure_rand()); + } + if (test.size() > 0 && ((r >> 2) % 4) == 1) { + test.erase(insecure_rand() % test.size()); + } + if (((r >> 4) % 8) == 2) { + int new_size = std::max<int>(0, std::min<int>(30, test.size() + (insecure_rand() % 5) - 2)); + test.resize(new_size); + } + if (((r >> 7) % 8) == 3) { + test.insert(insecure_rand() % (test.size() + 1), 1 + (insecure_rand() % 2), insecure_rand()); + } + if (((r >> 10) % 8) == 4) { + int del = std::min<int>(test.size(), 1 + (insecure_rand() % 2)); + int beg = insecure_rand() % (test.size() + 1 - del); + test.erase(beg, beg + del); + } + if (((r >> 13) % 16) == 5) { + test.push_back(insecure_rand()); + } + if (test.size() > 0 && ((r >> 17) % 16) == 6) { + test.pop_back(); + } + if (((r >> 21) % 32) == 7) { + int values[4]; + int num = 1 + (insecure_rand() % 4); + for (int i = 0; i < num; i++) { + values[i] = insecure_rand(); + } + test.insert_range(insecure_rand() % (test.size() + 1), values, values + num); + } + if (((r >> 26) % 32) == 8) { + int del = std::min<int>(test.size(), 1 + (insecure_rand() % 4)); + int beg = insecure_rand() % (test.size() + 1 - del); + test.erase(beg, beg + del); + } + r = insecure_rand(); + if (r % 32 == 9) { + test.reserve(insecure_rand() % 32); + } + if ((r >> 5) % 64 == 10) { + test.shrink_to_fit(); + } + if (test.size() > 0) { + test.update(insecure_rand() % test.size(), insecure_rand()); + } + if (((r >> 11) & 1024) == 11) { + test.clear(); + } + if (((r >> 21) & 512) == 12) { + test.assign(insecure_rand() % 32, insecure_rand()); + } + } + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/reverselock_tests.cpp b/src/test/reverselock_tests.cpp index e7e627ae0f..8bdff97000 100644 --- a/src/test/reverselock_tests.cpp +++ b/src/test/reverselock_tests.cpp @@ -42,22 +42,18 @@ BOOST_AUTO_TEST_CASE(reverselock_errors) BOOST_CHECK(failed); BOOST_CHECK(!lock.owns_lock()); - // Make sure trying to lock a lock after it has been reverse locked fails - failed = false; - bool locked = false; + // Locking the original lock after it has been taken by a reverse lock + // makes no sense. Ensure that the original lock no longer owns the lock + // after giving it to a reverse one. lock.lock(); BOOST_CHECK(lock.owns_lock()); - - try { + { reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock); - lock.lock(); - locked = true; - } catch(...) { - failed = true; + BOOST_CHECK(!lock.owns_lock()); } - BOOST_CHECK(locked && failed); + BOOST_CHECK(failed); BOOST_CHECK(lock.owns_lock()); } diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 2a486f08e4..cc52e3ea06 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -72,6 +72,7 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams) BOOST_CHECK_THROW(CallRPC("decoderawtransaction DEADBEEF"), runtime_error); string rawtx = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000"; BOOST_CHECK_NO_THROW(r = CallRPC(string("decoderawtransaction ")+rawtx)); + BOOST_CHECK_EQUAL(find_value(r.get_obj(), "size").get_int(), 193); BOOST_CHECK_EQUAL(find_value(r.get_obj(), "version").get_int(), 1); BOOST_CHECK_EQUAL(find_value(r.get_obj(), "locktime").get_int(), 0); BOOST_CHECK_THROW(r = CallRPC(string("decoderawtransaction ")+rawtx+" extra"), runtime_error); @@ -236,7 +237,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) UniValue o1 = ar[0].get_obj(); UniValue adr = find_value(o1, "address"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/32"); - BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove")));; + BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); ar = r.get_array(); BOOST_CHECK_EQUAL(ar.size(), 0); @@ -266,7 +267,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) // must throw an exception because 127.0.0.1 is in already banned suubnet range BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.1 add")), runtime_error); - BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0/24 remove")));; + BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0/24 remove"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); ar = r.get_array(); BOOST_CHECK_EQUAL(ar.size(), 0); diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 2e652f76e2..398372af3c 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2014 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/sanity_tests.cpp b/src/test/sanity_tests.cpp index f5f7f381d3..51f9e9f39f 100644 --- a/src/test/sanity_tests.cpp +++ b/src/test/sanity_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp index cb1a427db0..9acd0e2430 100644 --- a/src/test/scheduler_tests.cpp +++ b/src/test/scheduler_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -40,6 +40,7 @@ static void MicroSleep(uint64_t n) #endif } +#if 0 /* Disabled for now because there is a race condition issue in this test - see #6540 */ BOOST_AUTO_TEST_CASE(manythreads) { seed_insecure_rand(false); @@ -115,5 +116,6 @@ BOOST_AUTO_TEST_CASE(manythreads) } BOOST_CHECK_EQUAL(counterSum, 200); } +#endif BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 16c9a4a868..7bd4b8441b 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -25,7 +25,7 @@ using namespace std; static std::vector<unsigned char> Serialize(const CScript& s) { - std::vector<unsigned char> sSerialized(s); + std::vector<unsigned char> sSerialized(s.begin(), s.end()); return sSerialized; } @@ -339,8 +339,8 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) // SignSignature doesn't know how to sign these. We're // not testing validating signatures, so just create // dummy signatures that DO include the correct P2SH scripts: - txTo.vin[3].scriptSig << OP_11 << OP_11 << static_cast<vector<unsigned char> >(oneAndTwo); - txTo.vin[4].scriptSig << static_cast<vector<unsigned char> >(fifteenSigops); + txTo.vin[3].scriptSig << OP_11 << OP_11 << vector<unsigned char>(oneAndTwo.begin(), oneAndTwo.end()); + txTo.vin[4].scriptSig << vector<unsigned char>(fifteenSigops.begin(), fifteenSigops.end()); BOOST_CHECK(::AreInputsStandard(txTo, coins)); // 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4] @@ -362,7 +362,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txToNonStd1.vin.resize(1); txToNonStd1.vin[0].prevout.n = 5; txToNonStd1.vin[0].prevout.hash = txFrom.GetHash(); - txToNonStd1.vin[0].scriptSig << static_cast<vector<unsigned char> >(sixteenSigops); + txToNonStd1.vin[0].scriptSig << vector<unsigned char>(sixteenSigops.begin(), sixteenSigops.end()); BOOST_CHECK(!::AreInputsStandard(txToNonStd1, coins)); BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd1, coins), 16U); @@ -374,7 +374,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txToNonStd2.vin.resize(1); txToNonStd2.vin[0].prevout.n = 6; txToNonStd2.vin[0].prevout.hash = txFrom.GetHash(); - txToNonStd2.vin[0].scriptSig << static_cast<vector<unsigned char> >(twentySigops); + txToNonStd2.vin[0].scriptSig << vector<unsigned char>(twentySigops.begin(), twentySigops.end()); BOOST_CHECK(!::AreInputsStandard(txToNonStd2, coins)); BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd2, coins), 20U); diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 882f9eb199..10175ebe8e 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -260,7 +260,7 @@ public: TestBuilder& PushRedeem() { - DoPush(static_cast<std::vector<unsigned char> >(scriptPubKey)); + DoPush(std::vector<unsigned char>(scriptPubKey.begin(), scriptPubKey.end())); return *this; } @@ -892,7 +892,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig); // dummy scriptSigCopy with placeholder, should always choose non-placeholder: - scriptSigCopy = CScript() << OP_0 << static_cast<vector<unsigned char> >(pkSingle); + scriptSigCopy = CScript() << OP_0 << vector<unsigned char>(pkSingle.begin(), pkSingle.end()); combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); BOOST_CHECK(combined == scriptSig); combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, scriptSigCopy); @@ -985,10 +985,10 @@ BOOST_AUTO_TEST_CASE(script_IsPushOnly_on_invalid_scripts) BOOST_AUTO_TEST_CASE(script_GetScriptAsm) { - BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2, true)); - BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true)); - BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2)); - BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY)); + BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_NOP2, true)); + BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true)); + BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_NOP2)); + BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY)); string derSig("304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090"); string pubKey("03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2"); diff --git a/src/test/scriptnum10.h b/src/test/scriptnum10.h new file mode 100644 index 0000000000..94dd58526c --- /dev/null +++ b/src/test/scriptnum10.h @@ -0,0 +1,183 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_TEST_SCRIPTNUM10_H +#define BITCOIN_TEST_SCRIPTNUM10_H + +#include <algorithm> +#include <limits> +#include <stdexcept> +#include <stdint.h> +#include <string> +#include <vector> +#include "assert.h" + +class scriptnum10_error : public std::runtime_error +{ +public: + explicit scriptnum10_error(const std::string& str) : std::runtime_error(str) {} +}; + +class CScriptNum10 +{ +/** + * The ScriptNum implementation from Bitcoin Core 0.10.0, for cross-comparison. + */ +public: + + explicit CScriptNum10(const int64_t& n) + { + m_value = n; + } + + static const size_t nDefaultMaxNumSize = 4; + + explicit CScriptNum10(const std::vector<unsigned char>& vch, bool fRequireMinimal, + const size_t nMaxNumSize = nDefaultMaxNumSize) + { + if (vch.size() > nMaxNumSize) { + throw scriptnum10_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 scriptnum10_error("non-minimally encoded script number"); + } + } + } + m_value = set_vch(vch); + } + + inline bool operator==(const int64_t& rhs) const { return m_value == rhs; } + inline bool operator!=(const int64_t& rhs) const { return m_value != rhs; } + inline bool operator<=(const int64_t& rhs) const { return m_value <= rhs; } + inline bool operator< (const int64_t& rhs) const { return m_value < rhs; } + inline bool operator>=(const int64_t& rhs) const { return m_value >= rhs; } + inline bool operator> (const int64_t& rhs) const { return m_value > rhs; } + + inline bool operator==(const CScriptNum10& rhs) const { return operator==(rhs.m_value); } + inline bool operator!=(const CScriptNum10& rhs) const { return operator!=(rhs.m_value); } + inline bool operator<=(const CScriptNum10& rhs) const { return operator<=(rhs.m_value); } + inline bool operator< (const CScriptNum10& rhs) const { return operator< (rhs.m_value); } + inline bool operator>=(const CScriptNum10& rhs) const { return operator>=(rhs.m_value); } + inline bool operator> (const CScriptNum10& rhs) const { return operator> (rhs.m_value); } + + inline CScriptNum10 operator+( const int64_t& rhs) const { return CScriptNum10(m_value + rhs);} + inline CScriptNum10 operator-( const int64_t& rhs) const { return CScriptNum10(m_value - rhs);} + inline CScriptNum10 operator+( const CScriptNum10& rhs) const { return operator+(rhs.m_value); } + inline CScriptNum10 operator-( const CScriptNum10& rhs) const { return operator-(rhs.m_value); } + + inline CScriptNum10& operator+=( const CScriptNum10& rhs) { return operator+=(rhs.m_value); } + inline CScriptNum10& operator-=( const CScriptNum10& rhs) { return operator-=(rhs.m_value); } + + inline CScriptNum10 operator-() const + { + assert(m_value != std::numeric_limits<int64_t>::min()); + return CScriptNum10(-m_value); + } + + inline CScriptNum10& operator=( const int64_t& rhs) + { + m_value = rhs; + return *this; + } + + inline CScriptNum10& operator+=( const int64_t& rhs) + { + assert(rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits<int64_t>::max() - rhs) || + (rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs)); + m_value += rhs; + return *this; + } + + inline CScriptNum10& operator-=( const int64_t& rhs) + { + assert(rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits<int64_t>::min() + rhs) || + (rhs < 0 && m_value <= std::numeric_limits<int64_t>::max() + rhs)); + m_value -= rhs; + return *this; + } + + int getint() const + { + if (m_value > std::numeric_limits<int>::max()) + return std::numeric_limits<int>::max(); + else if (m_value < std::numeric_limits<int>::min()) + return std::numeric_limits<int>::min(); + return m_value; + } + + std::vector<unsigned char> getvch() const + { + return serialize(m_value); + } + + static std::vector<unsigned char> serialize(const int64_t& value) + { + if(value == 0) + return std::vector<unsigned char>(); + + std::vector<unsigned char> result; + const bool neg = value < 0; + uint64_t absvalue = neg ? -value : value; + + while(absvalue) + { + result.push_back(absvalue & 0xff); + absvalue >>= 8; + } + +// - If the most significant byte is >= 0x80 and the value is positive, push a +// new zero-byte to make the significant byte < 0x80 again. + +// - If the most significant byte is >= 0x80 and the value is negative, push a +// new 0x80 byte that will be popped off when converting to an integral. + +// - If the most significant byte is < 0x80 and the value is negative, add +// 0x80 to it, since it will be subtracted and interpreted as a negative when +// converting to an integral. + + if (result.back() & 0x80) + result.push_back(neg ? 0x80 : 0); + else if (neg) + result.back() |= 0x80; + + return result; + } + +private: + static int64_t set_vch(const std::vector<unsigned char>& vch) + { + if (vch.empty()) + return 0; + + int64_t result = 0; + for (size_t i = 0; i != vch.size(); ++i) + result |= static_cast<int64_t>(vch[i]) << 8*i; + + // 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 -((int64_t)(result & ~(0x80ULL << (8 * (vch.size() - 1))))); + + return result; + } + + int64_t m_value; +}; + + +#endif // BITCOIN_TEST_BIGNUM_H diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp index d95724dbe1..6b6689c7d3 100644 --- a/src/test/scriptnum_tests.cpp +++ b/src/test/scriptnum_tests.cpp @@ -1,8 +1,8 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "bignum.h" +#include "scriptnum10.h" #include "script/script.h" #include "test/test_bitcoin.h" @@ -16,45 +16,48 @@ static const int64_t values[] = \ { 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, LONG_MIN, LONG_MAX }; static const int64_t offsets[] = { 1, 0x79, 0x80, 0x81, 0xFF, 0x7FFF, 0x8000, 0xFFFF, 0x10000}; -static bool verify(const CBigNum& bignum, const CScriptNum& scriptnum) +static bool verify(const CScriptNum10& bignum, const CScriptNum& scriptnum) { return bignum.getvch() == scriptnum.getvch() && bignum.getint() == scriptnum.getint(); } static void CheckCreateVch(const int64_t& num) { - CBigNum bignum(num); + CScriptNum10 bignum(num); CScriptNum scriptnum(num); BOOST_CHECK(verify(bignum, scriptnum)); - CBigNum bignum2(bignum.getvch()); + std::vector<unsigned char> vch = bignum.getvch(); + + CScriptNum10 bignum2(bignum.getvch(), false); + vch = scriptnum.getvch(); CScriptNum scriptnum2(scriptnum.getvch(), false); BOOST_CHECK(verify(bignum2, scriptnum2)); - CBigNum bignum3(scriptnum2.getvch()); + CScriptNum10 bignum3(scriptnum2.getvch(), false); CScriptNum scriptnum3(bignum2.getvch(), false); BOOST_CHECK(verify(bignum3, scriptnum3)); } static void CheckCreateInt(const int64_t& num) { - CBigNum bignum(num); + CScriptNum10 bignum(num); CScriptNum scriptnum(num); BOOST_CHECK(verify(bignum, scriptnum)); - BOOST_CHECK(verify(bignum.getint(), CScriptNum(scriptnum.getint()))); - BOOST_CHECK(verify(scriptnum.getint(), CScriptNum(bignum.getint()))); - BOOST_CHECK(verify(CBigNum(scriptnum.getint()).getint(), CScriptNum(CScriptNum(bignum.getint()).getint()))); + BOOST_CHECK(verify(CScriptNum10(bignum.getint()), CScriptNum(scriptnum.getint()))); + BOOST_CHECK(verify(CScriptNum10(scriptnum.getint()), CScriptNum(bignum.getint()))); + BOOST_CHECK(verify(CScriptNum10(CScriptNum10(scriptnum.getint()).getint()), CScriptNum(CScriptNum(bignum.getint()).getint()))); } static void CheckAdd(const int64_t& num1, const int64_t& num2) { - const CBigNum bignum1(num1); - const CBigNum bignum2(num2); + const CScriptNum10 bignum1(num1); + const CScriptNum10 bignum2(num2); const CScriptNum scriptnum1(num1); const CScriptNum scriptnum2(num2); - CBigNum bignum3(num1); - CBigNum bignum4(num1); + CScriptNum10 bignum3(num1); + CScriptNum10 bignum4(num1); CScriptNum scriptnum3(num1); CScriptNum scriptnum4(num1); @@ -71,7 +74,7 @@ static void CheckAdd(const int64_t& num1, const int64_t& num2) static void CheckNegate(const int64_t& num) { - const CBigNum bignum(num); + const CScriptNum10 bignum(num); const CScriptNum scriptnum(num); // -INT64_MIN is undefined @@ -81,8 +84,8 @@ static void CheckNegate(const int64_t& num) static void CheckSubtract(const int64_t& num1, const int64_t& num2) { - const CBigNum bignum1(num1); - const CBigNum bignum2(num2); + const CScriptNum10 bignum1(num1); + const CScriptNum10 bignum2(num2); const CScriptNum scriptnum1(num1); const CScriptNum scriptnum2(num2); bool invalid = false; @@ -107,8 +110,8 @@ static void CheckSubtract(const int64_t& num1, const int64_t& num2) static void CheckCompare(const int64_t& num1, const int64_t& num2) { - const CBigNum bignum1(num1); - const CBigNum bignum2(num2); + const CScriptNum10 bignum1(num1); + const CScriptNum10 bignum2(num2); const CScriptNum scriptnum1(num1); const CScriptNum scriptnum2(num2); @@ -149,7 +152,7 @@ static void RunCreate(const int64_t& num) CheckCreateVch(num); else { - BOOST_CHECK_THROW (CheckCreateVch(num), scriptnum_error); + BOOST_CHECK_THROW (CheckCreateVch(num), scriptnum10_error); } } diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index cc8f2b788d..c0fd99aca2 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 6fca64d5da..04c6fa9625 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index b26fed99f2..a207fd9216 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -20,7 +20,7 @@ using namespace std; static std::vector<unsigned char> Serialize(const CScript& s) { - std::vector<unsigned char> sSerialized(s); + std::vector<unsigned char> sSerialized(s.begin(), s.end()); return sSerialized; } diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index a904e3862f..f14b902fe1 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp new file mode 100644 index 0000000000..34f501e867 --- /dev/null +++ b/src/test/streams_tests.cpp @@ -0,0 +1,67 @@ +// Copyright (c) 2012-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "streams.h" +#include "support/allocators/zeroafterfree.h" +#include "test/test_bitcoin.h" + +#include <boost/assign/std/vector.hpp> // for 'operator+=()' +#include <boost/assert.hpp> +#include <boost/test/unit_test.hpp> + +using namespace std; +using namespace boost::assign; // bring 'operator+=()' into scope + +BOOST_FIXTURE_TEST_SUITE(streams_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(streams_serializedata_xor) +{ + std::vector<char> in; + std::vector<char> expected_xor; + std::vector<unsigned char> key; + CDataStream ds(in, 0, 0); + + // Degenerate case + + key += '\x00','\x00'; + ds.Xor(key); + BOOST_CHECK_EQUAL( + std::string(expected_xor.begin(), expected_xor.end()), + std::string(ds.begin(), ds.end())); + + in += '\x0f','\xf0'; + expected_xor += '\xf0','\x0f'; + + // Single character key + + ds.clear(); + ds.insert(ds.begin(), in.begin(), in.end()); + key.clear(); + + key += '\xff'; + ds.Xor(key); + BOOST_CHECK_EQUAL( + std::string(expected_xor.begin(), expected_xor.end()), + std::string(ds.begin(), ds.end())); + + // Multi character key + + in.clear(); + expected_xor.clear(); + in += '\xf0','\x0f'; + expected_xor += '\x0f','\x00'; + + ds.clear(); + ds.insert(ds.begin(), in.begin(), in.end()); + + key.clear(); + key += '\xff','\x0f'; + + ds.Xor(key); + BOOST_CHECK_EQUAL( + std::string(expected_xor.begin(), expected_xor.end()), + std::string(ds.begin(), ds.end())); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 8d81275a6f..f81050b15d 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,6 +15,7 @@ #include "pubkey.h" #include "random.h" #include "txdb.h" +#include "txmempool.h" #include "ui_interface.h" #include "util.h" #ifdef ENABLE_WALLET @@ -32,13 +33,14 @@ CWallet* pwalletMain; extern bool fPrintToConsole; extern void noui_connect(); -BasicTestingSetup::BasicTestingSetup(CBaseChainParams::Network network) +BasicTestingSetup::BasicTestingSetup(const std::string& chainName) { ECC_Start(); SetupEnvironment(); + SetupNetworking(); fPrintToDebugLog = false; // don't want to write to debug.log file fCheckBlockIndex = true; - SelectParams(network); + SelectParams(chainName); noui_connect(); } @@ -47,8 +49,9 @@ BasicTestingSetup::~BasicTestingSetup() ECC_Stop(); } -TestingSetup::TestingSetup(CBaseChainParams::Network network) : BasicTestingSetup(network) +TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName) { + const CChainParams& chainparams = Params(); #ifdef ENABLE_WALLET bitdb.MakeMock(); #endif @@ -59,7 +62,7 @@ TestingSetup::TestingSetup(CBaseChainParams::Network network) : BasicTestingSetu pblocktree = new CBlockTreeDB(1 << 20, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); - InitBlockIndex(); + InitBlockIndex(chainparams); #ifdef ENABLE_WALLET bool fFirstRun; pwalletMain = new CWallet("wallet.dat"); @@ -113,7 +116,8 @@ TestChain100Setup::TestChain100Setup() : TestingSetup(CBaseChainParams::REGTEST) CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey) { - CBlockTemplate *pblocktemplate = CreateNewBlock(scriptPubKey); + const CChainParams& chainparams = Params(); + CBlockTemplate *pblocktemplate = CreateNewBlock(chainparams, scriptPubKey); CBlock& block = pblocktemplate->block; // Replace mempool-selected txns with just coinbase plus passed-in txns: @@ -124,10 +128,10 @@ TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& unsigned int extraNonce = 0; IncrementExtraNonce(&block, chainActive.Tip(), extraNonce); - while (!CheckProofOfWork(block.GetHash(), block.nBits, Params(CBaseChainParams::REGTEST).GetConsensus())) ++block.nNonce; + while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce; CValidationState state; - ProcessNewBlock(state, NULL, &block, true, NULL); + ProcessNewBlock(state, chainparams, NULL, &block, true, NULL); CBlock result = block; delete pblocktemplate; @@ -138,6 +142,17 @@ TestChain100Setup::~TestChain100Setup() { } + +CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPool *pool) { + CTransaction txn(tx); + bool hasNoDependencies = pool ? pool->HasNoInputsOf(tx) : hadNoDependencies; + // Hack to assume either its completely dependent on other mempool txs or not at all + CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0; + + return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight, + hasNoDependencies, inChainValue, spendsCoinbase, sigOpCount); +} + void Shutdown(void* parg) { exit(0); diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index b9314d0611..273bfdd7f4 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -3,6 +3,7 @@ #include "chainparamsbase.h" #include "key.h" +#include "pubkey.h" #include "txdb.h" #include <boost/filesystem.hpp> @@ -12,7 +13,9 @@ * This just configures logging and chain parameters. */ struct BasicTestingSetup { - BasicTestingSetup(CBaseChainParams::Network network = CBaseChainParams::MAIN); + ECCVerifyHandle globalVerifyHandle; + + BasicTestingSetup(const std::string& chainName = CBaseChainParams::MAIN); ~BasicTestingSetup(); }; @@ -25,7 +28,7 @@ struct TestingSetup: public BasicTestingSetup { boost::filesystem::path pathTemp; boost::thread_group threadGroup; - TestingSetup(CBaseChainParams::Network network = CBaseChainParams::MAIN); + TestingSetup(const std::string& chainName = CBaseChainParams::MAIN); ~TestingSetup(); }; @@ -51,4 +54,33 @@ struct TestChain100Setup : public TestingSetup { CKey coinbaseKey; // private/public key needed to spend coinbase transactions }; +class CTxMemPoolEntry; +class CTxMemPool; + +struct TestMemPoolEntryHelper +{ + // Default values + CAmount nFee; + int64_t nTime; + double dPriority; + unsigned int nHeight; + bool hadNoDependencies; + bool spendsCoinbase; + unsigned int sigOpCount; + + TestMemPoolEntryHelper() : + nFee(0), nTime(0), dPriority(0.0), nHeight(1), + hadNoDependencies(false), spendsCoinbase(false), sigOpCount(1) { } + + CTxMemPoolEntry FromTx(CMutableTransaction &tx, CTxMemPool *pool = NULL); + + // Change the default value + TestMemPoolEntryHelper &Fee(CAmount _fee) { nFee = _fee; return *this; } + TestMemPoolEntryHelper &Time(int64_t _time) { nTime = _time; return *this; } + TestMemPoolEntryHelper &Priority(double _priority) { dPriority = _priority; return *this; } + TestMemPoolEntryHelper &Height(unsigned int _height) { nHeight = _height; return *this; } + TestMemPoolEntryHelper &HadNoDependencies(bool _hnd) { hadNoDependencies = _hnd; return *this; } + TestMemPoolEntryHelper &SpendsCoinbase(bool _flag) { spendsCoinbase = _flag; return *this; } + TestMemPoolEntryHelper &SigOps(unsigned int _sigops) { sigOpCount = _sigops; return *this; } +}; #endif diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp index 887cfb4761..1224ff8454 100644 --- a/src/test/timedata_tests.cpp +++ b/src/test/timedata_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 9847f6512e..3dca7ea0f7 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -342,11 +342,26 @@ BOOST_AUTO_TEST_CASE(test_IsStandard) string reason; BOOST_CHECK(IsStandardTx(t, reason)); - t.vout[0].nValue = 501; // dust + // Check dust with default relay fee: + CAmount nDustThreshold = 182 * minRelayTxFee.GetFeePerK()/1000 * 3; + BOOST_CHECK_EQUAL(nDustThreshold, 546); + // dust: + t.vout[0].nValue = nDustThreshold - 1; BOOST_CHECK(!IsStandardTx(t, reason)); + // not dust: + t.vout[0].nValue = nDustThreshold; + BOOST_CHECK(IsStandardTx(t, reason)); - t.vout[0].nValue = 601; // not dust + // Check dust with odd relay fee to verify rounding: + // nDustThreshold = 182 * 1234 / 1000 * 3 + minRelayTxFee = CFeeRate(1234); + // dust: + t.vout[0].nValue = 672 - 1; + BOOST_CHECK(!IsStandardTx(t, reason)); + // not dust: + t.vout[0].nValue = 672; BOOST_CHECK(IsStandardTx(t, reason)); + minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); t.vout[0].scriptPubKey = CScript() << OP_1; BOOST_CHECK(!IsStandardTx(t, reason)); diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index edad18644e..66be9d3d5e 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -23,7 +23,7 @@ ToMemPool(CMutableTransaction& tx) LOCK(cs_main); CValidationState state; - return AcceptToMemoryPool(mempool, state, tx, false, NULL, false); + return AcceptToMemoryPool(mempool, state, tx, false, NULL, true, false); } BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index 426d296a9a..da0a3d73e0 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "arith_uint256.h" diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 997dc31931..28cecfffaf 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/timedata.cpp b/src/timedata.cpp index 0641009537..de8cc62b24 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -55,7 +55,7 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) // Add data static CMedianFilter<int64_t> vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0); vTimeOffsets.input(nOffsetSample); - LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60); + LogPrint("net","added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60); // There is a known issue here (see issue #4521): // @@ -105,11 +105,11 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) } } } - if (fDebug) { - BOOST_FOREACH(int64_t n, vSorted) - LogPrintf("%+d ", n); - LogPrintf("| "); - } - LogPrintf("nTimeOffset = %+d (%+d minutes)\n", nTimeOffset, nTimeOffset/60); + + BOOST_FOREACH(int64_t n, vSorted) + LogPrint("net", "%+d ", n); + LogPrint("net", "| "); + + LogPrint("net", "nTimeOffset = %+d (%+d minutes)\n", nTimeOffset, nTimeOffset/60); } } diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp new file mode 100644 index 0000000000..4ebcb9b667 --- /dev/null +++ b/src/torcontrol.cpp @@ -0,0 +1,696 @@ +#include "torcontrol.h" +#include "utilstrencodings.h" +#include "net.h" +#include "util.h" +#include "crypto/hmac_sha256.h" + +#include <vector> +#include <deque> +#include <set> +#include <stdlib.h> + +#include <boost/function.hpp> +#include <boost/bind.hpp> +#include <boost/signals2/signal.hpp> +#include <boost/foreach.hpp> +#include <boost/algorithm/string/predicate.hpp> +#include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/classification.hpp> +#include <boost/algorithm/string/replace.hpp> + +#include <event2/bufferevent.h> +#include <event2/buffer.h> +#include <event2/util.h> +#include <event2/event.h> +#include <event2/thread.h> + +/** Default control port */ +const std::string DEFAULT_TOR_CONTROL = "127.0.0.1:9051"; +/** Tor cookie size (from control-spec.txt) */ +static const int TOR_COOKIE_SIZE = 32; +/** Size of client/server nonce for SAFECOOKIE */ +static const int TOR_NONCE_SIZE = 32; +/** For computing serverHash in SAFECOOKIE */ +static const std::string TOR_SAFE_SERVERKEY = "Tor safe cookie authentication server-to-controller hash"; +/** For computing clientHash in SAFECOOKIE */ +static const std::string TOR_SAFE_CLIENTKEY = "Tor safe cookie authentication controller-to-server hash"; +/** Exponential backoff configuration - initial timeout in seconds */ +static const float RECONNECT_TIMEOUT_START = 1.0; +/** Exponential backoff configuration - growth factor */ +static const float RECONNECT_TIMEOUT_EXP = 1.5; +/** Maximum length for lines received on TorControlConnection. + * tor-control-spec.txt mentions that there is explicitly no limit defined to line length, + * this is belt-and-suspenders sanity limit to prevent memory exhaustion. + */ +static const int MAX_LINE_LENGTH = 100000; + +/****** Low-level TorControlConnection ********/ + +/** Reply from Tor, can be single or multi-line */ +class TorControlReply +{ +public: + TorControlReply() { Clear(); } + + int code; + std::vector<std::string> lines; + + void Clear() + { + code = 0; + lines.clear(); + } +}; + +/** Low-level handling for Tor control connection. + * Speaks the SMTP-like protocol as defined in torspec/control-spec.txt + */ +class TorControlConnection +{ +public: + typedef boost::function<void(TorControlConnection&)> ConnectionCB; + typedef boost::function<void(TorControlConnection &,const TorControlReply &)> ReplyHandlerCB; + + /** Create a new TorControlConnection. + */ + TorControlConnection(struct event_base *base); + ~TorControlConnection(); + + /** + * Connect to a Tor control port. + * target is address of the form host:port. + * connected is the handler that is called when connection is succesfully established. + * disconnected is a handler that is called when the connection is broken. + * Return true on success. + */ + bool Connect(const std::string &target, const ConnectionCB& connected, const ConnectionCB& disconnected); + + /** + * Disconnect from Tor control port. + */ + bool Disconnect(); + + /** Send a command, register a handler for the reply. + * A trailing CRLF is automatically added. + * Return true on success. + */ + bool Command(const std::string &cmd, const ReplyHandlerCB& reply_handler); + + /** Response handlers for async replies */ + boost::signals2::signal<void(TorControlConnection &,const TorControlReply &)> async_handler; +private: + /** Callback when ready for use */ + boost::function<void(TorControlConnection&)> connected; + /** Callback when connection lost */ + boost::function<void(TorControlConnection&)> disconnected; + /** Libevent event base */ + struct event_base *base; + /** Connection to control socket */ + struct bufferevent *b_conn; + /** Message being received */ + TorControlReply message; + /** Response handlers */ + std::deque<ReplyHandlerCB> reply_handlers; + + /** Libevent handlers: internal */ + static void readcb(struct bufferevent *bev, void *ctx); + static void eventcb(struct bufferevent *bev, short what, void *ctx); +}; + +TorControlConnection::TorControlConnection(struct event_base *base): + base(base), b_conn(0) +{ +} + +TorControlConnection::~TorControlConnection() +{ + if (b_conn) + bufferevent_free(b_conn); +} + +void TorControlConnection::readcb(struct bufferevent *bev, void *ctx) +{ + TorControlConnection *self = (TorControlConnection*)ctx; + struct evbuffer *input = bufferevent_get_input(bev); + size_t n_read_out = 0; + char *line; + assert(input); + // If there is not a whole line to read, evbuffer_readln returns NULL + while((line = evbuffer_readln(input, &n_read_out, EVBUFFER_EOL_CRLF)) != NULL) + { + std::string s(line, n_read_out); + free(line); + if (s.size() < 4) // Short line + continue; + // <status>(-|+| )<data><CRLF> + self->message.code = atoi(s.substr(0,3)); + self->message.lines.push_back(s.substr(4)); + char ch = s[3]; // '-','+' or ' ' + if (ch == ' ') { + // Final line, dispatch reply and clean up + if (self->message.code >= 600) { + // Dispatch async notifications to async handler + // Synchronous and asynchronous messages are never interleaved + self->async_handler(*self, self->message); + } else { + if (!self->reply_handlers.empty()) { + // Invoke reply handler with message + self->reply_handlers.front()(*self, self->message); + self->reply_handlers.pop_front(); + } else { + LogPrint("tor", "tor: Received unexpected sync reply %i\n", self->message.code); + } + } + self->message.Clear(); + } + } + // Check for size of buffer - protect against memory exhaustion with very long lines + // Do this after evbuffer_readln to make sure all full lines have been + // removed from the buffer. Everything left is an incomplete line. + if (evbuffer_get_length(input) > MAX_LINE_LENGTH) { + LogPrintf("tor: Disconnecting because MAX_LINE_LENGTH exceeded\n"); + self->Disconnect(); + } +} + +void TorControlConnection::eventcb(struct bufferevent *bev, short what, void *ctx) +{ + TorControlConnection *self = (TorControlConnection*)ctx; + if (what & BEV_EVENT_CONNECTED) { + LogPrint("tor", "tor: Succesfully connected!\n"); + self->connected(*self); + } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) { + if (what & BEV_EVENT_ERROR) + LogPrint("tor", "tor: Error connecting to Tor control socket\n"); + else + LogPrint("tor", "tor: End of stream\n"); + self->Disconnect(); + self->disconnected(*self); + } +} + +bool TorControlConnection::Connect(const std::string &target, const ConnectionCB& connected, const ConnectionCB& disconnected) +{ + if (b_conn) + Disconnect(); + // Parse target address:port + struct sockaddr_storage connect_to_addr; + int connect_to_addrlen = sizeof(connect_to_addr); + if (evutil_parse_sockaddr_port(target.c_str(), + (struct sockaddr*)&connect_to_addr, &connect_to_addrlen)<0) { + LogPrintf("tor: Error parsing socket address %s\n", target); + return false; + } + + // Create a new socket, set up callbacks and enable notification bits + b_conn = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); + if (!b_conn) + return false; + bufferevent_setcb(b_conn, TorControlConnection::readcb, NULL, TorControlConnection::eventcb, this); + bufferevent_enable(b_conn, EV_READ|EV_WRITE); + this->connected = connected; + this->disconnected = disconnected; + + // Finally, connect to target + if (bufferevent_socket_connect(b_conn, (struct sockaddr*)&connect_to_addr, connect_to_addrlen) < 0) { + LogPrintf("tor: Error connecting to address %s\n", target); + return false; + } + return true; +} + +bool TorControlConnection::Disconnect() +{ + if (b_conn) + bufferevent_free(b_conn); + b_conn = 0; + return true; +} + +bool TorControlConnection::Command(const std::string &cmd, const ReplyHandlerCB& reply_handler) +{ + if (!b_conn) + return false; + struct evbuffer *buf = bufferevent_get_output(b_conn); + if (!buf) + return false; + evbuffer_add(buf, cmd.data(), cmd.size()); + evbuffer_add(buf, "\r\n", 2); + reply_handlers.push_back(reply_handler); + return true; +} + +/****** General parsing utilities ********/ + +/* Split reply line in the form 'AUTH METHODS=...' into a type + * 'AUTH' and arguments 'METHODS=...'. + */ +static std::pair<std::string,std::string> SplitTorReplyLine(const std::string &s) +{ + size_t ptr=0; + std::string type; + while (ptr < s.size() && s[ptr] != ' ') { + type.push_back(s[ptr]); + ++ptr; + } + if (ptr < s.size()) + ++ptr; // skip ' ' + return make_pair(type, s.substr(ptr)); +} + +/** Parse reply arguments in the form 'METHODS=COOKIE,SAFECOOKIE COOKIEFILE=".../control_auth_cookie"'. + */ +static std::map<std::string,std::string> ParseTorReplyMapping(const std::string &s) +{ + std::map<std::string,std::string> mapping; + size_t ptr=0; + while (ptr < s.size()) { + std::string key, value; + while (ptr < s.size() && s[ptr] != '=') { + key.push_back(s[ptr]); + ++ptr; + } + if (ptr == s.size()) // unexpected end of line + return std::map<std::string,std::string>(); + ++ptr; // skip '=' + if (ptr < s.size() && s[ptr] == '"') { // Quoted string + ++ptr; // skip '=' + bool escape_next = false; + while (ptr < s.size() && (!escape_next && s[ptr] != '"')) { + escape_next = (s[ptr] == '\\'); + value.push_back(s[ptr]); + ++ptr; + } + if (ptr == s.size()) // unexpected end of line + return std::map<std::string,std::string>(); + ++ptr; // skip closing '"' + /* TODO: unescape value - according to the spec this depends on the + * context, some strings use C-LogPrintf style escape codes, some + * don't. So may be better handled at the call site. + */ + } else { // Unquoted value. Note that values can contain '=' at will, just no spaces + while (ptr < s.size() && s[ptr] != ' ') { + value.push_back(s[ptr]); + ++ptr; + } + } + if (ptr < s.size() && s[ptr] == ' ') + ++ptr; // skip ' ' after key=value + mapping[key] = value; + } + return mapping; +} + +/** Read full contents of a file and return them in a std::string. + * Returns a pair <status, string>. + * If an error occured, status will be false, otherwise status will be true and the data will be returned in string. + * + * @param maxsize Puts a maximum size limit on the file that is read. If the file is larger than this, truncated data + * (with len > maxsize) will be returned. + */ +static std::pair<bool,std::string> ReadBinaryFile(const std::string &filename, size_t maxsize=std::numeric_limits<size_t>::max()) +{ + FILE *f = fopen(filename.c_str(), "rb"); + if (f == NULL) + return std::make_pair(false,""); + std::string retval; + char buffer[128]; + size_t n; + while ((n=fread(buffer, 1, sizeof(buffer), f)) > 0) { + retval.append(buffer, buffer+n); + if (retval.size() > maxsize) + break; + } + fclose(f); + return std::make_pair(true,retval); +} + +/** Write contents of std::string to a file. + * @return true on success. + */ +static bool WriteBinaryFile(const std::string &filename, const std::string &data) +{ + FILE *f = fopen(filename.c_str(), "wb"); + if (f == NULL) + return false; + if (fwrite(data.data(), 1, data.size(), f) != data.size()) { + fclose(f); + return false; + } + fclose(f); + return true; +} + +/****** Bitcoin specific TorController implementation ********/ + +/** Controller that connects to Tor control socket, authenticate, then create + * and maintain a ephemeral hidden service. + */ +class TorController +{ +public: + TorController(struct event_base* base, const std::string& target); + ~TorController(); + + /** Get name fo file to store private key in */ + std::string GetPrivateKeyFile(); + + /** Reconnect, after getting disconnected */ + void Reconnect(); +private: + struct event_base* base; + std::string target; + TorControlConnection conn; + std::string private_key; + std::string service_id; + bool reconnect; + struct event *reconnect_ev; + float reconnect_timeout; + CService service; + /** Cooie for SAFECOOKIE auth */ + std::vector<uint8_t> cookie; + /** ClientNonce for SAFECOOKIE auth */ + std::vector<uint8_t> clientNonce; + + /** Callback for ADD_ONION result */ + void add_onion_cb(TorControlConnection& conn, const TorControlReply& reply); + /** Callback for AUTHENTICATE result */ + void auth_cb(TorControlConnection& conn, const TorControlReply& reply); + /** Callback for AUTHCHALLENGE result */ + void authchallenge_cb(TorControlConnection& conn, const TorControlReply& reply); + /** Callback for PROTOCOLINFO result */ + void protocolinfo_cb(TorControlConnection& conn, const TorControlReply& reply); + /** Callback after succesful connection */ + void connected_cb(TorControlConnection& conn); + /** Callback after connection lost or failed connection attempt */ + void disconnected_cb(TorControlConnection& conn); + + /** Callback for reconnect timer */ + static void reconnect_cb(evutil_socket_t fd, short what, void *arg); +}; + +TorController::TorController(struct event_base* base, const std::string& target): + base(base), + target(target), conn(base), reconnect(true), reconnect_ev(0), + reconnect_timeout(RECONNECT_TIMEOUT_START) +{ + // Start connection attempts immediately + if (!conn.Connect(target, boost::bind(&TorController::connected_cb, this, _1), + boost::bind(&TorController::disconnected_cb, this, _1) )) { + LogPrintf("tor: Initiating connection to Tor control port %s failed\n", target); + } + // Read service private key if cached + std::pair<bool,std::string> pkf = ReadBinaryFile(GetPrivateKeyFile()); + if (pkf.first) { + LogPrint("tor", "tor: Reading cached private key from %s\n", GetPrivateKeyFile()); + private_key = pkf.second; + } +} + +TorController::~TorController() +{ + if (reconnect_ev) + event_del(reconnect_ev); + if (service.IsValid()) { + RemoveLocal(service); + } +} + +void TorController::add_onion_cb(TorControlConnection& conn, const TorControlReply& reply) +{ + if (reply.code == 250) { + LogPrint("tor", "tor: ADD_ONION succesful\n"); + BOOST_FOREACH(const std::string &s, reply.lines) { + std::map<std::string,std::string> m = ParseTorReplyMapping(s); + std::map<std::string,std::string>::iterator i; + if ((i = m.find("ServiceID")) != m.end()) + service_id = i->second; + if ((i = m.find("PrivateKey")) != m.end()) + private_key = i->second; + } + + service = CService(service_id+".onion", GetListenPort(), false); + LogPrintf("tor: Got service ID %s, advertizing service %s\n", service_id, service.ToString()); + if (WriteBinaryFile(GetPrivateKeyFile(), private_key)) { + LogPrint("tor", "tor: Cached service private key to %s\n", GetPrivateKeyFile()); + } else { + LogPrintf("tor: Error writing service private key to %s\n", GetPrivateKeyFile()); + } + AddLocal(service, LOCAL_MANUAL); + // ... onion requested - keep connection open + } else if (reply.code == 510) { // 510 Unrecognized command + LogPrintf("tor: Add onion failed with unrecognized command (You probably need to upgrade Tor)\n"); + } else { + LogPrintf("tor: Add onion failed; error code %d\n", reply.code); + } +} + +void TorController::auth_cb(TorControlConnection& conn, const TorControlReply& reply) +{ + if (reply.code == 250) { + LogPrint("tor", "tor: Authentication succesful\n"); + + // Now that we know Tor is running setup the proxy for onion addresses + // if -onion isn't set to something else. + if (GetArg("-onion", "") == "") { + proxyType addrOnion = proxyType(CService("127.0.0.1", 9050), true); + SetProxy(NET_TOR, addrOnion); + SetReachable(NET_TOR); + } + + // Finally - now create the service + if (private_key.empty()) // No private key, generate one + private_key = "NEW:BEST"; + // Request hidden service, redirect port. + // Note that the 'virtual' port doesn't have to be the same as our internal port, but this is just a convenient + // choice. TODO; refactor the shutdown sequence some day. + conn.Command(strprintf("ADD_ONION %s Port=%i,127.0.0.1:%i", private_key, GetListenPort(), GetListenPort()), + boost::bind(&TorController::add_onion_cb, this, _1, _2)); + } else { + LogPrintf("tor: Authentication failed\n"); + } +} + +/** Compute Tor SAFECOOKIE response. + * + * ServerHash is computed as: + * HMAC-SHA256("Tor safe cookie authentication server-to-controller hash", + * CookieString | ClientNonce | ServerNonce) + * (with the HMAC key as its first argument) + * + * After a controller sends a successful AUTHCHALLENGE command, the + * next command sent on the connection must be an AUTHENTICATE command, + * and the only authentication string which that AUTHENTICATE command + * will accept is: + * + * HMAC-SHA256("Tor safe cookie authentication controller-to-server hash", + * CookieString | ClientNonce | ServerNonce) + * + */ +static std::vector<uint8_t> ComputeResponse(const std::string &key, const std::vector<uint8_t> &cookie, const std::vector<uint8_t> &clientNonce, const std::vector<uint8_t> &serverNonce) +{ + CHMAC_SHA256 computeHash((const uint8_t*)key.data(), key.size()); + std::vector<uint8_t> computedHash(CHMAC_SHA256::OUTPUT_SIZE, 0); + computeHash.Write(begin_ptr(cookie), cookie.size()); + computeHash.Write(begin_ptr(clientNonce), clientNonce.size()); + computeHash.Write(begin_ptr(serverNonce), serverNonce.size()); + computeHash.Finalize(begin_ptr(computedHash)); + return computedHash; +} + +void TorController::authchallenge_cb(TorControlConnection& conn, const TorControlReply& reply) +{ + if (reply.code == 250) { + LogPrint("tor", "tor: SAFECOOKIE authentication challenge succesful\n"); + std::pair<std::string,std::string> l = SplitTorReplyLine(reply.lines[0]); + if (l.first == "AUTHCHALLENGE") { + std::map<std::string,std::string> m = ParseTorReplyMapping(l.second); + std::vector<uint8_t> serverHash = ParseHex(m["SERVERHASH"]); + std::vector<uint8_t> serverNonce = ParseHex(m["SERVERNONCE"]); + LogPrint("tor", "tor: AUTHCHALLENGE ServerHash %s ServerNonce %s\n", HexStr(serverHash), HexStr(serverNonce)); + if (serverNonce.size() != 32) { + LogPrintf("tor: ServerNonce is not 32 bytes, as required by spec\n"); + return; + } + + std::vector<uint8_t> computedServerHash = ComputeResponse(TOR_SAFE_SERVERKEY, cookie, clientNonce, serverNonce); + if (computedServerHash != serverHash) { + LogPrintf("tor: ServerHash %s does not match expected ServerHash %s\n", HexStr(serverHash), HexStr(computedServerHash)); + return; + } + + std::vector<uint8_t> computedClientHash = ComputeResponse(TOR_SAFE_CLIENTKEY, cookie, clientNonce, serverNonce); + conn.Command("AUTHENTICATE " + HexStr(computedClientHash), boost::bind(&TorController::auth_cb, this, _1, _2)); + } else { + LogPrintf("tor: Invalid reply to AUTHCHALLENGE\n"); + } + } else { + LogPrintf("tor: SAFECOOKIE authentication challenge failed\n"); + } +} + +void TorController::protocolinfo_cb(TorControlConnection& conn, const TorControlReply& reply) +{ + if (reply.code == 250) { + std::set<std::string> methods; + std::string cookiefile; + /* + * 250-AUTH METHODS=COOKIE,SAFECOOKIE COOKIEFILE="/home/x/.tor/control_auth_cookie" + * 250-AUTH METHODS=NULL + * 250-AUTH METHODS=HASHEDPASSWORD + */ + BOOST_FOREACH(const std::string &s, reply.lines) { + std::pair<std::string,std::string> l = SplitTorReplyLine(s); + if (l.first == "AUTH") { + std::map<std::string,std::string> m = ParseTorReplyMapping(l.second); + std::map<std::string,std::string>::iterator i; + if ((i = m.find("METHODS")) != m.end()) + boost::split(methods, i->second, boost::is_any_of(",")); + if ((i = m.find("COOKIEFILE")) != m.end()) + cookiefile = i->second; + } else if (l.first == "VERSION") { + std::map<std::string,std::string> m = ParseTorReplyMapping(l.second); + std::map<std::string,std::string>::iterator i; + if ((i = m.find("Tor")) != m.end()) { + LogPrint("tor", "tor: Connected to Tor version %s\n", i->second); + } + } + } + BOOST_FOREACH(const std::string &s, methods) { + LogPrint("tor", "tor: Supported authentication method: %s\n", s); + } + // Prefer NULL, otherwise SAFECOOKIE. If a password is provided, use HASHEDPASSWORD + /* Authentication: + * cookie: hex-encoded ~/.tor/control_auth_cookie + * password: "password" + */ + std::string torpassword = GetArg("-torpassword", ""); + if (methods.count("NULL")) { + LogPrint("tor", "tor: Using NULL authentication\n"); + conn.Command("AUTHENTICATE", boost::bind(&TorController::auth_cb, this, _1, _2)); + } else if (methods.count("SAFECOOKIE")) { + // Cookie: hexdump -e '32/1 "%02x""\n"' ~/.tor/control_auth_cookie + LogPrint("tor", "tor: Using SAFECOOKIE authentication, reading cookie authentication from %s\n", cookiefile); + std::pair<bool,std::string> status_cookie = ReadBinaryFile(cookiefile, TOR_COOKIE_SIZE); + if (status_cookie.first && status_cookie.second.size() == TOR_COOKIE_SIZE) { + // conn.Command("AUTHENTICATE " + HexStr(status_cookie.second), boost::bind(&TorController::auth_cb, this, _1, _2)); + cookie = std::vector<uint8_t>(status_cookie.second.begin(), status_cookie.second.end()); + clientNonce = std::vector<uint8_t>(TOR_NONCE_SIZE, 0); + GetRandBytes(&clientNonce[0], TOR_NONCE_SIZE); + conn.Command("AUTHCHALLENGE SAFECOOKIE " + HexStr(clientNonce), boost::bind(&TorController::authchallenge_cb, this, _1, _2)); + } else { + if (status_cookie.first) { + LogPrintf("tor: Authentication cookie %s is not exactly %i bytes, as is required by the spec\n", cookiefile, TOR_COOKIE_SIZE); + } else { + LogPrintf("tor: Authentication cookie %s could not be opened (check permissions)\n", cookiefile); + } + } + } else if (methods.count("HASHEDPASSWORD")) { + if (!torpassword.empty()) { + LogPrint("tor", "tor: Using HASHEDPASSWORD authentication\n"); + boost::replace_all(torpassword, "\"", "\\\""); + conn.Command("AUTHENTICATE \"" + torpassword + "\"", boost::bind(&TorController::auth_cb, this, _1, _2)); + } else { + LogPrintf("tor: Password authentication required, but no password provided with -torpassword\n"); + } + } else { + LogPrintf("tor: No supported authentication method\n"); + } + } else { + LogPrintf("tor: Requesting protocol info failed\n"); + } +} + +void TorController::connected_cb(TorControlConnection& conn) +{ + reconnect_timeout = RECONNECT_TIMEOUT_START; + // First send a PROTOCOLINFO command to figure out what authentication is expected + if (!conn.Command("PROTOCOLINFO 1", boost::bind(&TorController::protocolinfo_cb, this, _1, _2))) + LogPrintf("tor: Error sending initial protocolinfo command\n"); +} + +void TorController::disconnected_cb(TorControlConnection& conn) +{ + // Stop advertizing service when disconnected + if (service.IsValid()) + RemoveLocal(service); + service = CService(); + if (!reconnect) + return; + + LogPrint("tor", "tor: Not connected to Tor control port %s, trying to reconnect\n", target); + + // Single-shot timer for reconnect. Use exponential backoff. + struct timeval time = MillisToTimeval(int64_t(reconnect_timeout * 1000.0)); + reconnect_ev = event_new(base, -1, 0, reconnect_cb, this); + event_add(reconnect_ev, &time); + reconnect_timeout *= RECONNECT_TIMEOUT_EXP; +} + +void TorController::Reconnect() +{ + /* Try to reconnect and reestablish if we get booted - for example, Tor + * may be restarting. + */ + if (!conn.Connect(target, boost::bind(&TorController::connected_cb, this, _1), + boost::bind(&TorController::disconnected_cb, this, _1) )) { + LogPrintf("tor: Re-initiating connection to Tor control port %s failed\n", target); + } +} + +std::string TorController::GetPrivateKeyFile() +{ + return (GetDataDir() / "onion_private_key").string(); +} + +void TorController::reconnect_cb(evutil_socket_t fd, short what, void *arg) +{ + TorController *self = (TorController*)arg; + self->Reconnect(); +} + +/****** Thread ********/ +struct event_base *base; +boost::thread torControlThread; + +static void TorControlThread() +{ + TorController ctrl(base, GetArg("-torcontrol", DEFAULT_TOR_CONTROL)); + + event_base_dispatch(base); +} + +void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler) +{ + assert(!base); +#ifdef WIN32 + evthread_use_windows_threads(); +#else + evthread_use_pthreads(); +#endif + base = event_base_new(); + if (!base) { + LogPrintf("tor: Unable to create event_base\n"); + return; + } + + torControlThread = boost::thread(boost::bind(&TraceThread<void (*)()>, "torcontrol", &TorControlThread)); +} + +void InterruptTorControl() +{ + if (base) { + LogPrintf("tor: Thread interrupt\n"); + event_base_loopbreak(base); + } +} + +void StopTorControl() +{ + if (base) { + torControlThread.join(); + event_base_free(base); + base = 0; + } +} + diff --git a/src/torcontrol.h b/src/torcontrol.h new file mode 100644 index 0000000000..72dc82c5b1 --- /dev/null +++ b/src/torcontrol.h @@ -0,0 +1,20 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +/** + * Functionality for communicating with Tor. + */ +#ifndef BITCOIN_TORCONTROL_H +#define BITCOIN_TORCONTROL_H + +#include "scheduler.h" + +extern const std::string DEFAULT_TOR_CONTROL; +static const bool DEFAULT_LISTEN_ONION = true; + +void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler); +void InterruptTorControl(); +void StopTorControl(); + +#endif /* BITCOIN_TORCONTROL_H */ diff --git a/src/txdb.cpp b/src/txdb.cpp index 21ecd65238..f99e11f26e 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -29,18 +29,8 @@ static const char DB_REINDEX_FLAG = 'R'; static const char DB_LAST_BLOCK = 'l'; -void static BatchWriteCoins(CLevelDBBatch &batch, const uint256 &hash, const CCoins &coins) { - if (coins.IsPruned()) - batch.Erase(make_pair(DB_COINS, hash)); - else - batch.Write(make_pair(DB_COINS, hash), coins); -} - -void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) { - batch.Write(DB_BEST_BLOCK, hash); -} - -CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) { +CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe, true) +{ } bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) const { @@ -59,12 +49,15 @@ uint256 CCoinsViewDB::GetBestBlock() const { } bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { - CLevelDBBatch batch; + CDBBatch batch(&db.GetObfuscateKey()); size_t count = 0; size_t changed = 0; for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) { if (it->second.flags & CCoinsCacheEntry::DIRTY) { - BatchWriteCoins(batch, it->first, it->second.coins); + if (it->second.coins.IsPruned()) + batch.Erase(make_pair(DB_COINS, it->first)); + else + batch.Write(make_pair(DB_COINS, it->first), it->second.coins); changed++; } count++; @@ -72,13 +65,13 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { mapCoins.erase(itOld); } if (!hashBlock.IsNull()) - BatchWriteHashBestChain(batch, hashBlock); + batch.Write(DB_BEST_BLOCK, 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) { +CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) { } bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) { @@ -105,8 +98,8 @@ 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. */ - boost::scoped_ptr<leveldb::Iterator> pcursor(const_cast<CLevelDBWrapper*>(&db)->NewIterator()); - pcursor->SeekToFirst(); + boost::scoped_ptr<CDBIterator> pcursor(const_cast<CDBWrapper*>(&db)->NewIterator()); + pcursor->Seek(DB_COINS); CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); stats.hashBlock = GetBestBlock(); @@ -114,22 +107,10 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { CAmount nTotalAmount = 0; while (pcursor->Valid()) { boost::this_thread::interruption_point(); - try { - leveldb::Slice slKey = pcursor->key(); - CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION); - char chType; - ssKey >> chType; - if (chType == DB_COINS) { - leveldb::Slice slValue = pcursor->value(); - CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION); - CCoins coins; - ssValue >> coins; - uint256 txhash; - ssKey >> txhash; - ss << txhash; - ss << VARINT(coins.nVersion); - ss << (coins.fCoinBase ? 'c' : 'n'); - ss << VARINT(coins.nHeight); + std::pair<char, uint256> key; + CCoins coins; + if (pcursor->GetKey(key) && key.first == DB_COINS) { + if (pcursor->GetValue(coins)) { stats.nTransactions++; for (unsigned int i=0; i<coins.vout.size(); i++) { const CTxOut &out = coins.vout[i]; @@ -140,13 +121,15 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { nTotalAmount += out.nValue; } } - stats.nSerializedSize += 32 + slValue.size(); + stats.nSerializedSize += 32 + pcursor->GetValueSize(); ss << VARINT(0); + } else { + return error("CCoinsViewDB::GetStats() : unable to read value"); } - pcursor->Next(); - } catch (const std::exception& e) { - return error("%s: Deserialize or I/O error - %s", __func__, e.what()); + } else { + break; } + pcursor->Next(); } { LOCK(cs_main); @@ -158,7 +141,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { } bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) { - CLevelDBBatch batch; + CDBBatch batch(&GetObfuscateKey()); for (std::vector<std::pair<int, const CBlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) { batch.Write(make_pair(DB_BLOCK_FILES, it->first), *it->second); } @@ -174,7 +157,7 @@ bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) { } bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> >&vect) { - CLevelDBBatch batch; + CDBBatch batch(&GetObfuscateKey()); for (std::vector<std::pair<uint256,CDiskTxPos> >::const_iterator it=vect.begin(); it!=vect.end(); it++) batch.Write(make_pair(DB_TXINDEX, it->first), it->second); return WriteBatch(batch); @@ -194,26 +177,17 @@ bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) { bool CBlockTreeDB::LoadBlockIndexGuts() { - boost::scoped_ptr<leveldb::Iterator> pcursor(NewIterator()); + boost::scoped_ptr<CDBIterator> pcursor(NewIterator()); - CDataStream ssKeySet(SER_DISK, CLIENT_VERSION); - ssKeySet << make_pair(DB_BLOCK_INDEX, uint256()); - pcursor->Seek(ssKeySet.str()); + pcursor->Seek(make_pair(DB_BLOCK_INDEX, uint256())); // Load mapBlockIndex while (pcursor->Valid()) { boost::this_thread::interruption_point(); - try { - leveldb::Slice slKey = pcursor->key(); - CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION); - char chType; - ssKey >> chType; - if (chType == DB_BLOCK_INDEX) { - leveldb::Slice slValue = pcursor->value(); - CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION); - CDiskBlockIndex diskindex; - ssValue >> diskindex; - + std::pair<char, uint256> key; + if (pcursor->GetKey(key) && key.first == DB_BLOCK_INDEX) { + CDiskBlockIndex diskindex; + if (pcursor->GetValue(diskindex)) { // Construct block index object CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash()); pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); @@ -234,10 +208,10 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pcursor->Next(); } else { - break; // if shutdown requested or finished loading block index + return error("LoadBlockIndex() : failed to read value"); } - } catch (const std::exception& e) { - return error("%s: Deserialize or I/O error - %s", __func__, e.what()); + } else { + break; } } diff --git a/src/txdb.h b/src/txdb.h index bef5dc9fd1..22e0c5704c 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,7 +7,7 @@ #define BITCOIN_TXDB_H #include "coins.h" -#include "leveldbwrapper.h" +#include "dbwrapper.h" #include <map> #include <string> @@ -26,11 +26,11 @@ static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024; //! min. -dbcache in (MiB) static const int64_t nMinDbCache = 4; -/** CCoinsView backed by the LevelDB coin database (chainstate/) */ +/** CCoinsView backed by the coin database (chainstate/) */ class CCoinsViewDB : public CCoinsView { protected: - CLevelDBWrapper db; + CDBWrapper db; public: CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); @@ -42,7 +42,7 @@ public: }; /** Access to the block database (blocks/index/) */ -class CBlockTreeDB : public CLevelDBWrapper +class CBlockTreeDB : public CDBWrapper { public: CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 1370cab0c0..f8e03c2533 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -11,17 +11,21 @@ #include "main.h" #include "policy/fees.h" #include "streams.h" +#include "timedata.h" #include "util.h" #include "utilmoneystr.h" +#include "utiltime.h" #include "version.h" using namespace std; CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, - int64_t _nTime, double _dPriority, - unsigned int _nHeight, bool poolHasNoInputsOf): - tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight), - hadNoDependencies(poolHasNoInputsOf) + int64_t _nTime, double _entryPriority, unsigned int _entryHeight, + bool poolHasNoInputsOf, CAmount _inChainInputValue, + bool _spendsCoinbase, unsigned int _sigOps): + tx(_tx), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight), + hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue), + spendsCoinbase(_spendsCoinbase), sigOpCount(_sigOps) { nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); nModSize = tx.CalculateModifiedSize(nTxSize); @@ -29,7 +33,11 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, nCountWithDescendants = 1; nSizeWithDescendants = nTxSize; - nFeesWithDescendants = nFee; + nModFeesWithDescendants = nFee; + CAmount nValueIn = tx.GetValueOut()+nFee; + assert(inChainInputValue <= nValueIn); + + feeDelta = 0; } CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other) @@ -40,12 +48,19 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other) double CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const { - CAmount nValueIn = tx.GetValueOut()+nFee; - double deltaPriority = ((double)(currentHeight-nHeight)*nValueIn)/nModSize; - double dResult = dPriority + deltaPriority; + double deltaPriority = ((double)(currentHeight-entryHeight)*inChainInputValue)/nModSize; + double dResult = entryPriority + deltaPriority; + if (dResult < 0) // This should only happen if it was called with a height below entry height + dResult = 0; return dResult; } +void CTxMemPoolEntry::UpdateFeeDelta(int64_t newFeeDelta) +{ + nModFeesWithDescendants += newFeeDelta - feeDelta; + feeDelta = newFeeDelta; +} + // Update the given tx for any in-mempool descendants. // Assumes that setMemPoolChildren is correct for the given tx and all // descendants. @@ -100,7 +115,7 @@ bool CTxMemPool::UpdateForDescendants(txiter updateIt, int maxDescendantsToVisit BOOST_FOREACH(txiter cit, setAllDescendants) { if (!setExclude.count(cit->GetTx().GetHash())) { modifySize += cit->GetTxSize(); - modifyFee += cit->GetFee(); + modifyFee += cit->GetModifiedFee(); modifyCount++; cachedDescendants[updateIt].insert(cit); } @@ -230,7 +245,7 @@ void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, setEntries &setAncestors } const int64_t updateCount = (add ? 1 : -1); const int64_t updateSize = updateCount * it->GetTxSize(); - const CAmount updateFee = updateCount * it->GetFee(); + const CAmount updateFee = updateCount * it->GetModifiedFee(); BOOST_FOREACH(txiter ancestorIt, setAncestors) { mapTx.modify(ancestorIt, update_descendant_state(updateSize, updateFee, updateCount)); } @@ -290,7 +305,7 @@ void CTxMemPoolEntry::SetDirty() { nCountWithDescendants = 0; nSizeWithDescendants = nTxSize; - nFeesWithDescendants = nFee; + nModFeesWithDescendants = GetModifiedFee(); } void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount) @@ -298,22 +313,24 @@ void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t if (!IsDirty()) { nSizeWithDescendants += modifySize; assert(int64_t(nSizeWithDescendants) > 0); - nFeesWithDescendants += modifyFee; - assert(nFeesWithDescendants >= 0); + nModFeesWithDescendants += modifyFee; nCountWithDescendants += modifyCount; assert(int64_t(nCountWithDescendants) > 0); } } -CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) : +CTxMemPool::CTxMemPool(const CFeeRate& _minReasonableRelayFee) : nTransactionsUpdated(0) { + _clear(); //lock free clear + // Sanity checks off by default for performance, because otherwise // accepting transactions becomes O(N^2) where N is the number // of transactions in the pool - fSanityCheck = false; + nCheckFrequency = 0; - minerPolicyEstimator = new CBlockPolicyEstimator(_minRelayFee); + minerPolicyEstimator = new CBlockPolicyEstimator(_minReasonableRelayFee); + minReasonableRelayFee = _minReasonableRelayFee; } CTxMemPool::~CTxMemPool() @@ -355,6 +372,17 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, indexed_transaction_set::iterator newit = mapTx.insert(entry).first; mapLinks.insert(make_pair(newit, TxLinks())); + // Update transaction for any feeDelta created by PrioritiseTransaction + // TODO: refactor so that the fee delta is calculated before inserting + // into mapTx. + std::map<uint256, std::pair<double, CAmount> >::const_iterator pos = mapDeltas.find(hash); + if (pos != mapDeltas.end()) { + const std::pair<double, CAmount> &deltas = pos->second; + if (deltas.second) { + mapTx.modify(newit, update_fee_delta(deltas.second)); + } + } + // Update cachedInnerUsage to include contained transaction's usage. // (When we update the entry for in-mempool parents, memory usage will be // further updated.) @@ -471,22 +499,26 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem } } -void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight) +void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags) { - // Remove transactions spending a coinbase which are now immature + // Remove transactions spending a coinbase which are now immature and no-longer-final transactions LOCK(cs); list<CTransaction> transactionsToRemove; for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { const CTransaction& tx = it->GetTx(); - BOOST_FOREACH(const CTxIn& txin, tx.vin) { - indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); - if (it2 != mapTx.end()) - continue; - const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); - if (fSanityCheck) assert(coins); - if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) { - transactionsToRemove.push_back(tx); - break; + if (!CheckFinalTx(tx, flags)) { + transactionsToRemove.push_back(tx); + } else if (it->GetSpendsCoinbase()) { + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); + if (it2 != mapTx.end()) + continue; + const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); + if (nCheckFrequency != 0) assert(coins); + if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) { + transactionsToRemove.push_back(tx); + break; + } } } } @@ -508,6 +540,7 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction> if (txConflict != tx) { remove(txConflict, removed, true); + ClearPrioritisation(txConflict.GetHash()); } } } @@ -538,22 +571,35 @@ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned i } // After the txs in the new block have been removed from the mempool, update policy estimates minerPolicyEstimator->processBlock(nBlockHeight, entries, fCurrentEstimate); + lastRollingFeeUpdate = GetTime(); + blockSinceLastRollingFeeBump = true; } -void CTxMemPool::clear() +void CTxMemPool::_clear() { - LOCK(cs); mapLinks.clear(); mapTx.clear(); mapNextTx.clear(); totalTxSize = 0; cachedInnerUsage = 0; + lastRollingFeeUpdate = GetTime(); + blockSinceLastRollingFeeBump = false; + rollingMinimumFeeRate = 0; ++nTransactionsUpdated; } +void CTxMemPool::clear() +{ + LOCK(cs); + _clear(); +} + void CTxMemPool::check(const CCoinsViewCache *pcoins) const { - if (!fSanityCheck) + if (nCheckFrequency == 0) + return; + + if (insecure_rand() >= nCheckFrequency) return; LogPrint("mempool", "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size()); @@ -600,27 +646,24 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const CTxMemPool::setEntries setChildrenCheck; std::map<COutPoint, CInPoint>::const_iterator iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0)); int64_t childSizes = 0; - CAmount childFees = 0; + CAmount childModFee = 0; for (; iter != mapNextTx.end() && iter->first.hash == it->GetTx().GetHash(); ++iter) { txiter childit = mapTx.find(iter->second.ptx->GetHash()); assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions if (setChildrenCheck.insert(childit).second) { childSizes += childit->GetTxSize(); - childFees += childit->GetFee(); + childModFee += childit->GetModifiedFee(); } } assert(setChildrenCheck == GetMemPoolChildren(it)); - // Also check to make sure size/fees is greater than sum with immediate children. + // Also check to make sure size is greater than sum with immediate children. // just a sanity check, not definitive that this calc is correct... - // also check that the size is less than the size of the entire mempool. if (!it->IsDirty()) { assert(it->GetSizeWithDescendants() >= childSizes + it->GetTxSize()); - assert(it->GetFeesWithDescendants() >= childFees + it->GetFee()); } else { assert(it->GetSizeWithDescendants() == it->GetTxSize()); - assert(it->GetFeesWithDescendants() == it->GetFee()); + assert(it->GetModFeesWithDescendants() == it->GetModifiedFee()); } - assert(it->GetFeesWithDescendants() >= 0); if (fDependsWait) waitingOnDependants.push_back(&(*it)); @@ -683,11 +726,21 @@ CFeeRate CTxMemPool::estimateFee(int nBlocks) const LOCK(cs); return minerPolicyEstimator->estimateFee(nBlocks); } +CFeeRate CTxMemPool::estimateSmartFee(int nBlocks, int *answerFoundAtBlocks) const +{ + LOCK(cs); + return minerPolicyEstimator->estimateSmartFee(nBlocks, answerFoundAtBlocks, *this); +} double CTxMemPool::estimatePriority(int nBlocks) const { LOCK(cs); return minerPolicyEstimator->estimatePriority(nBlocks); } +double CTxMemPool::estimateSmartPriority(int nBlocks, int *answerFoundAtBlocks) const +{ + LOCK(cs); + return minerPolicyEstimator->estimateSmartPriority(nBlocks, answerFoundAtBlocks, *this); +} bool CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const @@ -731,14 +784,26 @@ void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, std::pair<double, CAmount> &deltas = mapDeltas[hash]; deltas.first += dPriorityDelta; deltas.second += nFeeDelta; + txiter it = mapTx.find(hash); + if (it != mapTx.end()) { + mapTx.modify(it, update_fee_delta(deltas.second)); + // Now update all ancestors' modified fees with descendants + setEntries setAncestors; + uint64_t nNoLimit = std::numeric_limits<uint64_t>::max(); + std::string dummy; + CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false); + BOOST_FOREACH(txiter ancestorIt, setAncestors) { + mapTx.modify(ancestorIt, update_descendant_state(0, nFeeDelta, 0)); + } + } } LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta)); } -void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta) +void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta) const { LOCK(cs); - std::map<uint256, std::pair<double, CAmount> >::iterator pos = mapDeltas.find(hash); + std::map<uint256, std::pair<double, CAmount> >::const_iterator pos = mapDeltas.find(hash); if (pos == mapDeltas.end()) return; const std::pair<double, CAmount> &deltas = pos->second; @@ -780,8 +845,8 @@ bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const { size_t CTxMemPool::DynamicMemoryUsage() const { LOCK(cs); - // Estimate the overhead of mapTx to be 9 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented. - return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 9 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + cachedInnerUsage; + // Estimate the overhead of mapTx to be 12 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented. + return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 12 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + cachedInnerUsage; } void CTxMemPool::RemoveStaged(setEntries &stage) { @@ -792,6 +857,22 @@ void CTxMemPool::RemoveStaged(setEntries &stage) { } } +int CTxMemPool::Expire(int64_t time) { + LOCK(cs); + indexed_transaction_set::nth_index<2>::type::iterator it = mapTx.get<2>().begin(); + setEntries toremove; + while (it != mapTx.get<2>().end() && it->GetTime() < time) { + toremove.insert(mapTx.project<0>(it)); + it++; + } + setEntries stage; + BOOST_FOREACH(txiter removeit, toremove) { + CalculateDescendants(removeit, stage); + } + RemoveStaged(stage); + return stage.size(); +} + bool CTxMemPool::addUnchecked(const uint256&hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate) { LOCK(cs); @@ -837,3 +918,80 @@ const CTxMemPool::setEntries & CTxMemPool::GetMemPoolChildren(txiter entry) cons assert(it != mapLinks.end()); return it->second.children; } + +CFeeRate CTxMemPool::GetMinFee(size_t sizelimit) const { + LOCK(cs); + if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0) + return CFeeRate(rollingMinimumFeeRate); + + int64_t time = GetTime(); + if (time > lastRollingFeeUpdate + 10) { + double halflife = ROLLING_FEE_HALFLIFE; + if (DynamicMemoryUsage() < sizelimit / 4) + halflife /= 4; + else if (DynamicMemoryUsage() < sizelimit / 2) + halflife /= 2; + + rollingMinimumFeeRate = rollingMinimumFeeRate / pow(2.0, (time - lastRollingFeeUpdate) / halflife); + lastRollingFeeUpdate = time; + + if (rollingMinimumFeeRate < minReasonableRelayFee.GetFeePerK() / 2) { + rollingMinimumFeeRate = 0; + return CFeeRate(0); + } + } + return std::max(CFeeRate(rollingMinimumFeeRate), minReasonableRelayFee); +} + +void CTxMemPool::trackPackageRemoved(const CFeeRate& rate) { + AssertLockHeld(cs); + if (rate.GetFeePerK() > rollingMinimumFeeRate) { + rollingMinimumFeeRate = rate.GetFeePerK(); + blockSinceLastRollingFeeBump = false; + } +} + +void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<uint256>* pvNoSpendsRemaining) { + LOCK(cs); + + unsigned nTxnRemoved = 0; + CFeeRate maxFeeRateRemoved(0); + while (DynamicMemoryUsage() > sizelimit) { + indexed_transaction_set::nth_index<1>::type::iterator it = mapTx.get<1>().begin(); + + // We set the new mempool min fee to the feerate of the removed set, plus the + // "minimum reasonable fee rate" (ie some value under which we consider txn + // to have 0 fee). This way, we don't allow txn to enter mempool with feerate + // equal to txn which were removed with no block in between. + CFeeRate removed(it->GetModFeesWithDescendants(), it->GetSizeWithDescendants()); + removed += minReasonableRelayFee; + trackPackageRemoved(removed); + maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed); + + setEntries stage; + CalculateDescendants(mapTx.project<0>(it), stage); + nTxnRemoved += stage.size(); + + std::vector<CTransaction> txn; + if (pvNoSpendsRemaining) { + txn.reserve(stage.size()); + BOOST_FOREACH(txiter it, stage) + txn.push_back(it->GetTx()); + } + RemoveStaged(stage); + if (pvNoSpendsRemaining) { + BOOST_FOREACH(const CTransaction& tx, txn) { + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + if (exists(txin.prevout.hash)) + continue; + std::map<COutPoint, CInPoint>::iterator it = mapNextTx.lower_bound(COutPoint(txin.prevout.hash, 0)); + if (it == mapNextTx.end() || it->first.hash != txin.prevout.hash) + pvNoSpendsRemaining->push_back(txin.prevout.hash); + } + } + } + } + + if (maxFeeRateRemoved > CFeeRate(0)) + LogPrint("mempool", "Removed %u txn, rolling minimum fee bumped to %s\n", nTxnRemoved, maxFeeRateRemoved.ToString()); +} diff --git a/src/txmempool.h b/src/txmempool.h index c0eef0dd22..386cb26d25 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -44,12 +44,12 @@ class CTxMemPool; * ("descendant" transactions). * * When a new entry is added to the mempool, we update the descendant state - * (nCountWithDescendants, nSizeWithDescendants, and nFeesWithDescendants) for + * (nCountWithDescendants, nSizeWithDescendants, and nModFeesWithDescendants) for * all ancestors of the newly added transaction. * * If updating the descendant state is skipped, we can mark the entry as - * "dirty", and set nSizeWithDescendants/nFeesWithDescendants to equal nTxSize/ - * nTxFee. (This can potentially happen during a reorg, where we limit the + * "dirty", and set nSizeWithDescendants/nModFeesWithDescendants to equal nTxSize/ + * nFee+feeDelta. (This can potentially happen during a reorg, where we limit the * amount of work we're willing to do to avoid consuming too much CPU.) * */ @@ -63,35 +63,50 @@ private: size_t nModSize; //! ... and modified size for priority size_t nUsageSize; //! ... and total memory usage int64_t nTime; //! Local time when entering the mempool - double dPriority; //! Priority when entering the mempool - unsigned int nHeight; //! Chain height when entering the mempool + double entryPriority; //! Priority when entering the mempool + unsigned int entryHeight; //! Chain height when entering the mempool bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool + CAmount inChainInputValue; //! Sum of all txin values that are already in blockchain + bool spendsCoinbase; //! keep track of transactions that spend a coinbase + unsigned int sigOpCount; //! Legacy sig ops plus P2SH sig op count + int64_t feeDelta; //! Used for determining the priority of the transaction for mining in a block // Information about descendants of this transaction that are in the // mempool; if we remove this transaction we must remove all of these // descendants as well. if nCountWithDescendants is 0, treat this entry as - // dirty, and nSizeWithDescendants and nFeesWithDescendants will not be + // dirty, and nSizeWithDescendants and nModFeesWithDescendants will not be // correct. uint64_t nCountWithDescendants; //! number of descendant transactions uint64_t nSizeWithDescendants; //! ... and size - CAmount nFeesWithDescendants; //! ... and total fees (all including us) + CAmount nModFeesWithDescendants; //! ... and total fees (all including us) public: CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, - int64_t _nTime, double _dPriority, unsigned int _nHeight, bool poolHasNoInputsOf = false); + int64_t _nTime, double _entryPriority, unsigned int _entryHeight, + bool poolHasNoInputsOf, CAmount _inChainInputValue, bool spendsCoinbase, + unsigned int nSigOps); CTxMemPoolEntry(const CTxMemPoolEntry& other); const CTransaction& GetTx() const { return this->tx; } + /** + * Fast calculation of lower bound of current priority as update + * from entry priority. Only inputs that were originally in-chain will age. + */ double GetPriority(unsigned int currentHeight) const; - CAmount GetFee() const { return nFee; } + const CAmount& GetFee() const { return nFee; } size_t GetTxSize() const { return nTxSize; } int64_t GetTime() const { return nTime; } - unsigned int GetHeight() const { return nHeight; } + unsigned int GetHeight() const { return entryHeight; } bool WasClearAtEntry() const { return hadNoDependencies; } + unsigned int GetSigOpCount() const { return sigOpCount; } + int64_t GetModifiedFee() const { return nFee + feeDelta; } size_t DynamicMemoryUsage() const { return nUsageSize; } // Adjusts the descendant state, if this entry is not dirty. void UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount); + // Updates the fee delta used for mining priority score, and the + // modified fees with descendants. + void UpdateFeeDelta(int64_t feeDelta); /** We can set the entry to be dirty if doing the full calculation of in- * mempool descendants will be too expensive, which can potentially happen @@ -102,7 +117,9 @@ public: uint64_t GetCountWithDescendants() const { return nCountWithDescendants; } uint64_t GetSizeWithDescendants() const { return nSizeWithDescendants; } - CAmount GetFeesWithDescendants() const { return nFeesWithDescendants; } + CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; } + + bool GetSpendsCoinbase() const { return spendsCoinbase; } }; // Helpers for modifying CTxMemPool::mapTx, which is a boost multi_index. @@ -127,6 +144,16 @@ struct set_dirty { e.SetDirty(); } }; +struct update_fee_delta +{ + update_fee_delta(int64_t _feeDelta) : feeDelta(_feeDelta) { } + + void operator() (CTxMemPoolEntry &e) { e.UpdateFeeDelta(feeDelta); } + +private: + int64_t feeDelta; +}; + // extracts a TxMemPoolEntry's transaction hash struct mempoolentry_txid { @@ -137,43 +164,61 @@ struct mempoolentry_txid } }; -/** \class CompareTxMemPoolEntryByFee +/** \class CompareTxMemPoolEntryByDescendantScore * - * Sort an entry by max(feerate of entry's tx, feerate with all descendants). + * Sort an entry by max(score/size of entry's tx, score/size with all descendants). */ -class CompareTxMemPoolEntryByFee +class CompareTxMemPoolEntryByDescendantScore { public: bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) { - bool fUseADescendants = UseDescendantFeeRate(a); - bool fUseBDescendants = UseDescendantFeeRate(b); + bool fUseADescendants = UseDescendantScore(a); + bool fUseBDescendants = UseDescendantScore(b); - double aFees = fUseADescendants ? a.GetFeesWithDescendants() : a.GetFee(); + double aModFee = fUseADescendants ? a.GetModFeesWithDescendants() : a.GetModifiedFee(); double aSize = fUseADescendants ? a.GetSizeWithDescendants() : a.GetTxSize(); - double bFees = fUseBDescendants ? b.GetFeesWithDescendants() : b.GetFee(); + double bModFee = fUseBDescendants ? b.GetModFeesWithDescendants() : b.GetModifiedFee(); double bSize = fUseBDescendants ? b.GetSizeWithDescendants() : b.GetTxSize(); // Avoid division by rewriting (a/b > c/d) as (a*d > c*b). - double f1 = aFees * bSize; - double f2 = aSize * bFees; + double f1 = aModFee * bSize; + double f2 = aSize * bModFee; if (f1 == f2) { - return a.GetTime() < b.GetTime(); + return a.GetTime() >= b.GetTime(); } - return f1 > f2; + return f1 < f2; } - // Calculate which feerate to use for an entry (avoiding division). - bool UseDescendantFeeRate(const CTxMemPoolEntry &a) + // Calculate which score to use for an entry (avoiding division). + bool UseDescendantScore(const CTxMemPoolEntry &a) { - double f1 = (double)a.GetFee() * a.GetSizeWithDescendants(); - double f2 = (double)a.GetFeesWithDescendants() * a.GetTxSize(); + double f1 = (double)a.GetModifiedFee() * a.GetSizeWithDescendants(); + double f2 = (double)a.GetModFeesWithDescendants() * a.GetTxSize(); return f2 > f1; } }; +/** \class CompareTxMemPoolEntryByScore + * + * Sort by score of entry ((fee+delta)/size) in descending order + */ +class CompareTxMemPoolEntryByScore +{ +public: + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + { + double f1 = (double)a.GetModifiedFee() * b.GetTxSize(); + double f2 = (double)b.GetModifiedFee() * a.GetTxSize(); + if (f1 == f2) { + return b.GetTx().GetHash() < a.GetTx().GetHash(); + } + return f1 > f2; + } +}; + class CompareTxMemPoolEntryByEntryTime { public: @@ -211,9 +256,11 @@ public: * * CTxMemPool::mapTx, and CTxMemPoolEntry bookkeeping: * - * mapTx is a boost::multi_index that sorts the mempool on 2 criteria: + * mapTx is a boost::multi_index that sorts the mempool on 4 criteria: * - transaction hash * - feerate [we use max(feerate of tx, feerate of tx with all descendants)] + * - time in mempool + * - mining score (feerate modified by any fee deltas from PrioritiseTransaction) * * Note: the term "descendant" refers to in-mempool transactions that depend on * this one, while "ancestor" refers to in-mempool transactions that a given @@ -277,14 +324,25 @@ public: class CTxMemPool { private: - bool fSanityCheck; //! Normally false, true if -checkmempool or -regtest + uint32_t nCheckFrequency; //! Value n means that n times in 2^32 we check. unsigned int nTransactionsUpdated; CBlockPolicyEstimator* minerPolicyEstimator; uint64_t totalTxSize; //! sum of all mempool tx' byte sizes uint64_t cachedInnerUsage; //! sum of dynamic memory usage of all the map elements (NOT the maps themselves) + CFeeRate minReasonableRelayFee; + + mutable int64_t lastRollingFeeUpdate; + mutable bool blockSinceLastRollingFeeBump; + mutable double rollingMinimumFeeRate; //! minimum fee to get into the pool, decreases exponentially + + void trackPackageRemoved(const CFeeRate& rate); + public: + + static const int ROLLING_FEE_HALFLIFE = 60 * 60 * 12; // public only for testing + typedef boost::multi_index_container< CTxMemPoolEntry, boost::multi_index::indexed_by< @@ -293,7 +351,17 @@ public: // sorted by fee rate boost::multi_index::ordered_non_unique< boost::multi_index::identity<CTxMemPoolEntry>, - CompareTxMemPoolEntryByFee + CompareTxMemPoolEntryByDescendantScore + >, + // sorted by entry time + boost::multi_index::ordered_non_unique< + boost::multi_index::identity<CTxMemPoolEntry>, + CompareTxMemPoolEntryByEntryTime + >, + // sorted by score (for mining prioritization) + boost::multi_index::ordered_unique< + boost::multi_index::identity<CTxMemPoolEntry>, + CompareTxMemPoolEntryByScore > > > indexed_transaction_set; @@ -308,6 +376,8 @@ public: }; typedef std::set<txiter, CompareIteratorByHash> setEntries; + const setEntries & GetMemPoolParents(txiter entry) const; + const setEntries & GetMemPoolChildren(txiter entry) const; private: typedef std::map<txiter, setEntries, CompareIteratorByHash> cacheMap; @@ -319,8 +389,6 @@ private: typedef std::map<txiter, TxLinks, CompareIteratorByHash> txlinksMap; txlinksMap mapLinks; - const setEntries & GetMemPoolParents(txiter entry) const; - const setEntries & GetMemPoolChildren(txiter entry) const; void UpdateParent(txiter entry, txiter parent, bool add); void UpdateChild(txiter entry, txiter child, bool add); @@ -328,7 +396,12 @@ public: std::map<COutPoint, CInPoint> mapNextTx; std::map<uint256, std::pair<double, CAmount> > mapDeltas; - CTxMemPool(const CFeeRate& _minRelayFee); + /** Create a new CTxMemPool. + * minReasonableRelayFee should be a feerate which is, roughly, somewhere + * around what it "costs" to relay a transaction around the network and + * below which we would reasonably say a transaction has 0-effective-fee. + */ + CTxMemPool(const CFeeRate& _minReasonableRelayFee); ~CTxMemPool(); /** @@ -338,7 +411,7 @@ public: * check does nothing. */ void check(const CCoinsViewCache *pcoins) const; - void setSanityCheck(bool _fSanityCheck) { fSanityCheck = _fSanityCheck; } + void setSanityCheck(double dFrequency = 1.0) { nCheckFrequency = dFrequency * 4294967295.0; } // addUnchecked must updated state for all ancestors of a given transaction, // to track size/count of descendant transactions. First version of @@ -348,11 +421,12 @@ public: bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate = true); void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false); - void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight); + void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags); void removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed); void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight, std::list<CTransaction>& conflicts, bool fCurrentEstimate = true); void clear(); + void _clear(); //lock free void queryHashes(std::vector<uint256>& vtxid); void pruneSpent(const uint256& hash, CCoins &coins); unsigned int GetTransactionsUpdated() const; @@ -365,7 +439,7 @@ public: /** Affect CreateNewBlock prioritisation of transactions */ void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, const CAmount& nFeeDelta); - void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta); + void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta) const; void ClearPrioritisation(const uint256 hash); public: @@ -397,6 +471,28 @@ public: */ bool CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents = true); + /** Populate setDescendants with all in-mempool descendants of hash. + * Assumes that setDescendants includes all in-mempool descendants of anything + * already in it. */ + void CalculateDescendants(txiter it, setEntries &setDescendants); + + /** The minimum fee to get into the mempool, which may itself not be enough + * for larger-sized transactions. + * The minReasonableRelayFee constructor arg is used to bound the time it + * takes the fee rate to go back down all the way to 0. When the feerate + * would otherwise be half of this, it is set to 0 instead. + */ + CFeeRate GetMinFee(size_t sizelimit) const; + + /** Remove transactions from the mempool until its dynamic size is <= sizelimit. + * pvNoSpendsRemaining, if set, will be populated with the list of transactions + * which are not in mempool which no longer have any spends in this mempool. + */ + void TrimToSize(size_t sizelimit, std::vector<uint256>* pvNoSpendsRemaining=NULL); + + /** Expire all transaction (and their dependencies) in the mempool older than time. Return the number of removed transactions. */ + int Expire(int64_t time); + unsigned long size() { LOCK(cs); @@ -417,9 +513,21 @@ public: bool lookup(uint256 hash, CTransaction& result) const; + /** Estimate fee rate needed to get into the next nBlocks + * If no answer can be given at nBlocks, return an estimate + * at the lowest number of blocks where one can be given + */ + CFeeRate estimateSmartFee(int nBlocks, int *answerFoundAtBlocks = NULL) const; + /** Estimate fee rate needed to get into the next nBlocks */ CFeeRate estimateFee(int nBlocks) const; + /** Estimate priority needed to get into the next nBlocks + * If no answer can be given at nBlocks, return an estimate + * at the lowest number of blocks where one can be given + */ + double estimateSmartPriority(int nBlocks, int *answerFoundAtBlocks = NULL) const; + /** Estimate priority needed to get into the next nBlocks */ double estimatePriority(int nBlocks) const; @@ -456,10 +564,6 @@ private: void UpdateForRemoveFromMempool(const setEntries &entriesToRemove); /** Sever link between specified transaction and direct children. */ void UpdateChildrenForRemoval(txiter entry); - /** Populate setDescendants with all in-mempool descendants of hash. - * Assumes that setDescendants includes all in-mempool descendants of anything - * already in it. */ - void CalculateDescendants(txiter it, setEntries &setDescendants); /** Before calling removeUnchecked for a given transaction, * UpdateForRemoveFromMempool must be called on the entire (dependent) set @@ -487,4 +591,17 @@ public: bool HaveCoins(const uint256 &txid) const; }; +// We want to sort transactions by coin age priority +typedef std::pair<double, CTxMemPool::txiter> TxCoinAgePriority; + +struct TxCoinAgePriorityCompare +{ + bool operator()(const TxCoinAgePriority& a, const TxCoinAgePriority& b) + { + if (a.first == b.first) + return CompareTxMemPoolEntryByScore()(*(b.second), *(a.second)); //Reverse order to make sort less than + return a.first < b.first; + } +}; + #endif // BITCOIN_TXMEMPOOL_H diff --git a/src/ui_interface.h b/src/ui_interface.h index e402479933..967d243270 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2012 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,6 +15,7 @@ class CBasicKeyStore; class CWallet; class uint256; +class CBlockIndex; /** General change type (added, updated, removed). */ enum ChangeType @@ -94,7 +95,7 @@ public: boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress; /** New block has been accepted */ - boost::signals2::signal<void (const uint256& hash)> NotifyBlockTip; + boost::signals2::signal<void (bool, const CBlockIndex *)> NotifyBlockTip; /** Banlist did change. */ boost::signals2::signal<void (void)> BannedListChanged; diff --git a/src/uint256.cpp b/src/uint256.cpp index 25148808c6..c58c88bf4a 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/uint256.h b/src/uint256.h index 6d016ab164..4495000f2f 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,6 +12,7 @@ #include <stdint.h> #include <string> #include <vector> +#include "crypto/common.h" /** Template base class for fixed-sized opaque blobs. */ template<unsigned int BITS> @@ -119,13 +120,10 @@ public: * used when the contents are considered uniformly random. It is not appropriate * when the value can easily be influenced from outside as e.g. a network adversary could * provide values to trigger worst-case behavior. - * @note The result of this function is not stable between little and big endian. */ uint64_t GetCheapHash() const { - uint64_t result; - memcpy((void*)&result, (void*)data, 8); - return result; + return ReadLE64(data); } /** A more secure, salted hash function. diff --git a/src/univalue/.gitignore b/src/univalue/.gitignore index ca9e842348..19e42f814a 100644 --- a/src/univalue/.gitignore +++ b/src/univalue/.gitignore @@ -18,5 +18,15 @@ univalue-config.h* test-driver libtool ltmain.sh +test-suite.log +*.a +*.la +*.lo +*.logs *.o +*.pc +*.trs + +.dirstamp +.libs diff --git a/src/univalue/.travis.yml b/src/univalue/.travis.yml index af632c78d9..d318d9cc8f 100644 --- a/src/univalue/.travis.yml +++ b/src/univalue/.travis.yml @@ -36,7 +36,7 @@ script: - ./configure --cache-file=config.cache $UNIVALUE_CONFIG_ALL $UNIVALUE_CONFIG || ( cat config.log && false) - make -s $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL ; false ) - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib - - if [ "$RUN_TESTS" = "true" ]; then make check; fi + - if [ "$RUN_TESTS" = "true" ]; then make $MAKEJOBS distcheck; fi matrix: fast_finish: true diff --git a/src/univalue/Makefile.am b/src/univalue/Makefile.am index 2800f466dc..34fe9e3f13 100644 --- a/src/univalue/Makefile.am +++ b/src/univalue/Makefile.am @@ -5,20 +5,20 @@ ACLOCAL_AMFLAGS = -I build-aux/m4 include_HEADERS = include/univalue.h noinst_HEADERS = lib/univalue_escapes.h -lib_LTLIBRARIES = lib/libunivalue.la +lib_LTLIBRARIES = libunivalue.la pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = pc/libunivalue.pc -lib_libunivalue_la_SOURCES = \ +libunivalue_la_SOURCES = \ lib/univalue.cpp \ lib/univalue_read.cpp \ lib/univalue_write.cpp -lib_libunivalue_la_LDFLAGS = \ +libunivalue_la_LDFLAGS = \ -version-info $(LIBUNIVALUE_CURRENT):$(LIBUNIVALUE_REVISION):$(LIBUNIVALUE_AGE) \ -no-undefined -lib_libunivalue_la_CXXFLAGS = -I$(top_srcdir)/include +libunivalue_la_CXXFLAGS = -I$(top_srcdir)/include TESTS = test/unitester @@ -38,7 +38,7 @@ noinst_PROGRAMS = $(TESTS) TEST_DATA_DIR=test test_unitester_SOURCES = test/unitester.cpp -test_unitester_LDADD = lib/libunivalue.la +test_unitester_LDADD = libunivalue.la test_unitester_CXXFLAGS = -I$(top_srcdir)/include -DJSON_TEST_SRC=\"$(srcdir)/$(TEST_DATA_DIR)\" test_unitester_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS) @@ -70,6 +70,9 @@ TEST_FILES = \ $(TEST_DATA_DIR)/fail32.json \ $(TEST_DATA_DIR)/fail33.json \ $(TEST_DATA_DIR)/fail34.json \ + $(TEST_DATA_DIR)/fail35.json \ + $(TEST_DATA_DIR)/fail36.json \ + $(TEST_DATA_DIR)/fail37.json \ $(TEST_DATA_DIR)/fail3.json \ $(TEST_DATA_DIR)/fail4.json \ $(TEST_DATA_DIR)/fail5.json \ @@ -79,6 +82,7 @@ TEST_FILES = \ $(TEST_DATA_DIR)/fail9.json \ $(TEST_DATA_DIR)/pass1.json \ $(TEST_DATA_DIR)/pass2.json \ - $(TEST_DATA_DIR)/pass3.json + $(TEST_DATA_DIR)/pass3.json \ + $(TEST_DATA_DIR)/round1.json EXTRA_DIST=$(TEST_FILES) $(GEN_SRCS) diff --git a/src/univalue/build-aux/m4/.empty b/src/univalue/build-aux/m4/.empty deleted file mode 100644 index e69de29bb2..0000000000 --- a/src/univalue/build-aux/m4/.empty +++ /dev/null diff --git a/src/univalue/build-aux/m4/.gitignore b/src/univalue/build-aux/m4/.gitignore new file mode 100644 index 0000000000..f063686524 --- /dev/null +++ b/src/univalue/build-aux/m4/.gitignore @@ -0,0 +1 @@ +/*.m4 diff --git a/src/univalue/configure.ac b/src/univalue/configure.ac index 6cd9516229..0515b632bd 100644 --- a/src/univalue/configure.ac +++ b/src/univalue/configure.ac @@ -14,7 +14,7 @@ m4_define([libunivalue_age], [m4_eval(libunivalue_binary_age - libunivalue_inter m4_define([libunivalue_version], [libunivalue_major_version().libunivalue_minor_version().libunivalue_micro_version()libunivalue_extraversion()]) -AC_INIT([univalue], [1.0.0], +AC_INIT([univalue], [1.0.1], [http://github.com/jgarzik/univalue/]) dnl make the compilation flags quiet unless V=1 is used diff --git a/src/univalue/gen/gen.cpp b/src/univalue/gen/gen.cpp index 5e5a4d4aed..17f361941d 100644 --- a/src/univalue/gen/gen.cpp +++ b/src/univalue/gen/gen.cpp @@ -8,7 +8,6 @@ // $ ./gen > univalue_escapes.h // -#include <ctype.h> #include <stdio.h> #include <string.h> #include "univalue.h" @@ -16,10 +15,17 @@ using namespace std; static bool initEscapes; -static const char *escapes[256]; +static std::string escapes[256]; static void initJsonEscape() { + // Escape all lower control characters (some get overridden with smaller sequences below) + for (int ch=0x00; ch<0x20; ++ch) { + char tmpbuf[20]; + snprintf(tmpbuf, sizeof(tmpbuf), "\\u%04x", ch); + escapes[ch] = std::string(tmpbuf); + } + escapes[(int)'"'] = "\\\""; escapes[(int)'\\'] = "\\\\"; escapes[(int)'\b'] = "\\b"; @@ -27,6 +33,7 @@ static void initJsonEscape() escapes[(int)'\n'] = "\\n"; escapes[(int)'\r'] = "\\r"; escapes[(int)'\t'] = "\\t"; + escapes[(int)'\x7f'] = "\\u007f"; // U+007F DELETE initEscapes = true; } @@ -39,13 +46,13 @@ static void outputEscape() "static const char *escapes[256] = {\n"); for (unsigned int i = 0; i < 256; i++) { - if (!escapes[i]) { + if (escapes[i].empty()) { printf("\tNULL,\n"); } else { printf("\t\""); unsigned int si; - for (si = 0; si < strlen(escapes[i]); si++) { + for (si = 0; si < escapes[i].size(); si++) { char ch = escapes[i][si]; switch (ch) { case '"': diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h index ac05116011..8428b1c683 100644 --- a/src/univalue/include/univalue.h +++ b/src/univalue/include/univalue.h @@ -243,8 +243,41 @@ extern enum jtokentype getJsonToken(std::string& tokenVal, unsigned int& consumed, const char *raw); extern const char *uvTypeName(UniValue::VType t); +static inline bool jsonTokenIsValue(enum jtokentype jtt) +{ + switch (jtt) { + case JTOK_KW_NULL: + case JTOK_KW_TRUE: + case JTOK_KW_FALSE: + case JTOK_NUMBER: + case JTOK_STRING: + return true; + + default: + return false; + } + + // not reached +} + +static inline bool json_isspace(int ch) +{ + switch (ch) { + case 0x20: + case 0x09: + case 0x0a: + case 0x0d: + return true; + + default: + return false; + } + + // not reached +} + extern const UniValue NullUniValue; const UniValue& find_value( const UniValue& obj, const std::string& name); -#endif // __UNIVALUE_H__
\ No newline at end of file +#endif // __UNIVALUE_H__ diff --git a/src/univalue/lib/.gitignore b/src/univalue/lib/.gitignore index ca8c16dcd4..ee7fc2851c 100644 --- a/src/univalue/lib/.gitignore +++ b/src/univalue/lib/.gitignore @@ -1,10 +1,2 @@ - -libunivalue-uninstalled.pc -libunivalue.pc -libunivalue.a gen - .libs -*.lo -*.la - diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp index 883e8651fe..0076d6678e 100644 --- a/src/univalue/lib/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -4,7 +4,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <stdint.h> -#include <ctype.h> #include <errno.h> #include <iomanip> #include <limits> @@ -21,7 +20,7 @@ static bool ParsePrechecks(const std::string& str) { if (str.empty()) // No empty string allowed return false; - if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size()-1]))) // No padding allowed + if (str.size() >= 1 && (json_isspace(str[0]) || json_isspace(str[str.size()-1]))) // No padding allowed return false; if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed return false; @@ -210,7 +209,7 @@ bool UniValue::pushKVs(const UniValue& obj) for (unsigned int i = 0; i < obj.keys.size(); i++) { keys.push_back(obj.keys[i]); - values.push_back(obj.values[i]); + values.push_back(obj.values.at(i)); } return true; @@ -234,7 +233,7 @@ bool UniValue::checkObject(const std::map<std::string,UniValue::VType>& t) if (idx < 0) return false; - if (values[idx].getType() != it->second) + if (values.at(idx).getType() != it->second) return false; } @@ -250,7 +249,7 @@ const UniValue& UniValue::operator[](const std::string& key) const if (index < 0) return NullUniValue; - return values[index]; + return values.at(index); } const UniValue& UniValue::operator[](unsigned int index) const @@ -260,7 +259,7 @@ const UniValue& UniValue::operator[](unsigned int index) const if (index >= values.size()) return NullUniValue; - return values[index]; + return values.at(index); } const char *uvTypeName(UniValue::VType t) @@ -278,15 +277,11 @@ const char *uvTypeName(UniValue::VType t) return NULL; } -const UniValue& find_value( const UniValue& obj, const std::string& name) +const UniValue& find_value(const UniValue& obj, const std::string& name) { for (unsigned int i = 0; i < obj.keys.size(); i++) - { - if( obj.keys[i] == name ) - { - return obj.values[i]; - } - } + if (obj.keys[i] == name) + return obj.values.at(i); return NullUniValue; } diff --git a/src/univalue/lib/univalue_escapes.h b/src/univalue/lib/univalue_escapes.h index 4133b24ca1..74596aab6d 100644 --- a/src/univalue/lib/univalue_escapes.h +++ b/src/univalue/lib/univalue_escapes.h @@ -2,38 +2,38 @@ #ifndef BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H #define BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H static const char *escapes[256] = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + "\\u0000", + "\\u0001", + "\\u0002", + "\\u0003", + "\\u0004", + "\\u0005", + "\\u0006", + "\\u0007", "\\b", "\\t", "\\n", - NULL, + "\\u000b", "\\f", "\\r", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + "\\u000e", + "\\u000f", + "\\u0010", + "\\u0011", + "\\u0012", + "\\u0013", + "\\u0014", + "\\u0015", + "\\u0016", + "\\u0017", + "\\u0018", + "\\u0019", + "\\u001a", + "\\u001b", + "\\u001c", + "\\u001d", + "\\u001e", + "\\u001f", NULL, NULL, "\\\"", @@ -129,7 +129,7 @@ static const char *escapes[256] = { NULL, NULL, NULL, - NULL, + "\\u007f", NULL, NULL, NULL, diff --git a/src/univalue/lib/univalue_read.cpp b/src/univalue/lib/univalue_read.cpp index 64591234cb..c7516b9628 100644 --- a/src/univalue/lib/univalue_read.cpp +++ b/src/univalue/lib/univalue_read.cpp @@ -9,6 +9,11 @@ using namespace std; +static bool json_isdigit(int ch) +{ + return ((ch >= '0') && (ch <= '9')); +} + // convert hexadecimal string to unsigned integer static const char *hatoui(const char *first, const char *last, unsigned int& out) @@ -17,7 +22,7 @@ static const char *hatoui(const char *first, const char *last, for (; first != last; ++first) { int digit; - if (isdigit(*first)) + if (json_isdigit(*first)) digit = *first - '0'; else if (*first >= 'a' && *first <= 'f') @@ -44,7 +49,7 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, const char *rawStart = raw; - while ((*raw) && (isspace(*raw))) // skip whitespace + while ((*raw) && (json_isspace(*raw))) // skip whitespace raw++; switch (*raw) { @@ -113,18 +118,18 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, const char *first = raw; const char *firstDigit = first; - if (!isdigit(*firstDigit)) + if (!json_isdigit(*firstDigit)) firstDigit++; - if ((*firstDigit == '0') && isdigit(firstDigit[1])) + if ((*firstDigit == '0') && json_isdigit(firstDigit[1])) return JTOK_ERR; numStr += *raw; // copy first char raw++; - if ((*first == '-') && (!isdigit(*raw))) + if ((*first == '-') && (!json_isdigit(*raw))) return JTOK_ERR; - while ((*raw) && isdigit(*raw)) { // copy digits + while ((*raw) && json_isdigit(*raw)) { // copy digits numStr += *raw; raw++; } @@ -134,9 +139,9 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, numStr += *raw; // copy . raw++; - if (!isdigit(*raw)) + if (!json_isdigit(*raw)) return JTOK_ERR; - while ((*raw) && isdigit(*raw)) { // copy digits + while ((*raw) && json_isdigit(*raw)) { // copy digits numStr += *raw; raw++; } @@ -152,9 +157,9 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, raw++; } - if (!isdigit(*raw)) + if (!json_isdigit(*raw)) return JTOK_ERR; - while ((*raw) && isdigit(*raw)) { // copy digits + while ((*raw) && json_isdigit(*raw)) { // copy digits numStr += *raw; raw++; } @@ -236,12 +241,23 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, } } +enum expect_bits { + EXP_OBJ_NAME = (1U << 0), + EXP_COLON = (1U << 1), + EXP_ARR_VALUE = (1U << 2), + EXP_VALUE = (1U << 3), + EXP_NOT_VALUE = (1U << 4), +}; + +#define expect(bit) (expectMask & (EXP_##bit)) +#define setExpect(bit) (expectMask |= EXP_##bit) +#define clearExpect(bit) (expectMask &= ~EXP_##bit) + bool UniValue::read(const char *raw) { clear(); - bool expectName = false; - bool expectColon = false; + uint32_t expectMask = 0; vector<UniValue*> stack; string tokenVal; @@ -256,6 +272,41 @@ bool UniValue::read(const char *raw) return false; raw += consumed; + bool isValueOpen = jsonTokenIsValue(tok) || + tok == JTOK_OBJ_OPEN || tok == JTOK_ARR_OPEN; + + if (expect(VALUE)) { + if (!isValueOpen) + return false; + clearExpect(VALUE); + + } else if (expect(ARR_VALUE)) { + bool isArrValue = isValueOpen || (tok == JTOK_ARR_CLOSE); + if (!isArrValue) + return false; + + clearExpect(ARR_VALUE); + + } else if (expect(OBJ_NAME)) { + bool isObjName = (tok == JTOK_OBJ_CLOSE || tok == JTOK_STRING); + if (!isObjName) + return false; + + } else if (expect(COLON)) { + if (tok != JTOK_COLON) + return false; + clearExpect(COLON); + + } else if (!expect(COLON) && (tok == JTOK_COLON)) { + return false; + } + + if (expect(NOT_VALUE)) { + if (isValueOpen) + return false; + clearExpect(NOT_VALUE); + } + switch (tok) { case JTOK_OBJ_OPEN: @@ -277,13 +328,15 @@ bool UniValue::read(const char *raw) } if (utyp == VOBJ) - expectName = true; + setExpect(OBJ_NAME); + else + setExpect(ARR_VALUE); break; } case JTOK_OBJ_CLOSE: case JTOK_ARR_CLOSE: { - if (!stack.size() || expectColon || (last_tok == JTOK_COMMA)) + if (!stack.size() || (last_tok == JTOK_COMMA)) return false; VType utyp = (tok == JTOK_OBJ_CLOSE ? VOBJ : VARR); @@ -292,37 +345,40 @@ bool UniValue::read(const char *raw) return false; stack.pop_back(); - expectName = false; + clearExpect(OBJ_NAME); + setExpect(NOT_VALUE); break; } case JTOK_COLON: { - if (!stack.size() || expectName || !expectColon) + if (!stack.size()) return false; UniValue *top = stack.back(); if (top->getType() != VOBJ) return false; - expectColon = false; + setExpect(VALUE); break; } case JTOK_COMMA: { - if (!stack.size() || expectName || expectColon || + if (!stack.size() || (last_tok == JTOK_COMMA) || (last_tok == JTOK_ARR_OPEN)) return false; UniValue *top = stack.back(); if (top->getType() == VOBJ) - expectName = true; + setExpect(OBJ_NAME); + else + setExpect(ARR_VALUE); break; } case JTOK_KW_NULL: case JTOK_KW_TRUE: case JTOK_KW_FALSE: { - if (!stack.size() || expectName || expectColon) + if (!stack.size()) return false; UniValue tmpVal; @@ -342,17 +398,19 @@ bool UniValue::read(const char *raw) UniValue *top = stack.back(); top->values.push_back(tmpVal); + setExpect(NOT_VALUE); break; } case JTOK_NUMBER: { - if (!stack.size() || expectName || expectColon) + if (!stack.size()) return false; UniValue tmpVal(VNUM, tokenVal); UniValue *top = stack.back(); top->values.push_back(tmpVal); + setExpect(NOT_VALUE); break; } @@ -362,15 +420,16 @@ bool UniValue::read(const char *raw) UniValue *top = stack.back(); - if (expectName) { + if (expect(OBJ_NAME)) { top->keys.push_back(tokenVal); - expectName = false; - expectColon = true; + clearExpect(OBJ_NAME); + setExpect(COLON); } else { UniValue tmpVal(VSTR, tokenVal); top->values.push_back(tmpVal); } + setExpect(NOT_VALUE); break; } diff --git a/src/univalue/lib/univalue_write.cpp b/src/univalue/lib/univalue_write.cpp index bce3997af7..ceb4cc9166 100644 --- a/src/univalue/lib/univalue_write.cpp +++ b/src/univalue/lib/univalue_write.cpp @@ -2,7 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <ctype.h> #include <iomanip> #include <sstream> #include <stdio.h> @@ -25,10 +24,10 @@ static string json_escape(const string& inS) if (escStr) outS += escStr; - else if (isprint(ch)) + else if (ch < 0x80) outS += ch; - else { + else { // TODO handle UTF-8 properly char tmpesc[16]; sprintf(tmpesc, "\\u%04x", ch); outS += tmpesc; @@ -113,7 +112,7 @@ void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, s += "\"" + json_escape(keys[i]) + "\":"; if (prettyIndent) s += " "; - s += values[i].write(prettyIndent, indentLevel + 1); + s += values.at(i).write(prettyIndent, indentLevel + 1); if (i != (values.size() - 1)) s += ","; if (prettyIndent) diff --git a/src/univalue/test/.gitignore b/src/univalue/test/.gitignore index e4dea0df72..3d9347fe7e 100644 --- a/src/univalue/test/.gitignore +++ b/src/univalue/test/.gitignore @@ -1,7 +1,4 @@ - unitester -*.log *.trs - -.libs +*.log diff --git a/src/univalue/test/fail35.json b/src/univalue/test/fail35.json new file mode 100644 index 0000000000..de30ca5c47 --- /dev/null +++ b/src/univalue/test/fail35.json @@ -0,0 +1 @@ +[ true true true [] [] [] ] diff --git a/src/univalue/test/fail36.json b/src/univalue/test/fail36.json new file mode 100644 index 0000000000..f82eb8e1f0 --- /dev/null +++ b/src/univalue/test/fail36.json @@ -0,0 +1 @@ +{"a":} diff --git a/src/univalue/test/fail37.json b/src/univalue/test/fail37.json new file mode 100644 index 0000000000..3294dc3a42 --- /dev/null +++ b/src/univalue/test/fail37.json @@ -0,0 +1 @@ +{"a":1 "b":2} diff --git a/src/univalue/test/round1.json b/src/univalue/test/round1.json new file mode 100644 index 0000000000..a711e7308b --- /dev/null +++ b/src/univalue/test/round1.json @@ -0,0 +1 @@ +["\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f"] diff --git a/src/univalue/test/unitester.cpp b/src/univalue/test/unitester.cpp index 835556e031..5a052fe92c 100644 --- a/src/univalue/test/unitester.cpp +++ b/src/univalue/test/unitester.cpp @@ -19,24 +19,37 @@ using namespace std; string srcdir(JSON_TEST_SRC); +static bool test_failed = false; -static void runtest(string filename, const string& jdata) +#define d_assert(expr) { if (!(expr)) { test_failed = true; fprintf(stderr, "%s failed\n", filename.c_str()); } } + +static std::string rtrim(std::string s) { - fprintf(stderr, "test %s\n", filename.c_str()); + s.erase(s.find_last_not_of(" \n\r\t")+1); + return s; +} +static void runtest(string filename, const string& jdata) +{ string prefix = filename.substr(0, 4); - bool wantPass = (prefix == "pass"); + bool wantPass = (prefix == "pass") || (prefix == "roun"); bool wantFail = (prefix == "fail"); + bool wantRoundTrip = (prefix == "roun"); assert(wantPass || wantFail); UniValue val; bool testResult = val.read(jdata); if (wantPass) { - assert(testResult == true); + d_assert(testResult == true); } else { - assert(testResult == false); + d_assert(testResult == false); + } + + if (wantRoundTrip) { + std::string odata = val.write(0, 0); + assert(odata == rtrim(jdata)); } } @@ -92,6 +105,9 @@ static const char *filenames[] = { "fail32.json", "fail33.json", "fail34.json", + "fail35.json", + "fail36.json", + "fail37.json", "fail3.json", "fail4.json", // extra comma "fail5.json", @@ -102,6 +118,7 @@ static const char *filenames[] = { "pass1.json", "pass2.json", "pass3.json", + "round1.json", // round-trip test }; int main (int argc, char *argv[]) @@ -110,6 +127,6 @@ int main (int argc, char *argv[]) runtest_file(filenames[fidx]); } - return 0; + return test_failed ? 1 : 0; } diff --git a/src/util.cpp b/src/util.cpp index f50d25e17a..019c912f51 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -99,6 +99,9 @@ namespace boost { using namespace std; +const char * const BITCOIN_CONF_FILENAME = "bitcoin.conf"; +const char * const BITCOIN_PID_FILENAME = "bitcoind.pid"; + map<string, string> mapArgs; map<string, vector<string> > mapMultiArgs; bool fDebug = false; @@ -107,8 +110,9 @@ bool fPrintToDebugLog = true; bool fDaemon = false; bool fServer = false; string strMiscWarning; -bool fLogTimestamps = false; -bool fLogIPs = false; +bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS; +bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS; +bool fLogIPs = DEFAULT_LOGIPS; volatile bool fReopenDebugLog = false; CTranslationInterface translationInterface; @@ -263,9 +267,13 @@ static std::string LogTimestampStr(const std::string &str, bool *fStartedNewLine if (!fLogTimestamps) return str; - if (*fStartedNewLine) - strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()) + ' ' + str; - else + if (*fStartedNewLine) { + int64_t nTimeMicros = GetLogTimeMicros(); + strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nTimeMicros/1000000); + if (fLogTimeMicros) + strStamped += strprintf(".%06d", nTimeMicros%1000000); + strStamped += ' ' + str; + } else strStamped = str; if (!str.empty() && str[str.size()-1] == '\n') @@ -280,10 +288,13 @@ int LogPrintStr(const std::string &str) { int ret = 0; // Returns total number of characters written static bool fStartedNewLine = true; + + string strTimestamped = LogTimestampStr(str, &fStartedNewLine); + if (fPrintToConsole) { // print to console - ret = fwrite(str.data(), 1, str.size(), stdout); + ret = fwrite(strTimestamped.data(), 1, strTimestamped.size(), stdout); fflush(stdout); } else if (fPrintToDebugLog) @@ -291,8 +302,6 @@ int LogPrintStr(const std::string &str) boost::call_once(&DebugPrintInit, debugPrintInitFlag); boost::mutex::scoped_lock scoped_lock(*mutexDebugLog); - string strTimestamped = LogTimestampStr(str, &fStartedNewLine); - // buffer if we haven't opened the log yet if (fileout == NULL) { assert(vMsgsBeforeOpenLog); @@ -441,7 +450,6 @@ void PrintExceptionContinue(const std::exception* pex, const char* pszThread) std::string message = FormatException(pex, pszThread); LogPrintf("\n\n************************\n%s\n", message); fprintf(stderr, "\n\n************************\n%s\n", message.c_str()); - strMiscWarning = message; } boost::filesystem::path GetDefaultDataDir() @@ -515,7 +523,7 @@ void ClearDatadirCache() boost::filesystem::path GetConfigFile() { - boost::filesystem::path pathConfigFile(GetArg("-conf", "bitcoin.conf")); + boost::filesystem::path pathConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)); if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile; @@ -549,7 +557,7 @@ void ReadConfigFile(map<string, string>& mapSettingsRet, #ifndef WIN32 boost::filesystem::path GetPidFile() { - boost::filesystem::path pathPidFile(GetArg("-pid", "bitcoind.pid")); + boost::filesystem::path pathPidFile(GetArg("-pid", BITCOIN_PID_FILENAME)); if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile; return pathPidFile; } diff --git a/src/util.h b/src/util.h index 0b2dc01ac6..4d3c029e9a 100644 --- a/src/util.h +++ b/src/util.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -28,6 +28,10 @@ #include <boost/signals2/signal.hpp> #include <boost/thread/exceptions.hpp> +static const bool DEFAULT_LOGTIMEMICROS = false; +static const bool DEFAULT_LOGIPS = false; +static const bool DEFAULT_LOGTIMESTAMPS = true; + /** Signals for translation. */ class CTranslationInterface { @@ -44,10 +48,14 @@ extern bool fPrintToDebugLog; extern bool fServer; extern std::string strMiscWarning; extern bool fLogTimestamps; +extern bool fLogTimeMicros; extern bool fLogIPs; extern volatile bool fReopenDebugLog; extern CTranslationInterface translationInterface; +extern const char * const BITCOIN_CONF_FILENAME; +extern const char * const BITCOIN_PID_FILENAME; + /** * Translation function: Call Translate signal on UI interface, which returns a boost::optional result. * If no translation slot is registered, nothing is returned, and simply return the input. diff --git a/src/utilmoneystr.cpp b/src/utilmoneystr.cpp index 0f3203432f..bebe56130d 100644 --- a/src/utilmoneystr.cpp +++ b/src/utilmoneystr.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilmoneystr.h b/src/utilmoneystr.h index 99c3ba8306..5839b07344 100644 --- a/src/utilmoneystr.h +++ b/src/utilmoneystr.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index c5a2b5cdbb..130bc997ba 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index ce93e83497..d40613cfc4 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utiltime.cpp b/src/utiltime.cpp index d316288999..91b40d9991 100644 --- a/src/utiltime.cpp +++ b/src/utiltime.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -20,7 +20,9 @@ int64_t GetTime() { if (nMockTime) return nMockTime; - return time(NULL); + time_t now = time(NULL); + assert(now > 0); + return now; } void SetMockTime(int64_t nMockTimeIn) @@ -30,14 +32,26 @@ void SetMockTime(int64_t nMockTimeIn) int64_t GetTimeMillis() { - return (boost::posix_time::microsec_clock::universal_time() - - boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds(); + int64_t now = (boost::posix_time::microsec_clock::universal_time() - + boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds(); + assert(now > 0); + return now; } int64_t GetTimeMicros() { - return (boost::posix_time::microsec_clock::universal_time() - - boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds(); + int64_t now = (boost::posix_time::microsec_clock::universal_time() - + boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds(); + assert(now > 0); + return now; +} + +/** Return a time useful for the debug log */ +int64_t GetLogTimeMicros() +{ + if (nMockTime) return nMockTime*1000000; + + return GetTimeMicros(); } void MilliSleep(int64_t n) diff --git a/src/utiltime.h b/src/utiltime.h index 900992f871..b2807267db 100644 --- a/src/utiltime.h +++ b/src/utiltime.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,6 +12,7 @@ int64_t GetTime(); int64_t GetTimeMillis(); int64_t GetTimeMicros(); +int64_t GetLogTimeMicros(); void SetMockTime(int64_t nMockTimeIn); void MilliSleep(int64_t n); diff --git a/src/validationinterface.h b/src/validationinterface.h index ffb56d266b..4da145473b 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/version.h b/src/version.h index 6cdddf9255..f7cf18d0b6 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 70011; +static const int PROTOCOL_VERSION = 70012; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -37,4 +37,7 @@ static const int MEMPOOL_GD_VERSION = 60002; //! "filter*" commands are disabled without NODE_BLOOM after and including this version static const int NO_BLOOM_VERSION = 70011; +//! "sendheaders" command and announcing blocks with headers starts with this version +static const int SENDHEADERS_VERSION = 70012; + #endif // BITCOIN_VERSION_H diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index c86ad9758e..95aa4c2593 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index 70aeb76723..eb06a7866a 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index e5bc653c33..d18250b76f 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -85,7 +85,7 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string()); unsigned int nEnvFlags = 0; - if (GetBoolArg("-privdb", true)) + if (GetBoolArg("-privdb", DEFAULT_WALLET_PRIVDB)) nEnvFlags |= DB_PRIVATE; dbenv->set_lg_dir(pathLogDir.string().c_str()); @@ -293,7 +293,7 @@ void CDB::Flush() if (fReadOnly) nMinutes = 1; - bitdb.dbenv->txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100) * 1024 : 0, nMinutes, 0); + bitdb.dbenv->txn_checkpoint(nMinutes ? GetArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0); } void CDB::Close() diff --git a/src/wallet/db.h b/src/wallet/db.h index 64071caa3a..01b8c71a04 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -20,6 +20,9 @@ #include <db_cxx.h> +static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100; +static const bool DEFAULT_WALLET_PRIVDB = true; + extern unsigned int nWalletDBUpdated; class CDBEnv diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index c431fc4013..b025c37459 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 30b854477b..e68d646096 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -65,6 +65,8 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); entry.push_back(Pair("blockindex", wtx.nIndex)); entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime())); + } else { + entry.push_back(Pair("trusted", wtx.IsTrusted())); } uint256 hash = wtx.GetHash(); entry.push_back(Pair("txid", hash.GetHex())); @@ -386,11 +388,11 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp) if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n" - "\nSend 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.\n" + HelpRequiringPassphrase() + "\nArguments:\n" "1. \"bitcoinaddress\" (string, required) The bitcoin address to send to.\n" - "2. \"amount\" (numeric, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" + "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" " This is not part of the transaction, just kept in your wallet.\n" "4. \"comment-to\" (string, optional) A comment to store the name of the person or organization \n" @@ -835,7 +837,7 @@ UniValue movecmd(const UniValue& params, bool fHelp) debit.nTime = nNow; debit.strOtherAccount = strTo; debit.strComment = strComment; - walletdb.WriteAccountingEntry(debit); + pwalletMain->AddAccountingEntry(debit, walletdb); // Credit CAccountingEntry credit; @@ -845,7 +847,7 @@ UniValue movecmd(const UniValue& params, bool fHelp) credit.nTime = nNow; credit.strOtherAccount = strFrom; credit.strComment = strComment; - walletdb.WriteAccountingEntry(credit); + pwalletMain->AddAccountingEntry(credit, walletdb); if (!walletdb.TxnCommit()) throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); @@ -862,13 +864,12 @@ UniValue sendfrom(const UniValue& params, bool fHelp) if (fHelp || params.size() < 3 || params.size() > 6) throw runtime_error( "sendfrom \"fromaccount\" \"tobitcoinaddress\" amount ( minconf \"comment\" \"comment-to\" )\n" - "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address.\n" - "The amount is a real and is rounded to the nearest 0.00000001." + "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address." + HelpRequiringPassphrase() + "\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n" "2. \"tobitcoinaddress\" (string, required) The bitcoin address to send funds to.\n" - "3. amount (numeric, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n" + "3. amount (numeric or string, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n" "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" " This is not part of the transaction, just kept in your wallet.\n" @@ -933,7 +934,7 @@ UniValue sendmany(const UniValue& params, bool fHelp) "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n" "2. \"amounts\" (string, required) A json object with addresses and amounts\n" " {\n" - " \"address\":amount (numeric) The bitcoin address is the key, the numeric amount in " + CURRENCY_UNIT + " is the value\n" + " \"address\":amount (numeric or string) The bitcoin address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value\n" " ,...\n" " }\n" "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n" @@ -1182,6 +1183,8 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) obj.push_back(Pair("account", strAccount)); obj.push_back(Pair("amount", ValueFromAmount(nAmount))); obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf))); + if (!fByAccounts) + obj.push_back(Pair("label", strAccount)); UniValue transactions(UniValue::VARR); if (it != mapTally.end()) { @@ -1235,7 +1238,8 @@ UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) " \"address\" : \"receivingaddress\", (string) The receiving address\n" " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n" " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n" - " \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n" + " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n" + " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n" " }\n" " ,...\n" "]\n" @@ -1271,7 +1275,8 @@ UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) " \"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" + " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n" + " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n" " }\n" " ,...\n" "]\n" @@ -1318,6 +1323,8 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe MaybePushAddress(entry, s.destination); entry.push_back(Pair("category", "send")); entry.push_back(Pair("amount", ValueFromAmount(-s.amount))); + if (pwalletMain->mapAddressBook.count(s.destination)) + entry.push_back(Pair("label", pwalletMain->mapAddressBook[s.destination].name)); entry.push_back(Pair("vout", s.vout)); entry.push_back(Pair("fee", ValueFromAmount(-nFee))); if (fLong) @@ -1355,6 +1362,8 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe entry.push_back(Pair("category", "receive")); } entry.push_back(Pair("amount", ValueFromAmount(r.amount))); + if (pwalletMain->mapAddressBook.count(r.destination)) + entry.push_back(Pair("label", account)); entry.push_back(Pair("vout", r.vout)); if (fLong) WalletTxToJSON(wtx, entry); @@ -1409,20 +1418,24 @@ UniValue listtransactions(const UniValue& params, bool fHelp) " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n" " 'move' category for moves outbound. It is positive for the 'receive' category,\n" " and for the 'move' category for inbound funds.\n" - " \"vout\" : n, (numeric) the vout value\n" + " \"vout\": n, (numeric) the vout value\n" " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" " 'send' category of transactions.\n" " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n" - " 'receive' category of transactions.\n" + " 'receive' category of transactions. Negative confirmations indicate the\n" + " transation conflicts with the block chain\n" + " \"trusted\": xxx (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n" " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n" " category of transactions.\n" " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive'\n" " category of transactions.\n" + " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n" " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n" " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n" " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n" " for 'send' and 'receive' category of transactions.\n" " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n" + " \"label\": \"label\" (string) A comment for the address/transaction, if any\n" " \"otheraccount\": \"accountname\", (string) For the 'move' category of transactions, the account the funds came \n" " from (for receiving funds, positive amounts), or went to (for sending funds,\n" " negative amounts).\n" @@ -1461,11 +1474,10 @@ UniValue listtransactions(const UniValue& params, bool fHelp) UniValue ret(UniValue::VARR); - std::list<CAccountingEntry> acentries; - CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount); + const CWallet::TxItems & txOrdered = pwalletMain->wtxOrdered; // iterate backwards until we have nCount items to return: - for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) + for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { CWalletTx *const pwtx = (*it).second.first; if (pwtx != 0) @@ -1570,8 +1582,7 @@ UniValue listaccounts(const UniValue& params, bool fHelp) } } - list<CAccountingEntry> acentries; - CWalletDB(pwalletMain->strWalletFile).ListAccountCreditDebit("*", acentries); + const list<CAccountingEntry> & acentries = pwalletMain->laccentries; BOOST_FOREACH(const CAccountingEntry& entry, acentries) mapAccountBalances[entry.strAccount] += entry.nCreditDebit; @@ -1613,6 +1624,7 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n" " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n" " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n" + " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n" " \"to\": \"...\", (string) If a comment to is associated with the transaction.\n" " ],\n" " \"lastblock\": \"lastblockhash\" (string) The hash of the last block\n" @@ -1700,7 +1712,8 @@ UniValue gettransaction(const UniValue& params, bool fHelp) " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n" " \"address\" : \"bitcoinaddress\", (string) The bitcoin address involved in the transaction\n" " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n" - " \"amount\" : x.xxx (numeric) The amount in " + CURRENCY_UNIT + "\n" + " \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + "\n" + " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n" " \"vout\" : n, (numeric) the vout value\n" " }\n" " ,...\n" @@ -1750,6 +1763,40 @@ UniValue gettransaction(const UniValue& params, bool fHelp) return entry; } +UniValue abandontransaction(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() != 1) + throw runtime_error( + "abandontransaction \"txid\"\n" + "\nMark in-wallet transaction <txid> as abandoned\n" + "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n" + "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n" + "It only works on transactions which are not included in a block and are not currently in the mempool.\n" + "It has no effect on transactions which are already conflicted or abandoned.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id\n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + uint256 hash; + hash.SetHex(params[0].get_str()); + + if (!pwalletMain->mapWallet.count(hash)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); + if (!pwalletMain->AbandonTransaction(hash)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment"); + + return NullUniValue; +} + UniValue backupwallet(const UniValue& params, bool fHelp) { @@ -2164,9 +2211,9 @@ UniValue settxfee(const UniValue& params, bool fHelp) if (fHelp || params.size() < 1 || params.size() > 1) throw runtime_error( "settxfee amount\n" - "\nSet the transaction fee per kB.\n" + "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n" "\nArguments:\n" - "1. amount (numeric, required) The transaction fee in " + CURRENCY_UNIT + "/kB rounded to the nearest 0.00000001\n" + "1. amount (numeric or sting, required) The transaction fee in " + CURRENCY_UNIT + "/kB\n" "\nResult\n" "true|false (boolean) Returns true if successful\n" "\nExamples:\n" @@ -2385,7 +2432,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) "\nResult:\n" "{\n" " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n" - " \"fee\": n, (numeric) The fee added to the transaction\n" + " \"fee\": n, (numeric) Fee the resulting transaction pays\n" " \"changepos\": n (numeric) The position of the added change output, or -1\n" "}\n" "\"hex\" \n" @@ -2407,9 +2454,12 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) if (!DecodeHexTx(origTx, params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + if (origTx.vout.size() == 0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output"); + bool includeWatching = false; if (params.size() > 1) - includeWatching = true; + includeWatching = params[1].get_bool(); CMutableTransaction tx(origTx); CAmount nFee; diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index a5bc52b8dc..e84d588026 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -117,7 +117,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // try making 34 cents from 1,2,5,10,20 - we can't do it exactly BOOST_CHECK( wallet.SelectCoinsMinConf(34 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_GT(nValueRet, 34 * CENT); // but should get more than 34 cents + BOOST_CHECK_EQUAL(nValueRet, 35 * CENT); // but 35 cents is closest BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible) // when we try making 7 cents, the smaller coins (1,2,5) are enough. We should see just 2+5 @@ -185,33 +185,34 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); // we should get 2 BTC in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); - // empty the wallet and start again, now with fractions of a cent, to test sub-cent change avoidance + // empty the wallet and start again, now with fractions of a cent, to test small change avoidance + empty_wallet(); - add_coin(0.1*CENT); - add_coin(0.2*CENT); - add_coin(0.3*CENT); - add_coin(0.4*CENT); - add_coin(0.5*CENT); - - // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 = 1.5 cents - // we'll get sub-cent change whatever happens, so can expect 1.0 exactly - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); + add_coin(0.1*MIN_CHANGE); + add_coin(0.2*MIN_CHANGE); + add_coin(0.3*MIN_CHANGE); + add_coin(0.4*MIN_CHANGE); + add_coin(0.5*MIN_CHANGE); + + // try making 1 * MIN_CHANGE from the 1.5 * MIN_CHANGE + // we'll get change smaller than MIN_CHANGE whatever happens, so can expect MIN_CHANGE exactly + BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); - // but if we add a bigger coin, making it possible to avoid sub-cent change, things change: - add_coin(1111*CENT); + // but if we add a bigger coin, small change is avoided + add_coin(1111*MIN_CHANGE); - // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5 cents - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + // try making 1 from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5 + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount - // if we add more sub-cent coins: - add_coin(0.6*CENT); - add_coin(0.7*CENT); + // if we add more small coins: + add_coin(0.6*MIN_CHANGE); + add_coin(0.7*MIN_CHANGE); - // and try again to make 1.0 cents, we can still make 1.0 cents - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + // and try again to make 1.0 * MIN_CHANGE + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount // run the 'mtgox' test (see http://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf) // they tried to consolidate 10 50k coins into one 500k coin, and ended up with 50k in change @@ -223,45 +224,65 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); // we should get the exact amount BOOST_CHECK_EQUAL(setCoinsRet.size(), 10U); // in ten coins - // if there's not enough in the smaller coins to make at least 1 cent change (0.5+0.6+0.7 < 1.0+1.0), + // if there's not enough in the smaller coins to make at least 1 * MIN_CHANGE change (0.5+0.6+0.7 < 1.0+1.0), // we need to try finding an exact subset anyway // sometimes it will fail, and so we use the next biggest coin: empty_wallet(); - add_coin(0.5 * CENT); - add_coin(0.6 * CENT); - add_coin(0.7 * CENT); - add_coin(1111 * CENT); - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1111 * CENT); // we get the bigger coin + add_coin(0.5 * MIN_CHANGE); + add_coin(0.6 * MIN_CHANGE); + add_coin(0.7 * MIN_CHANGE); + add_coin(1111 * MIN_CHANGE); + BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1111 * MIN_CHANGE); // we get the bigger coin BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = 1.0) empty_wallet(); - add_coin(0.4 * CENT); - add_coin(0.6 * CENT); - add_coin(0.8 * CENT); - add_coin(1111 * CENT); - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + add_coin(0.4 * MIN_CHANGE); + add_coin(0.6 * MIN_CHANGE); + add_coin(0.8 * MIN_CHANGE); + add_coin(1111 * MIN_CHANGE); + BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); // we should get the exact amount BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // in two coins 0.4+0.6 - // test avoiding sub-cent change + // test avoiding small change empty_wallet(); - add_coin(0.0005 * COIN); - add_coin(0.01 * COIN); - add_coin(1 * COIN); + add_coin(0.05 * MIN_CHANGE); + add_coin(1 * MIN_CHANGE); + add_coin(100 * MIN_CHANGE); - // trying to make 1.0001 from these three coins - BOOST_CHECK( wallet.SelectCoinsMinConf(1.0001 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1.0105 * COIN); // we should get all coins + // trying to make 100.01 from these three coins + BOOST_CHECK( wallet.SelectCoinsMinConf(100.01 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 101.05 * MIN_CHANGE); // we should get all coins BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); - // but if we try to make 0.999, we should take the bigger of the two small coins to avoid sub-cent change - BOOST_CHECK( wallet.SelectCoinsMinConf(0.999 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1.01 * COIN); // we should get 1 + 0.01 + // but if we try to make 99.9, we should take the bigger of the two small coins to avoid small change + BOOST_CHECK( wallet.SelectCoinsMinConf(99.9 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); + // test with many inputs + for (CAmount amt=1500; amt < COIN; amt*=10) { + empty_wallet(); + // Create 676 inputs (= MAX_STANDARD_TX_SIZE / 148 bytes per input) + for (uint16_t j = 0; j < 676; j++) + add_coin(amt); + BOOST_CHECK(wallet.SelectCoinsMinConf(2000, 1, 1, vCoins, setCoinsRet, nValueRet)); + if (amt - 2000 < MIN_CHANGE) { + // needs more than one input: + uint16_t returnSize = std::ceil((2000.0 + MIN_CHANGE)/amt); + CAmount returnValue = amt * returnSize; + BOOST_CHECK_EQUAL(nValueRet, returnValue); + BOOST_CHECK_EQUAL(setCoinsRet.size(), returnSize); + } else { + // one input is sufficient: + BOOST_CHECK_EQUAL(nValueRet, amt); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); + } + } + // test randomness { empty_wallet(); @@ -307,4 +328,37 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) empty_wallet(); } +BOOST_AUTO_TEST_CASE(ApproximateBestSubset) +{ + CoinSet setCoinsRet; + CAmount nValueRet; + + LOCK(wallet.cs_wallet); + + empty_wallet(); + + // Test vValue sort order + for (int i = 0; i < 1000; i++) + add_coin(1000 * COIN); + add_coin(3 * COIN); + + BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); + + empty_wallet(); + + // Test trimming + for (int i = 0; i < 100; i++) + add_coin(10 * COIN); + for (int i = 0; i < 100; i++) + add_coin(1000 * COIN); + + BOOST_CHECK(wallet.SelectCoinsMinConf(100001 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); + // We need all 100 larger coins and exactly one small coin. + // Superfluous small coins must be trimmed from the set: + BOOST_CHECK_EQUAL(nValueRet, 100010 * COIN); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 101); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index bd3004061b..cbc71aa16b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -39,15 +39,22 @@ using namespace std; CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET; -bool bSpendZeroConfChange = true; -bool fSendFreeTransactions = false; -bool fPayAtLeastCustomFee = true; +bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; +bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS; /** * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) * Override with -mintxfee */ -CFeeRate CWallet::minTxFee = CFeeRate(1000); +CFeeRate CWallet::minTxFee = CFeeRate(DEFAULT_TRANSACTION_MINFEE); +/** + * If fee estimation does not have enough data to provide estimates, use this fee instead. + * Has no effect if not using fee estimation + * Override with -fallbackfee + */ +CFeeRate CWallet::fallbackFee = CFeeRate(DEFAULT_FALLBACK_FEE); + +const uint256 CMerkleTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); /** @defgroup mapWallet * @@ -456,8 +463,11 @@ bool CWallet::IsSpent(const uint256& hash, unsigned int n) const { const uint256& wtxid = it->second; std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid); - if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) - return true; // Spent + if (mit != mapWallet.end()) { + int depth = mit->second.GetDepthInMainChain(); + if (depth > 0 || (depth == 0 && !mit->second.isAbandoned())) + return true; // Spent + } } return false; } @@ -588,31 +598,6 @@ int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb) return nRet; } -CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount) -{ - AssertLockHeld(cs_wallet); // mapWallet - CWalletDB walletdb(strWalletFile); - - // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap. - TxItems txOrdered; - - // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry - // would make this much faster for applications that do this a lot. - for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) - { - CWalletTx* wtx = &((*it).second); - txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); - } - acentries.clear(); - walletdb.ListAccountCreditDebit(strAccount, acentries); - BOOST_FOREACH(CAccountingEntry& entry, acentries) - { - txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry))); - } - - return txOrdered; -} - void CWallet::MarkDirty() { { @@ -629,8 +614,18 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD if (fFromLoadWallet) { mapWallet[hash] = wtxIn; - mapWallet[hash].BindWallet(this); + CWalletTx& wtx = mapWallet[hash]; + wtx.BindWallet(this); + wtxOrdered.insert(make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0))); AddToSpends(hash); + BOOST_FOREACH(const CTxIn& txin, wtx.vin) { + if (mapWallet.count(txin.prevout.hash)) { + CWalletTx& prevtx = mapWallet[txin.prevout.hash]; + if (prevtx.nIndex == -1 && !prevtx.hashUnset()) { + MarkConflicted(prevtx.hashBlock, wtx.GetHash()); + } + } + } } else { @@ -644,9 +639,10 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD { wtx.nTimeReceived = GetAdjustedTime(); wtx.nOrderPos = IncOrderPosNext(pwalletdb); + wtxOrdered.insert(make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0))); wtx.nTimeSmart = wtx.nTimeReceived; - if (!wtxIn.hashBlock.IsNull()) + if (!wtxIn.hashUnset()) { if (mapBlockIndex.count(wtxIn.hashBlock)) { @@ -655,9 +651,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD { // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future int64_t latestTolerated = latestNow + 300; - std::list<CAccountingEntry> acentries; - TxItems txOrdered = OrderedTxItems(acentries); - for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) + const TxItems & txOrdered = wtxOrdered; + for (TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { CWalletTx *const pwtx = (*it).second.first; if (pwtx == &wtx) @@ -697,7 +692,13 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD if (!fInsertedNew) { // Merge - if (!wtxIn.hashBlock.IsNull() && wtxIn.hashBlock != wtx.hashBlock) + if (!wtxIn.hashUnset() && wtxIn.hashBlock != wtx.hashBlock) + { + wtx.hashBlock = wtxIn.hashBlock; + fUpdated = true; + } + // If no longer abandoned, update + if (wtxIn.hashBlock.IsNull() && wtx.isAbandoned()) { wtx.hashBlock = wtxIn.hashBlock; fUpdated = true; @@ -750,6 +751,20 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl { { AssertLockHeld(cs_wallet); + + if (pblock) { + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(txin.prevout); + while (range.first != range.second) { + if (range.first->second != tx.GetHash()) { + LogPrintf("Transaction %s (in block %s) conflicts with wallet transaction %s (both spend %s:%i)\n", tx.GetHash().ToString(), pblock->GetHash().ToString(), range.first->second.ToString(), range.first->first.hash.ToString(), range.first->first.n); + MarkConflicted(pblock->GetHash(), range.first->second); + } + range.first++; + } + } + } + bool fExisted = mapWallet.count(tx.GetHash()) != 0; if (fExisted && !fUpdate) return false; if (fExisted || IsMine(tx) || IsFromMe(tx)) @@ -770,9 +785,122 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl return false; } +bool CWallet::AbandonTransaction(const uint256& hashTx) +{ + LOCK2(cs_main, cs_wallet); + + // Do not flush the wallet here for performance reasons + CWalletDB walletdb(strWalletFile, "r+", false); + + std::set<uint256> todo; + std::set<uint256> done; + + // Can't mark abandoned if confirmed or in mempool + assert(mapWallet.count(hashTx)); + CWalletTx& origtx = mapWallet[hashTx]; + if (origtx.GetDepthInMainChain() > 0 || origtx.InMempool()) { + return false; + } + + todo.insert(hashTx); + + while (!todo.empty()) { + uint256 now = *todo.begin(); + todo.erase(now); + done.insert(now); + assert(mapWallet.count(now)); + CWalletTx& wtx = mapWallet[now]; + int currentconfirm = wtx.GetDepthInMainChain(); + // If the orig tx was not in block, none of its spends can be + assert(currentconfirm <= 0); + // if (currentconfirm < 0) {Tx and spends are already conflicted, no need to abandon} + if (currentconfirm == 0 && !wtx.isAbandoned()) { + // If the orig tx was not in block/mempool, none of its spends can be in mempool + assert(!wtx.InMempool()); + wtx.nIndex = -1; + wtx.setAbandoned(); + wtx.MarkDirty(); + wtx.WriteToDisk(&walletdb); + NotifyTransactionChanged(this, wtx.GetHash(), CT_UPDATED); + // Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too + TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(hashTx, 0)); + while (iter != mapTxSpends.end() && iter->first.hash == now) { + if (!done.count(iter->second)) { + todo.insert(iter->second); + } + iter++; + } + // If a transaction changes 'conflicted' state, that changes the balance + // available of the outputs it spends. So force those to be recomputed + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + { + if (mapWallet.count(txin.prevout.hash)) + mapWallet[txin.prevout.hash].MarkDirty(); + } + } + } + + return true; +} + +void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) +{ + LOCK2(cs_main, cs_wallet); + + CBlockIndex* pindex; + assert(mapBlockIndex.count(hashBlock)); + pindex = mapBlockIndex[hashBlock]; + int conflictconfirms = 0; + if (chainActive.Contains(pindex)) { + conflictconfirms = -(chainActive.Height() - pindex->nHeight + 1); + } + assert(conflictconfirms < 0); + + // Do not flush the wallet here for performance reasons + CWalletDB walletdb(strWalletFile, "r+", false); + + std::set<uint256> todo; + std::set<uint256> done; + + todo.insert(hashTx); + + while (!todo.empty()) { + uint256 now = *todo.begin(); + todo.erase(now); + done.insert(now); + assert(mapWallet.count(now)); + CWalletTx& wtx = mapWallet[now]; + int currentconfirm = wtx.GetDepthInMainChain(); + if (conflictconfirms < currentconfirm) { + // Block is 'more conflicted' than current confirm; update. + // Mark transaction as conflicted with this block. + wtx.nIndex = -1; + wtx.hashBlock = hashBlock; + wtx.MarkDirty(); + wtx.WriteToDisk(&walletdb); + // Iterate over all its outputs, and mark transactions in the wallet that spend them conflicted too + TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0)); + while (iter != mapTxSpends.end() && iter->first.hash == now) { + if (!done.count(iter->second)) { + todo.insert(iter->second); + } + iter++; + } + // If a transaction changes 'conflicted' state, that changes the balance + // available of the outputs it spends. So force those to be recomputed + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + { + if (mapWallet.count(txin.prevout.hash)) + mapWallet[txin.prevout.hash].MarkDirty(); + } + } + } +} + void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock) { LOCK2(cs_main, cs_wallet); + if (!AddToWalletIfInvolvingMe(tx, pblock, true)) return; // Not one of ours @@ -923,7 +1051,7 @@ int CWalletTx::GetRequestCount() const if (IsCoinBase()) { // Generated block - if (!hashBlock.IsNull()) + if (!hashUnset()) { map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); if (mi != pwallet->mapRequestCount.end()) @@ -939,7 +1067,7 @@ int CWalletTx::GetRequestCount() const nRequests = (*mi).second; // How about the block it's in? - if (nRequests == 0 && !hashBlock.IsNull()) + if (nRequests == 0 && !hashUnset()) { map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); if (mi != pwallet->mapRequestCount.end()) @@ -988,7 +1116,8 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived, // In either case, we need to get the destination address CTxDestination address; - if (!ExtractDestination(txout.scriptPubKey, address)) + + if (!ExtractDestination(txout.scriptPubKey, address) && !txout.scriptPubKey.IsUnspendable()) { LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n", this->GetHash().ToString()); @@ -1078,7 +1207,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100)))); CBlock block; - ReadBlockFromDisk(block, pindex); + ReadBlockFromDisk(block, pindex, Params().GetConsensus()); BOOST_FOREACH(CTransaction& tx, block.vtx) { if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) @@ -1112,7 +1241,7 @@ void CWallet::ReacceptWalletTransactions() int nDepth = wtx.GetDepthInMainChain(); - if (!wtx.IsCoinBase() && nDepth < 0) { + if (!wtx.IsCoinBase() && (nDepth == 0 && !wtx.isAbandoned())) { mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx)); } } @@ -1132,7 +1261,7 @@ bool CWalletTx::RelayWalletTransaction() assert(pwallet->GetBroadcastTransactions()); if (!IsCoinBase()) { - if (GetDepthInMainChain() == 0) { + if (GetDepthInMainChain() == 0 && !isAbandoned()) { LogPrintf("Relaying wtx %s\n", GetHash().ToString()); RelayTransaction((CTransaction)*this); return true; @@ -1313,6 +1442,15 @@ CAmount CWalletTx::GetChange() const return nChangeCached; } +bool CWalletTx::InMempool() const +{ + LOCK(mempool.cs); + if (mempool.exists(GetHash())) { + return true; + } + return false; +} + bool CWalletTx::IsTrusted() const { // Quick answer in most cases @@ -1326,6 +1464,10 @@ bool CWalletTx::IsTrusted() const if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit return false; + // Don't trust unconfirmed transactions from us unless they are in the mempool. + if (!InMempool()) + return false; + // Trusted if all inputs are from us and are in the mempool: BOOST_FOREACH(const CTxIn& txin, vin) { @@ -1497,9 +1639,6 @@ CAmount CWallet::GetImmatureWatchOnlyBalance() const return nTotal; } -/** - * populate vCoins with vector of available COutputs. - */ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeZeroValue) const { vCoins.clear(); @@ -1581,6 +1720,16 @@ static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,uns } } } + + //Reduces the approximate best subset by removing any inputs that are smaller than the surplus of nTotal beyond nTargetValue. + for (unsigned int i = 0; i < vValue.size(); i++) + { + if (vfBest[i] && (nBest - vValue[i].first) >= nTargetValue ) + { + vfBest[i] = false; + nBest -= vValue[i].first; + } + } } bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins, @@ -1619,7 +1768,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nValueRet += coin.first; return true; } - else if (n < nTargetValue + CENT) + else if (n < nTargetValue + MIN_CHANGE) { vValue.push_back(coin); nTotalLower += n; @@ -1654,14 +1803,14 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int vector<char> vfBest; CAmount nBest; - ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000); - if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT) - ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000); + ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest); + if (nBest != nTargetValue && nTotalLower >= nTargetValue + MIN_CHANGE) + ApproximateBestSubset(vValue, nTotalLower, nTargetValue + MIN_CHANGE, vfBest, nBest); // If we have a bigger coin and (either the stochastic approximation didn't find a good solution, // or the next bigger coin is closer), return the bigger coin if (coinLowestLarger.second.first && - ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest)) + ((nBest != nTargetValue && nBest < nTargetValue + MIN_CHANGE) || coinLowestLarger.first <= nBest)) { setCoinsRet.insert(coinLowestLarger.second); nValueRet += coinLowestLarger.first; @@ -1820,15 +1969,25 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt // 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); + // For a large miner the value of the transactions in the best block and + // the mempool can exceed the cost of deliberately attempting to mine two + // blocks to orphan the current best block. By setting nLockTime such that + // only the next block can include the transaction, we discourage this + // practice as the height restricted and limited blocksize gives miners + // considering fee sniping fewer options for pulling off this attack. + // + // A simple way to think about this is from the wallet's point of view we + // always want the blockchain to move forward. By setting nLockTime this + // way we're basically making the statement that we only want this + // transaction to appear in the next block; we don't want to potentially + // encourage reorgs by allowing transactions to appear at lower heights + // than the next block in forks of the best chain. + // + // Of course, the subsidy is high enough, and transaction volume low + // enough, that fee sniping isn't a problem yet, but by implementing a fix + // now we ensure code won't be written that makes assumptions about + // nLockTime that preclude a fix later. + txNew.nLockTime = chainActive.Height(); // Secondly occasionally randomly pick a nLockTime even further back, so // that transactions that are delayed after signing for whatever reason, @@ -1844,6 +2003,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt LOCK2(cs_main, cs_wallet); { nFeeRet = 0; + // Start with no fee and loop until there is enough fee while (true) { txNew.vin.clear(); @@ -1904,6 +2064,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt //a chance at a free transaction. //But mempool inputs might still be in the mempool, so their age stays 0 int age = pcoin.first->GetDepthInMainChain(); + assert(age >= 0); if (age != 0) age += 1; dPriority += (double)nCredit * age; @@ -2035,17 +2196,16 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt 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) + double dPriorityNeeded = mempool.estimateSmartPriority(nTxConfirmTarget); + // Require at least hard-coded AllowFree. + if (dPriority >= dPriorityNeeded && AllowFree(dPriority)) break; } CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool); + if (coinControl && nFeeNeeded > 0 && coinControl->nMinimumTotalFee > nFeeNeeded) { + nFeeNeeded = coinControl->nMinimumTotalFee; + } // 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. @@ -2120,23 +2280,37 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) return true; } +bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry, CWalletDB & pwalletdb) +{ + if (!pwalletdb.WriteAccountingEntry_Backend(acentry)) + return false; + + laccentries.push_back(acentry); + CAccountingEntry & entry = laccentries.back(); + wtxOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry))); + + return true; +} + +CAmount CWallet::GetRequiredFee(unsigned int nTxBytes) +{ + return std::max(minTxFee.GetFee(nTxBytes), ::minRelayTxFee.GetFee(nTxBytes)); +} + CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool) { // payTxFee is user-set "I want to pay this much" 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); - // ... unless we don't have enough mempool data, in which case fall - // 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); + if (nFeeNeeded == 0) { + int estimateFoundTarget = nConfirmTarget; + nFeeNeeded = pool.estimateSmartFee(nConfirmTarget, &estimateFoundTarget).GetFee(nTxBytes); + // ... unless we don't have enough mempool data for estimatefee, then use fallbackFee + if (nFeeNeeded == 0) + nFeeNeeded = fallbackFee.GetFee(nTxBytes); + } + // prevent user from paying a fee below minRelayTxFee or minTxFee + nFeeNeeded = std::max(nFeeNeeded, GetRequiredFee(nTxBytes)); // But always obey the maximum if (nFeeNeeded > maxTxFee) nFeeNeeded = maxTxFee; @@ -2270,7 +2444,7 @@ bool CWallet::NewKeyPool() if (IsLocked()) return false; - int64_t nKeys = max(GetArg("-keypool", 100), (int64_t)0); + int64_t nKeys = max(GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t)0); for (int i = 0; i < nKeys; i++) { int64_t nIndex = i+1; @@ -2297,7 +2471,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) if (kpSize > 0) nTargetSize = kpSize; else - nTargetSize = max(GetArg("-keypool", 100), (int64_t) 0); + nTargetSize = max(GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 0); while (setKeyPool.size() < (nTargetSize + 1)) { @@ -2824,10 +2998,11 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block) return chainActive.Height() - pindex->nHeight + 1; } -int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const +int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const { - if (hashBlock.IsNull() || nIndex == -1) + if (hashUnset()) return 0; + AssertLockHeld(cs_main); // Find the block it claims to be in @@ -2839,17 +3014,7 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const return 0; pindexRet = pindex; - return chainActive.Height() - pindex->nHeight + 1; -} - -int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const -{ - AssertLockHeld(cs_main); - int nResult = GetDepthInMainChainINTERNAL(pindexRet); - if (nResult == 0 && !mempool.exists(GetHash())) - return -1; // Not in chain, not in mempool - - return nResult; + return ((nIndex == -1) ? (-1) : 1) * (chainActive.Height() - pindex->nHeight + 1); } int CMerkleTx::GetBlocksToMaturity() const @@ -2863,6 +3028,5 @@ int CMerkleTx::GetBlocksToMaturity() const bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) { CValidationState state; - return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee); + return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, false, fRejectAbsurdFee); } - diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 34e98cfb81..2176a5ff66 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -35,22 +35,32 @@ extern CAmount maxTxFee; extern unsigned int nTxConfirmTarget; extern bool bSpendZeroConfChange; extern bool fSendFreeTransactions; -extern bool fPayAtLeastCustomFee; +static const unsigned int DEFAULT_KEYPOOL_SIZE = 100; //! -paytxfee default static const CAmount DEFAULT_TRANSACTION_FEE = 0; //! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB static const CAmount nHighTransactionFeeWarning = 0.01 * COIN; +//! -fallbackfee default +static const CAmount DEFAULT_FALLBACK_FEE = 20000; +//! -mintxfee default +static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000; //! -maxtxfee default static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; +//! minimum change amount +static const CAmount MIN_CHANGE = CENT; +//! Default for -spendzeroconfchange +static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true; +//! Default for -sendfreetransactions +static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false; //! -txconfirmtarget default static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; //! -maxtxfee will warn if called with a higher fee than this amount (in satoshis) static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWarning; //! Largest (in bytes) free transaction we're willing to create static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; +static const bool DEFAULT_WALLETBROADCAST = true; -class CAccountingEntry; class CBlockIndex; class CCoinControl; class COutput; @@ -147,10 +157,17 @@ struct COutputEntry class CMerkleTx : public CTransaction { private: - int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const; + /** Constant used in hashBlock to indicate tx has been abandoned */ + static const uint256 ABANDON_HASH; public: uint256 hashBlock; + + /* An nIndex == -1 means that hashBlock (in nonzero) refers to the earliest + * block in the chain we know this or any in-wallet dependency conflicts + * with. Older clients interpret nIndex == -1 as unconfirmed for backward + * compatibility. + */ int nIndex; CMerkleTx() @@ -183,18 +200,20 @@ public: int SetMerkleBranch(const CBlock& block); - /** * Return depth of transaction in blockchain: - * -1 : not in blockchain, and not in memory pool (conflicted transaction) + * <0 : conflicts with a transaction this deep in the blockchain * 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; } + bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; } int GetBlocksToMaturity() const; bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true); + bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); } + bool isAbandoned() const { return (hashBlock == ABANDON_HASH); } + void setAbandoned() { hashBlock = ABANDON_HASH; } }; /** @@ -373,6 +392,7 @@ public: // True if only scriptSigs are different bool IsEquivalentTo(const CWalletTx& tx) const; + bool InMempool() const; bool IsTrusted() const; bool WriteToDisk(CWalletDB *pwalletdb); @@ -433,6 +453,86 @@ public: } }; +/** + * Internal transfers. + * Database key is acentry<account><counter>. + */ +class CAccountingEntry +{ +public: + std::string strAccount; + CAmount nCreditDebit; + int64_t nTime; + std::string strOtherAccount; + std::string strComment; + mapValue_t mapValue; + int64_t nOrderPos; //! position in ordered transaction list + uint64_t nEntryNo; + + CAccountingEntry() + { + SetNull(); + } + + void SetNull() + { + nCreditDebit = 0; + nTime = 0; + strAccount.clear(); + strOtherAccount.clear(); + strComment.clear(); + nOrderPos = -1; + nEntryNo = 0; + } + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + //! Note: strAccount is serialized as part of the key, not here. + READWRITE(nCreditDebit); + READWRITE(nTime); + READWRITE(LIMITED_STRING(strOtherAccount, 65536)); + + if (!ser_action.ForRead()) + { + WriteOrderPos(nOrderPos, mapValue); + + if (!(mapValue.empty() && _ssExtra.empty())) + { + CDataStream ss(nType, nVersion); + ss.insert(ss.begin(), '\0'); + ss << mapValue; + ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end()); + strComment.append(ss.str()); + } + } + + READWRITE(LIMITED_STRING(strComment, 65536)); + + size_t nSepPos = strComment.find("\0", 0, 1); + if (ser_action.ForRead()) + { + mapValue.clear(); + if (std::string::npos != nSepPos) + { + CDataStream ss(std::vector<char>(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion); + ss >> mapValue; + _ssExtra = std::vector<char>(ss.begin(), ss.end()); + } + ReadOrderPos(nOrderPos, mapValue); + } + if (std::string::npos != nSepPos) + strComment.erase(nSepPos); + + mapValue.erase("n"); + } + +private: + std::vector<char> _ssExtra; +}; /** @@ -442,6 +542,11 @@ public: class CWallet : public CCryptoKeyStore, public CValidationInterface { private: + /** + * Select a set of coins such that nValueRet >= nTargetValue and at least + * all coins from coinControl are selected; Never select unconfirmed coins + * if they are not ours + */ bool SelectCoins(const CAmount& nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const; CWalletDB *pwalletdbEncryption; @@ -466,6 +571,9 @@ private: void AddToSpends(const COutPoint& outpoint, const uint256& wtxid); void AddToSpends(const uint256& wtxid); + /* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */ + void MarkConflicted(const uint256& hashBlock, const uint256& hashTx); + void SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator>); public: @@ -522,6 +630,11 @@ public: } std::map<uint256, CWalletTx> mapWallet; + std::list<CAccountingEntry> laccentries; + + typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair; + typedef std::multimap<int64_t, TxPair > TxItems; + TxItems wtxOrdered; int64_t nOrderPosNext; std::map<uint256, int> mapRequestCount; @@ -539,7 +652,17 @@ public: //! 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; } + /** + * populate vCoins with vector of available COutputs. + */ void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL, bool fIncludeZeroValue=false) const; + + /** + * Shuffle and select coins until nTargetValue is reached while avoiding + * small change; This method is stochastic for some inputs and upon + * completion the coin set and corresponding actual target value is + * assembled + */ 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; @@ -598,16 +721,6 @@ public: */ 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 - */ - TxItems OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount = ""); - void MarkDirty(); bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb); void SyncTransaction(const CTransaction& tx, const CBlock* pblock); @@ -622,13 +735,35 @@ public: CAmount GetWatchOnlyBalance() const; CAmount GetUnconfirmedWatchOnlyBalance() const; CAmount GetImmatureWatchOnlyBalance() const; + + /** + * Insert additional inputs into the transaction by + * calling CreateTransaction(); + */ bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching); + + /** + * Create a new transaction paying the recipients with a set of coins + * selected by SelectCoins(); Also create the change output, when needed + */ bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); + bool AddAccountingEntry(const CAccountingEntry&, CWalletDB & pwalletdb); + static CFeeRate minTxFee; + static CFeeRate fallbackFee; + /** + * Estimate the minimum fee considering user set parameters + * and the required fee + */ static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool); + /** + * Return the minimum required fee taking into account the + * floating relay fee and user set minimum transaction fee + */ + static CAmount GetRequiredFee(unsigned int nTxBytes); bool NewKeyPool(); bool TopUpKeyPool(unsigned int kpSize = 0); @@ -736,6 +871,9 @@ public: bool GetBroadcastTransactions() const { return fBroadcastTransactions; } /** Set whether this wallet broadcasts transactions. */ void SetBroadcastTransactions(bool broadcast) { fBroadcastTransactions = broadcast; } + + /* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */ + bool AbandonTransaction(const uint256& hashTx); }; /** A key allocated from the key pool. */ @@ -793,87 +931,4 @@ public: } }; - - -/** - * Internal transfers. - * Database key is acentry<account><counter>. - */ -class CAccountingEntry -{ -public: - std::string strAccount; - CAmount nCreditDebit; - int64_t nTime; - std::string strOtherAccount; - std::string strComment; - mapValue_t mapValue; - int64_t nOrderPos; //! position in ordered transaction list - uint64_t nEntryNo; - - CAccountingEntry() - { - SetNull(); - } - - void SetNull() - { - nCreditDebit = 0; - nTime = 0; - strAccount.clear(); - strOtherAccount.clear(); - strComment.clear(); - nOrderPos = -1; - nEntryNo = 0; - } - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - if (!(nType & SER_GETHASH)) - READWRITE(nVersion); - //! Note: strAccount is serialized as part of the key, not here. - READWRITE(nCreditDebit); - READWRITE(nTime); - READWRITE(LIMITED_STRING(strOtherAccount, 65536)); - - if (!ser_action.ForRead()) - { - WriteOrderPos(nOrderPos, mapValue); - - if (!(mapValue.empty() && _ssExtra.empty())) - { - CDataStream ss(nType, nVersion); - ss.insert(ss.begin(), '\0'); - ss << mapValue; - ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end()); - strComment.append(ss.str()); - } - } - - READWRITE(LIMITED_STRING(strComment, 65536)); - - size_t nSepPos = strComment.find("\0", 0, 1); - if (ser_action.ForRead()) - { - mapValue.clear(); - if (std::string::npos != nSepPos) - { - CDataStream ss(std::vector<char>(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion); - ss >> mapValue; - _ssExtra = std::vector<char>(ss.begin(), ss.end()); - } - ReadOrderPos(nOrderPos, mapValue); - } - if (std::string::npos != nSepPos) - strComment.erase(nSepPos); - - mapValue.erase("n"); - } - -private: - std::vector<char> _ssExtra; -}; - #endif // BITCOIN_WALLET_WALLET_H diff --git a/src/wallet/wallet_ismine.cpp b/src/wallet/wallet_ismine.cpp index d27b1531e3..ebda5cc53d 100644 --- a/src/wallet/wallet_ismine.cpp +++ b/src/wallet/wallet_ismine.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/wallet_ismine.h b/src/wallet/wallet_ismine.h index 9f45f76c6b..93cdf6ab8f 100644 --- a/src/wallet/wallet_ismine.h +++ b/src/wallet/wallet_ismine.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 0624e442d1..5266946ca0 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,6 +15,12 @@ #include "utiltime.h" #include "wallet/wallet.h" +#if defined(FORCE_BOOST_EMULATED_SCOPED_ENUMS) +#define BOOST_NO_SCOPED_ENUMS +#define BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +#include <boost/version.hpp> #include <boost/filesystem.hpp> #include <boost/foreach.hpp> #include <boost/scoped_ptr.hpp> @@ -113,19 +119,19 @@ bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript) { nWalletDBUpdated++; - return Write(std::make_pair(std::string("cscript"), hash), redeemScript, false); + return Write(std::make_pair(std::string("cscript"), hash), *(const CScriptBase*)(&redeemScript), false); } bool CWalletDB::WriteWatchOnly(const CScript &dest) { nWalletDBUpdated++; - return Write(std::make_pair(std::string("watchs"), dest), '1'); + return Write(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest)), '1'); } bool CWalletDB::EraseWatchOnly(const CScript &dest) { nWalletDBUpdated++; - return Erase(std::make_pair(std::string("watchs"), dest)); + return Erase(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest))); } bool CWalletDB::WriteBestBlock(const CBlockLocator& locator) @@ -191,7 +197,7 @@ bool CWalletDB::WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccount return Write(std::make_pair(std::string("acentry"), std::make_pair(acentry.strAccount, nAccEntryNum)), acentry); } -bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry) +bool CWalletDB::WriteAccountingEntry_Backend(const CAccountingEntry& acentry) { return WriteAccountingEntry(++nAccountingEntryNumber, acentry); } @@ -421,7 +427,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, else if (strType == "watchs") { CScript script; - ssKey >> script; + ssKey >> *(CScriptBase*)(&script); char fYes; ssValue >> fYes; if (fYes == '1') @@ -512,8 +518,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "ckey") { - vector<unsigned char> vchPubKey; + CPubKey vchPubKey; ssKey >> vchPubKey; + if (!vchPubKey.IsValid()) + { + strErr = "Error reading wallet database: CPubKey corrupt"; + return false; + } vector<unsigned char> vchPrivKey; ssValue >> vchPrivKey; wss.nCKeys++; @@ -570,7 +581,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, uint160 hash; ssKey >> hash; CScript script; - ssValue >> script; + ssValue >> *(CScriptBase*)(&script); if (!pwallet->LoadCScript(script)) { strErr = "Error reading wallet database: LoadCScript failed"; @@ -704,6 +715,12 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) if (wss.fAnyUnordered) result = ReorderTransactions(pwallet); + pwallet->laccentries.clear(); + ListAccountCreditDebit("*", pwallet->laccentries); + BOOST_FOREACH(CAccountingEntry& entry, pwallet->laccentries) { + pwallet->wtxOrdered.insert(make_pair(entry.nOrderPos, CWallet::TxPair((CWalletTx*)0, &entry))); + } + return result; } @@ -799,7 +816,7 @@ void ThreadFlushWalletDB(const string& strFile) if (fOneThread) return; fOneThread = true; - if (!GetBoolArg("-flushwallet", true)) + if (!GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) return; unsigned int nLastSeen = nWalletDBUpdated; @@ -949,8 +966,13 @@ bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKe CDataStream ssKey(row.first, SER_DISK, CLIENT_VERSION); CDataStream ssValue(row.second, SER_DISK, CLIENT_VERSION); string strType, strErr; - bool fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue, + bool fReadOK; + { + // Required in LoadKeyMetadata(): + LOCK(dummyWallet.cs_wallet); + fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue, wss, strType, strErr); + } if (!IsKeyType(strType)) continue; if (!fReadOK) diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 270f826aed..8da33dead2 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -16,6 +16,8 @@ #include <utility> #include <vector> +static const bool DEFAULT_FLUSHWALLET = true; + class CAccount; class CAccountingEntry; struct CBlockLocator; @@ -110,6 +112,9 @@ public: bool WriteMinVersion(int nVersion); + /// This writes directly to the database, and will not update the CWallet's cached accounting entries! + /// Use wallet.AddAccountingEntry instead, to write *and* update its caches. + bool WriteAccountingEntry_Backend(const CAccountingEntry& acentry); bool ReadAccount(const std::string& strAccount, CAccount& account); bool WriteAccount(const std::string& strAccount, const CAccount& account); @@ -118,7 +123,6 @@ public: /// Erase destination data tuple from wallet database bool EraseDestData(const std::string &address, const std::string &key); - bool WriteAccountingEntry(const CAccountingEntry& acentry); CAmount GetAccountCreditDebit(const std::string& strAccount); void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries); diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 388b86707b..be2aec7d15 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -12,7 +12,7 @@ void zmqError(const char *str) { - LogPrint("zmq", "Error: %s, errno=%s\n", str, zmq_strerror(errno)); + LogPrint("zmq", "zmq: Error: %s, errno=%s\n", str, zmq_strerror(errno)); } CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL) @@ -21,8 +21,7 @@ CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL) CZMQNotificationInterface::~CZMQNotificationInterface() { - // ensure Shutdown if Initialize is called - assert(!pcontext); + Shutdown(); for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i) { @@ -59,6 +58,12 @@ CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const { notificationInterface = new CZMQNotificationInterface(); notificationInterface->notifiers = notifiers; + + if (!notificationInterface->Initialize()) + { + delete notificationInterface; + notificationInterface = NULL; + } } return notificationInterface; @@ -67,7 +72,7 @@ CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const // Called at startup to conditionally set up ZMQ socket(s) bool CZMQNotificationInterface::Initialize() { - LogPrint("zmq", "Initialize notification interface\n"); + LogPrint("zmq", "zmq: Initialize notification interface\n"); assert(!pcontext); pcontext = zmq_init(1); @@ -99,13 +104,13 @@ bool CZMQNotificationInterface::Initialize() return false; } - return false; + return true; } // Called during shutdown sequence void CZMQNotificationInterface::Shutdown() { - LogPrint("zmq", "Shutdown notification interface\n"); + LogPrint("zmq", "zmq: Shutdown notification interface\n"); if (pcontext) { for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i) diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index 8eea15c068..3ccfaf341d 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -19,10 +19,11 @@ public: static CZMQNotificationInterface* CreateWithArguments(const std::map<std::string, std::string> &args); +protected: bool Initialize(); void Shutdown(); -protected: // CValidationInterface + // CValidationInterface void SyncTransaction(const CTransaction &tx, const CBlock *pblock); void UpdatedBlockTip(const CBlockIndex *pindex); diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 4c3eb8f2d9..ddc8fe93e9 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "chainparams.h" #include "zmqpublishnotifier.h" #include "main.h" #include "util.h" @@ -77,7 +78,7 @@ bool CZMQAbstractPublishNotifier::Initialize(void *pcontext) } else { - LogPrint("zmq", " Reuse socket for address %s\n", address); + LogPrint("zmq", "zmq: Reusing socket for address %s\n", address); psocket = i->second->psocket; mapPublishNotifiers.insert(std::make_pair(address, this)); @@ -119,7 +120,7 @@ void CZMQAbstractPublishNotifier::Shutdown() bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { uint256 hash = pindex->GetBlockHash(); - LogPrint("zmq", "Publish hash block %s\n", hash.GetHex()); + LogPrint("zmq", "zmq: Publish hashblock %s\n", hash.GetHex()); char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; @@ -130,7 +131,7 @@ bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction) { uint256 hash = transaction.GetHash(); - LogPrint("zmq", "Publish hash transaction %s\n", hash.GetHex()); + LogPrint("zmq", "zmq: Publish hashtx %s\n", hash.GetHex()); char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; @@ -140,13 +141,14 @@ bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &t bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { - LogPrint("zmq", "Publish raw block %s\n", pindex->GetBlockHash().GetHex()); + LogPrint("zmq", "zmq: Publish rawblock %s\n", pindex->GetBlockHash().GetHex()); + const Consensus::Params& consensusParams = Params().GetConsensus(); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); { LOCK(cs_main); CBlock block; - if(!ReadBlockFromDisk(block, pindex)) + if(!ReadBlockFromDisk(block, pindex, consensusParams)) { zmqError("Can't read block from disk"); return false; @@ -162,7 +164,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction) { uint256 hash = transaction.GetHash(); - LogPrint("zmq", "Publish raw transaction %s\n", hash.GetHex()); + LogPrint("zmq", "zmq: Publish rawtx %s\n", hash.GetHex()); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << transaction; int rc = zmq_send_multipart(psocket, "rawtx", 5, &(*ss.begin()), ss.size(), 0); |