aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am91
-rw-r--r--src/Makefile.bench.include45
-rw-r--r--src/Makefile.qt.include17
-rw-r--r--src/Makefile.qttest.include8
-rw-r--r--src/Makefile.test.include15
-rw-r--r--src/addrman.cpp20
-rw-r--r--src/addrman.h18
-rw-r--r--src/alert.cpp1
-rw-r--r--src/amount.cpp4
-rw-r--r--src/amount.h3
-rw-r--r--src/base58.h9
-rw-r--r--src/bench/.gitignore1
-rw-r--r--src/bench/Examples.cpp34
-rw-r--r--src/bench/bench.cpp68
-rw-r--r--src/bench/bench.h71
-rw-r--r--src/bench/bench_bitcoin.cpp21
-rw-r--r--src/bitcoin-cli.cpp154
-rw-r--r--src/bitcoin-tx.cpp56
-rw-r--r--src/bitcoind.cpp19
-rw-r--r--src/bloom.cpp34
-rw-r--r--src/bloom.h16
-rw-r--r--src/chainparams.cpp68
-rw-r--r--src/chainparams.h30
-rw-r--r--src/chainparamsbase.cpp47
-rw-r--r--src/chainparamsbase.h31
-rw-r--r--src/checkpoints.cpp1
-rw-r--r--src/checkpoints.h9
-rw-r--r--src/coincontrol.h3
-rw-r--r--src/compat.h1
-rw-r--r--src/consensus/consensus.h6
-rw-r--r--src/consensus/params.h1
-rw-r--r--src/consensus/validation.h17
-rw-r--r--src/core_io.h4
-rw-r--r--src/core_memusage.h2
-rw-r--r--src/core_read.cpp2
-rw-r--r--src/core_write.cpp68
-rw-r--r--src/dbwrapper.cpp152
-rw-r--r--src/dbwrapper.h280
-rw-r--r--src/ecwrapper.cpp33
-rw-r--r--src/httprpc.cpp193
-rw-r--r--src/httprpc.h37
-rw-r--r--src/httpserver.cpp654
-rw-r--r--src/httpserver.h149
-rw-r--r--src/init.cpp264
-rw-r--r--src/init.h2
-rw-r--r--src/keystore.cpp41
-rw-r--r--src/keystore.h5
-rw-r--r--src/leveldbwrapper.cpp88
-rw-r--r--src/leveldbwrapper.h173
-rw-r--r--src/limitedmap.h19
-rw-r--r--src/main.cpp542
-rw-r--r--src/main.h51
-rw-r--r--src/memusage.h18
-rw-r--r--src/merkleblock.cpp2
-rw-r--r--src/miner.cpp46
-rw-r--r--src/miner.h4
-rw-r--r--src/net.cpp413
-rw-r--r--src/net.h53
-rw-r--r--src/netbase.cpp69
-rw-r--r--src/policy/fees.cpp7
-rw-r--r--src/policy/fees.h2
-rw-r--r--src/policy/policy.cpp4
-rw-r--r--src/policy/policy.h6
-rw-r--r--src/pow.cpp3
-rw-r--r--src/primitives/block.cpp39
-rw-r--r--src/primitives/block.h12
-rw-r--r--src/primitives/transaction.cpp4
-rw-r--r--src/protocol.h4
-rw-r--r--src/qt/addressbookpage.cpp26
-rw-r--r--src/qt/addressbookpage.h3
-rw-r--r--src/qt/bantablemodel.cpp181
-rw-r--r--src/qt/bantablemodel.h72
-rw-r--r--src/qt/bitcoin.cpp47
-rw-r--r--src/qt/bitcoingui.cpp92
-rw-r--r--src/qt/bitcoingui.h11
-rw-r--r--src/qt/bitcoinstrings.cpp112
-rw-r--r--src/qt/clientmodel.cpp27
-rw-r--r--src/qt/clientmodel.h5
-rw-r--r--src/qt/coincontroldialog.cpp14
-rw-r--r--src/qt/coincontroldialog.h5
-rw-r--r--src/qt/forms/debugwindow.ui (renamed from src/qt/forms/rpcconsole.ui)156
-rw-r--r--src/qt/forms/optionsdialog.ui189
-rw-r--r--src/qt/guiconstants.h2
-rw-r--r--src/qt/guiutil.cpp4
-rw-r--r--src/qt/intro.cpp3
-rw-r--r--src/qt/locale/bitcoin_ach.ts2
-rw-r--r--src/qt/locale/bitcoin_af_ZA.ts2
-rw-r--r--src/qt/locale/bitcoin_ar.ts2
-rw-r--r--src/qt/locale/bitcoin_be_BY.ts2
-rw-r--r--src/qt/locale/bitcoin_bg.ts18
-rw-r--r--src/qt/locale/bitcoin_bs.ts2
-rw-r--r--src/qt/locale/bitcoin_ca.ts284
-rw-r--r--src/qt/locale/bitcoin_ca@valencia.ts657
-rw-r--r--src/qt/locale/bitcoin_ca_ES.ts284
-rw-r--r--src/qt/locale/bitcoin_cmn.ts6
-rw-r--r--src/qt/locale/bitcoin_cs.ts338
-rw-r--r--src/qt/locale/bitcoin_cy.ts2
-rw-r--r--src/qt/locale/bitcoin_da.ts86
-rw-r--r--src/qt/locale/bitcoin_de.ts86
-rw-r--r--src/qt/locale/bitcoin_el_GR.ts14
-rw-r--r--src/qt/locale/bitcoin_en.ts752
-rw-r--r--src/qt/locale/bitcoin_eo.ts48
-rw-r--r--src/qt/locale/bitcoin_es.ts206
-rw-r--r--src/qt/locale/bitcoin_es_CL.ts4
-rw-r--r--src/qt/locale/bitcoin_es_DO.ts6
-rw-r--r--src/qt/locale/bitcoin_es_MX.ts2
-rw-r--r--src/qt/locale/bitcoin_es_UY.ts2
-rw-r--r--src/qt/locale/bitcoin_et.ts2
-rw-r--r--src/qt/locale/bitcoin_eu_ES.ts2
-rw-r--r--src/qt/locale/bitcoin_fa.ts272
-rw-r--r--src/qt/locale/bitcoin_fa_IR.ts144
-rw-r--r--src/qt/locale/bitcoin_fi.ts226
-rw-r--r--src/qt/locale/bitcoin_fr.ts82
-rw-r--r--src/qt/locale/bitcoin_fr_CA.ts2
-rw-r--r--src/qt/locale/bitcoin_gl.ts2
-rw-r--r--src/qt/locale/bitcoin_gu_IN.ts2
-rw-r--r--src/qt/locale/bitcoin_he.ts18
-rw-r--r--src/qt/locale/bitcoin_hi_IN.ts2
-rw-r--r--src/qt/locale/bitcoin_hr.ts566
-rw-r--r--src/qt/locale/bitcoin_hu.ts94
-rw-r--r--src/qt/locale/bitcoin_id_ID.ts2
-rw-r--r--src/qt/locale/bitcoin_it.ts82
-rw-r--r--src/qt/locale/bitcoin_ja.ts86
-rw-r--r--src/qt/locale/bitcoin_ka.ts10
-rw-r--r--src/qt/locale/bitcoin_kk_KZ.ts2
-rw-r--r--src/qt/locale/bitcoin_ko_KR.ts32
-rw-r--r--src/qt/locale/bitcoin_ky.ts2
-rw-r--r--src/qt/locale/bitcoin_la.ts2
-rw-r--r--src/qt/locale/bitcoin_lt.ts66
-rw-r--r--src/qt/locale/bitcoin_lv_LV.ts2
-rw-r--r--src/qt/locale/bitcoin_mn.ts62
-rw-r--r--src/qt/locale/bitcoin_ms_MY.ts2
-rw-r--r--src/qt/locale/bitcoin_nb.ts86
-rw-r--r--src/qt/locale/bitcoin_nl.ts169
-rw-r--r--src/qt/locale/bitcoin_pam.ts6
-rw-r--r--src/qt/locale/bitcoin_pl.ts510
-rw-r--r--src/qt/locale/bitcoin_pt_BR.ts136
-rw-r--r--src/qt/locale/bitcoin_pt_PT.ts192
-rw-r--r--src/qt/locale/bitcoin_ro_RO.ts30
-rw-r--r--src/qt/locale/bitcoin_ru.ts276
-rw-r--r--src/qt/locale/bitcoin_sah.ts2
-rw-r--r--src/qt/locale/bitcoin_sk.ts620
-rw-r--r--src/qt/locale/bitcoin_sl_SI.ts1688
-rw-r--r--src/qt/locale/bitcoin_sq.ts32
-rw-r--r--src/qt/locale/bitcoin_sr.ts2
-rw-r--r--src/qt/locale/bitcoin_sv.ts148
-rw-r--r--src/qt/locale/bitcoin_th_TH.ts2
-rw-r--r--src/qt/locale/bitcoin_tr.ts110
-rw-r--r--src/qt/locale/bitcoin_uk.ts380
-rw-r--r--src/qt/locale/bitcoin_ur_PK.ts34
-rw-r--r--src/qt/locale/bitcoin_uz@Cyrl.ts6
-rw-r--r--src/qt/locale/bitcoin_vi.ts14
-rw-r--r--src/qt/locale/bitcoin_vi_VN.ts2
-rw-r--r--src/qt/locale/bitcoin_zh_CN.ts96
-rw-r--r--src/qt/locale/bitcoin_zh_HK.ts2
-rw-r--r--src/qt/locale/bitcoin_zh_TW.ts280
-rw-r--r--src/qt/networkstyle.cpp1
-rw-r--r--src/qt/optionsdialog.cpp53
-rw-r--r--src/qt/optionsdialog.h4
-rw-r--r--src/qt/optionsmodel.cpp59
-rw-r--r--src/qt/optionsmodel.h3
-rw-r--r--src/qt/overviewpage.cpp15
-rw-r--r--src/qt/overviewpage.h3
-rw-r--r--src/qt/paymentserver.cpp38
-rw-r--r--src/qt/paymentserver.h6
-rw-r--r--src/qt/peertablemodel.cpp19
-rw-r--r--src/qt/peertablemodel.h2
-rw-r--r--src/qt/platformstyle.cpp147
-rw-r--r--src/qt/platformstyle.h55
-rw-r--r--src/qt/receivecoinsdialog.cpp31
-rw-r--r--src/qt/receivecoinsdialog.h5
-rw-r--r--src/qt/res/icons/about_qt.pngbin2338 -> 2240 bytes
-rw-r--r--src/qt/res/icons/clock1.pngbin1921 -> 2618 bytes
-rw-r--r--src/qt/res/icons/clock2.pngbin1731 -> 2398 bytes
-rw-r--r--src/qt/res/icons/clock3.pngbin1557 -> 2055 bytes
-rw-r--r--src/qt/res/icons/clock4.pngbin1395 -> 1909 bytes
-rw-r--r--src/qt/res/icons/clock5.pngbin1889 -> 1659 bytes
-rw-r--r--src/qt/res/icons/connect0.pngbin2290 -> 2446 bytes
-rw-r--r--src/qt/res/icons/connect1.pngbin2242 -> 2163 bytes
-rw-r--r--src/qt/res/icons/connect2.pngbin1966 -> 1927 bytes
-rw-r--r--src/qt/res/icons/connect3.pngbin1966 -> 1750 bytes
-rw-r--r--src/qt/res/icons/connect4.pngbin1490 -> 1548 bytes
-rw-r--r--src/qt/res/icons/transaction0.pngbin1220 -> 1310 bytes
-rw-r--r--src/qt/res/icons/warning.pngbin3810 -> 2801 bytes
-rwxr-xr-xsrc/qt/res/movies/makespinner.sh7
-rw-r--r--src/qt/res/movies/spinner-000.pngbin1835 -> 1794 bytes
-rw-r--r--src/qt/res/src/clock_1.svg4
-rw-r--r--src/qt/res/src/clock_2.svg3
-rw-r--r--src/qt/res/src/clock_3.svg6
-rw-r--r--src/qt/res/src/clock_4.svg41
-rw-r--r--src/qt/res/src/connect-0.svg77
-rw-r--r--src/qt/res/src/connect-1.svg90
-rw-r--r--src/qt/res/src/connect-2.svg81
-rw-r--r--src/qt/res/src/connect-3.svg88
-rw-r--r--src/qt/res/src/connect-4.svg65
-rw-r--r--src/qt/res/src/qt.svg51
-rw-r--r--src/qt/res/src/spinner.png (renamed from src/qt/res/spinner.png)bin16636 -> 16636 bytes
-rw-r--r--src/qt/res/src/transaction0.svg35
-rw-r--r--src/qt/rpcconsole.cpp215
-rw-r--r--src/qt/rpcconsole.h28
-rw-r--r--src/qt/scicon.cpp98
-rw-r--r--src/qt/scicon.h24
-rw-r--r--src/qt/sendcoinsdialog.cpp39
-rw-r--r--src/qt/sendcoinsdialog.h4
-rw-r--r--src/qt/sendcoinsentry.cpp24
-rw-r--r--src/qt/sendcoinsentry.h4
-rw-r--r--src/qt/signverifymessagedialog.cpp35
-rw-r--r--src/qt/signverifymessagedialog.h4
-rw-r--r--src/qt/splashscreen.cpp2
-rw-r--r--src/qt/test/paymentservertests.cpp3
-rw-r--r--src/qt/test/test_main.cpp4
-rw-r--r--src/qt/transactiondesc.cpp4
-rw-r--r--src/qt/transactionrecord.cpp6
-rw-r--r--src/qt/transactiontablemodel.cpp11
-rw-r--r--src/qt/transactiontablemodel.h4
-rw-r--r--src/qt/transactionview.cpp63
-rw-r--r--src/qt/transactionview.h3
-rw-r--r--src/qt/walletframe.cpp7
-rw-r--r--src/qt/walletframe.h5
-rw-r--r--src/qt/walletmodel.cpp11
-rw-r--r--src/qt/walletmodel.h4
-rw-r--r--src/qt/walletview.cpp46
-rw-r--r--src/qt/walletview.h7
-rw-r--r--src/rest.cpp321
-rw-r--r--src/reverselock.h31
-rw-r--r--src/rpcblockchain.cpp123
-rw-r--r--src/rpcclient.cpp5
-rw-r--r--src/rpcclient.h2
-rw-r--r--src/rpcmining.cpp14
-rw-r--r--src/rpcmisc.cpp16
-rw-r--r--src/rpcnet.cpp24
-rw-r--r--src/rpcprotocol.cpp229
-rw-r--r--src/rpcprotocol.h89
-rw-r--r--src/rpcrawtransaction.cpp83
-rw-r--r--src/rpcserver.cpp570
-rw-r--r--src/rpcserver.h75
-rw-r--r--src/scheduler.cpp13
-rw-r--r--src/script/bitcoinconsensus.h7
-rw-r--r--src/script/interpreter.cpp10
-rw-r--r--src/script/interpreter.h2
-rw-r--r--src/script/script.cpp39
-rw-r--r--src/script/script.h12
-rw-r--r--src/script/standard.cpp28
-rw-r--r--src/script/standard.h3
-rw-r--r--src/streams.h23
-rw-r--r--src/sync.cpp49
-rw-r--r--src/sync.h10
-rw-r--r--src/test/Checkpoints_tests.cpp2
-rw-r--r--src/test/DoS_tests.cpp5
-rw-r--r--src/test/README.md16
-rw-r--r--src/test/addrman_tests.cpp180
-rw-r--r--src/test/alert_tests.cpp13
-rw-r--r--src/test/base58_tests.cpp2
-rw-r--r--src/test/bip32_tests.cpp11
-rw-r--r--src/test/bloom_tests.cpp6
-rw-r--r--src/test/checkblock_tests.cpp3
-rw-r--r--src/test/data/bitcoin-util-test.json30
-rw-r--r--src/test/data/tx_invalid.json8
-rw-r--r--src/test/data/tx_valid.json6
-rw-r--r--src/test/data/txcreatedata1.hex1
-rw-r--r--src/test/data/txcreatedata2.hex1
-rw-r--r--src/test/dbwrapper_tests.cpp207
-rw-r--r--src/test/getarg_tests.cpp22
-rw-r--r--src/test/limitedmap_tests.cpp101
-rw-r--r--src/test/mempool_tests.cpp335
-rw-r--r--src/test/miner_tests.cpp14
-rw-r--r--src/test/netbase_tests.cpp99
-rw-r--r--src/test/pmt_tests.cpp2
-rw-r--r--src/test/pow_tests.cpp4
-rw-r--r--src/test/reverselock_tests.cpp64
-rw-r--r--src/test/rpc_tests.cpp72
-rw-r--r--src/test/rpc_wallet_tests.cpp41
-rw-r--r--src/test/script_tests.cpp36
-rw-r--r--src/test/sighash_tests.cpp7
-rw-r--r--src/test/skiplist_tests.cpp2
-rw-r--r--src/test/streams_tests.cpp67
-rw-r--r--src/test/test_bitcoin.cpp58
-rw-r--r--src/test/test_bitcoin.h28
-rw-r--r--src/test/transaction_tests.cpp28
-rw-r--r--src/test/txvalidationcache_tests.cpp86
-rw-r--r--src/test/univalue_tests.cpp23
-rw-r--r--src/test/util_tests.cpp4
-rw-r--r--src/timedata.cpp9
-rw-r--r--src/txdb.cpp91
-rw-r--r--src/txdb.h8
-rw-r--r--src/txmempool.cpp627
-rw-r--r--src/txmempool.h352
-rw-r--r--src/ui_interface.h3
-rw-r--r--src/univalue/.gitignore31
-rw-r--r--src/univalue/.travis.yml52
-rw-r--r--src/univalue/COPYING19
-rw-r--r--src/univalue/Makefile.am84
-rw-r--r--src/univalue/README7
-rw-r--r--src/univalue/TODO10
-rwxr-xr-xsrc/univalue/autogen.sh9
-rw-r--r--src/univalue/build-aux/m4/.gitignore1
-rw-r--r--src/univalue/configure.ac69
-rw-r--r--src/univalue/gen/gen.cpp (renamed from src/univalue/gen.cpp)0
-rw-r--r--src/univalue/include/univalue.h (renamed from src/univalue/univalue.h)11
-rw-r--r--src/univalue/lib/.gitignore2
-rw-r--r--src/univalue/lib/univalue.cpp (renamed from src/univalue/univalue.cpp)71
-rw-r--r--src/univalue/lib/univalue_escapes.h (renamed from src/univalue/univalue_escapes.h)0
-rw-r--r--src/univalue/lib/univalue_read.cpp (renamed from src/univalue/univalue_read.cpp)14
-rw-r--r--src/univalue/lib/univalue_write.cpp (renamed from src/univalue/univalue_write.cpp)7
-rw-r--r--src/univalue/pc/libunivalue-uninstalled.pc.in9
-rw-r--r--src/univalue/pc/libunivalue.pc.in10
-rw-r--r--src/univalue/test/.gitignore1
-rw-r--r--src/univalue/test/fail1.json1
-rw-r--r--src/univalue/test/fail10.json1
-rw-r--r--src/univalue/test/fail11.json1
-rw-r--r--src/univalue/test/fail12.json1
-rw-r--r--src/univalue/test/fail13.json1
-rw-r--r--src/univalue/test/fail14.json1
-rw-r--r--src/univalue/test/fail15.json1
-rw-r--r--src/univalue/test/fail16.json1
-rw-r--r--src/univalue/test/fail17.json1
-rw-r--r--src/univalue/test/fail18.json1
-rw-r--r--src/univalue/test/fail19.json1
-rw-r--r--src/univalue/test/fail2.json1
-rw-r--r--src/univalue/test/fail20.json1
-rw-r--r--src/univalue/test/fail21.json1
-rw-r--r--src/univalue/test/fail22.json1
-rw-r--r--src/univalue/test/fail23.json1
-rw-r--r--src/univalue/test/fail24.json1
-rw-r--r--src/univalue/test/fail25.json1
-rw-r--r--src/univalue/test/fail26.json1
-rw-r--r--src/univalue/test/fail27.json2
-rw-r--r--src/univalue/test/fail28.json2
-rw-r--r--src/univalue/test/fail29.json1
-rw-r--r--src/univalue/test/fail3.json1
-rw-r--r--src/univalue/test/fail30.json1
-rw-r--r--src/univalue/test/fail31.json1
-rw-r--r--src/univalue/test/fail32.json1
-rw-r--r--src/univalue/test/fail33.json1
-rw-r--r--src/univalue/test/fail34.json1
-rw-r--r--src/univalue/test/fail4.json1
-rw-r--r--src/univalue/test/fail5.json1
-rw-r--r--src/univalue/test/fail6.json1
-rw-r--r--src/univalue/test/fail7.json1
-rw-r--r--src/univalue/test/fail8.json1
-rw-r--r--src/univalue/test/fail9.json1
-rw-r--r--src/univalue/test/pass1.json58
-rw-r--r--src/univalue/test/pass2.json1
-rw-r--r--src/univalue/test/pass3.json6
-rw-r--r--src/univalue/test/unitester.cpp115
-rw-r--r--src/util.cpp172
-rw-r--r--src/util.h5
-rw-r--r--src/utilstrencodings.cpp28
-rw-r--r--src/utilstrencodings.h16
-rw-r--r--src/utiltime.cpp8
-rw-r--r--src/utiltime.h1
-rw-r--r--src/validationinterface.cpp3
-rw-r--r--src/validationinterface.h4
-rw-r--r--src/version.h5
-rw-r--r--src/wallet/crypter.cpp6
-rw-r--r--src/wallet/rpcdump.cpp149
-rw-r--r--src/wallet/rpcwallet.cpp76
-rw-r--r--src/wallet/wallet.cpp46
-rw-r--r--src/wallet/wallet.h14
-rw-r--r--src/wallet/wallet_ismine.cpp10
-rw-r--r--src/wallet/wallet_ismine.h11
-rw-r--r--src/wallet/walletdb.cpp8
-rw-r--r--src/wallet/walletdb.h1
-rw-r--r--src/zmq/zmqabstractnotifier.cpp22
-rw-r--r--src/zmq/zmqabstractnotifier.h44
-rw-r--r--src/zmq/zmqconfig.h24
-rw-r--r--src/zmq/zmqnotificationinterface.cpp155
-rw-r--r--src/zmq/zmqnotificationinterface.h36
-rw-r--r--src/zmq/zmqpublishnotifier.cpp170
-rw-r--r--src/zmq/zmqpublishnotifier.h43
370 files changed, 17053 insertions, 5428 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index cc8dded413..f35b9dc898 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,4 @@
-DIST_SUBDIRS = secp256k1
+DIST_SUBDIRS = secp256k1 univalue
AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS)
@@ -21,6 +21,7 @@ BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config
BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include
+BITCOIN_INCLUDES += -I$(srcdir)/univalue/include
LIBBITCOIN_SERVER=libbitcoin_server.a
LIBBITCOIN_WALLET=libbitcoin_wallet.a
@@ -28,12 +29,15 @@ LIBBITCOIN_COMMON=libbitcoin_common.a
LIBBITCOIN_CLI=libbitcoin_cli.a
LIBBITCOIN_UTIL=libbitcoin_util.a
LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
-LIBBITCOIN_UNIVALUE=univalue/libbitcoin_univalue.a
LIBBITCOINQT=qt/libbitcoinqt.a
LIBSECP256K1=secp256k1/libsecp256k1.la
+LIBUNIVALUE=univalue/libunivalue.la
$(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*)
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
+
+$(LIBUNIVALUE): $(wildcard univalue/lib/*) $(wildcard univalue/include/*)
+ $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
# Make is not made aware of per-object dependencies to avoid limiting building parallelization
# But to build the less dependent modules first, we manually select their order here:
@@ -41,13 +45,15 @@ EXTRA_LIBRARIES = \
crypto/libbitcoin_crypto.a \
libbitcoin_util.a \
libbitcoin_common.a \
- univalue/libbitcoin_univalue.a \
libbitcoin_server.a \
libbitcoin_cli.a
if ENABLE_WALLET
BITCOIN_INCLUDES += $(BDB_CPPFLAGS)
EXTRA_LIBRARIES += libbitcoin_wallet.a
endif
+if ENABLE_ZMQ
+EXTRA_LIBRARIES += libbitcoin_zmq.a
+endif
if BUILD_BITCOIN_LIBS
lib_LTLIBRARIES = libbitcoinconsensus.la
@@ -58,6 +64,7 @@ endif
bin_PROGRAMS =
TESTS =
+BENCHMARKS =
if BUILD_BITCOIND
bin_PROGRAMS += bitcoind
@@ -98,10 +105,12 @@ BITCOIN_CORE_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 \
@@ -119,6 +128,7 @@ BITCOIN_CORE_H = \
protocol.h \
pubkey.h \
random.h \
+ reverselock.h \
rpcclient.h \
rpcprotocol.h \
rpcserver.h \
@@ -154,7 +164,12 @@ BITCOIN_CORE_H = \
wallet/db.h \
wallet/wallet.h \
wallet/wallet_ismine.h \
- wallet/walletdb.h
+ wallet/walletdb.h \
+ zmq/zmqabstractnotifier.h \
+ zmq/zmqconfig.h\
+ zmq/zmqnotificationinterface.h \
+ zmq/zmqpublishnotifier.h
+
obj/build.h: FORCE
@$(MKDIR_P) $(builddir)/obj
@@ -163,15 +178,17 @@ obj/build.h: FORCE
libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h
# server: shared between bitcoind and bitcoin-qt
-libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS)
+libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS)
libbitcoin_server_a_SOURCES = \
addrman.cpp \
alert.cpp \
bloom.cpp \
chain.cpp \
checkpoints.cpp \
+ httprpc.cpp \
+ httpserver.cpp \
init.cpp \
- leveldbwrapper.cpp \
+ dbwrapper.cpp \
main.cpp \
merkleblock.cpp \
miner.cpp \
@@ -194,6 +211,17 @@ libbitcoin_server_a_SOURCES = \
validationinterface.cpp \
$(BITCOIN_CORE_H)
+if ENABLE_ZMQ
+LIBBITCOIN_ZMQ=libbitcoin_zmq.a
+
+libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS)
+libbitcoin_zmq_a_SOURCES = \
+ zmq/zmqabstractnotifier.cpp \
+ zmq/zmqnotificationinterface.cpp \
+ zmq/zmqpublishnotifier.cpp
+endif
+
+
# wallet: shared between bitcoind and bitcoin-qt, but only linked
# when wallet enabled
libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES)
@@ -224,14 +252,6 @@ crypto_libbitcoin_crypto_a_SOURCES = \
crypto/sha512.cpp \
crypto/sha512.h
-# univalue JSON library
-univalue_libbitcoin_univalue_a_SOURCES = \
- univalue/univalue.cpp \
- univalue/univalue.h \
- univalue/univalue_escapes.h \
- univalue/univalue_read.cpp \
- univalue/univalue_write.cpp
-
# common: shared between bitcoind, and bitcoin-qt and non-server tools
libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_common_a_SOURCES = \
@@ -308,23 +328,26 @@ endif
bitcoind_LDADD = \
$(LIBBITCOIN_SERVER) \
$(LIBBITCOIN_COMMON) \
- $(LIBBITCOIN_UNIVALUE) \
+ $(LIBUNIVALUE) \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO) \
$(LIBLEVELDB) \
$(LIBMEMENV) \
$(LIBSECP256K1)
+if ENABLE_ZMQ
+bitcoind_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
+endif
+
if ENABLE_WALLET
bitcoind_LDADD += libbitcoin_wallet.a
endif
-bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
-#
+bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
# bitcoin-cli binary #
bitcoin_cli_SOURCES = bitcoin-cli.cpp
-bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES) $(EVENT_CFLAGS)
bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
if TARGET_WINDOWS
@@ -333,11 +356,10 @@ endif
bitcoin_cli_LDADD = \
$(LIBBITCOIN_CLI) \
- $(LIBBITCOIN_UNIVALUE) \
- $(LIBBITCOIN_UTIL) \
- $(LIBSECP256K1)
+ $(LIBUNIVALUE) \
+ $(LIBBITCOIN_UTIL)
-bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS)
+bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS)
#
# bitcoin-tx binary #
@@ -350,7 +372,7 @@ bitcoin_tx_SOURCES += bitcoin-tx-res.rc
endif
bitcoin_tx_LDADD = \
- $(LIBBITCOIN_UNIVALUE) \
+ $(LIBUNIVALUE) \
$(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO) \
@@ -390,7 +412,19 @@ libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BIT
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
@@ -399,7 +433,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:
@@ -418,6 +453,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..61fe9e287d
--- /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 = $(BITCOIN_INCLUDES) $(EVENT_CLFAGS) $(EVENT_PTHREADS_CFLAGS) -I$(builddir)/bench/
+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 2ec3468e06..67fd7c1076 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -87,7 +87,7 @@ QT_FORMS_UI = \
qt/forms/overviewpage.ui \
qt/forms/receivecoinsdialog.ui \
qt/forms/receiverequestdialog.ui \
- qt/forms/rpcconsole.ui \
+ qt/forms/debugwindow.ui \
qt/forms/sendcoinsdialog.ui \
qt/forms/sendcoinsentry.ui \
qt/forms/signverifymessagedialog.ui \
@@ -97,6 +97,7 @@ QT_MOC_CPP = \
qt/moc_addressbookpage.cpp \
qt/moc_addresstablemodel.cpp \
qt/moc_askpassphrasedialog.cpp \
+ qt/moc_bantablemodel.cpp \
qt/moc_bitcoinaddressvalidator.cpp \
qt/moc_bitcoinamountfield.cpp \
qt/moc_bitcoingui.cpp \
@@ -162,6 +163,7 @@ BITCOIN_QT_H = \
qt/addressbookpage.h \
qt/addresstablemodel.h \
qt/askpassphrasedialog.h \
+ qt/bantablemodel.h \
qt/bitcoinaddressvalidator.h \
qt/bitcoinamountfield.h \
qt/bitcoingui.h \
@@ -185,13 +187,13 @@ BITCOIN_QT_H = \
qt/paymentrequestplus.h \
qt/paymentserver.h \
qt/peertablemodel.h \
+ qt/platformstyle.h \
qt/qvalidatedlineedit.h \
qt/qvaluecombobox.h \
qt/receivecoinsdialog.h \
qt/receiverequestdialog.h \
qt/recentrequeststablemodel.h \
qt/rpcconsole.h \
- qt/scicon.h \
qt/sendcoinsdialog.h \
qt/sendcoinsentry.h \
qt/signverifymessagedialog.h \
@@ -260,6 +262,7 @@ RES_ICONS = \
qt/res/icons/verify.png
BITCOIN_QT_CPP = \
+ qt/bantablemodel.cpp \
qt/bitcoinaddressvalidator.cpp \
qt/bitcoinamountfield.cpp \
qt/bitcoingui.cpp \
@@ -273,10 +276,10 @@ BITCOIN_QT_CPP = \
qt/optionsdialog.cpp \
qt/optionsmodel.cpp \
qt/peertablemodel.cpp \
+ qt/platformstyle.cpp \
qt/qvalidatedlineedit.cpp \
qt/qvaluecombobox.cpp \
qt/rpcconsole.cpp \
- qt/scicon.cpp \
qt/splashscreen.cpp \
qt/trafficgraphwidget.cpp \
qt/utilitydialog.cpp
@@ -361,8 +364,12 @@ qt_bitcoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER)
if ENABLE_WALLET
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
endif
-qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
- $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1)
+if ENABLE_ZMQ
+qt_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
+endif
+qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
+ $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
+ $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
qt_bitcoin_qt_LIBTOOLFLAGS = --tag CXX
diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include
index c5392cf307..b8725c872d 100644
--- a/src/Makefile.qttest.include
+++ b/src/Makefile.qttest.include
@@ -30,9 +30,13 @@ qt_test_test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER)
if ENABLE_WALLET
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
endif
-qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) \
+if ENABLE_ZMQ
+qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
+endif
+qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \
$(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
- $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1)
+ $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
+ $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 0997148117..f23a8f41fc 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -15,6 +15,8 @@ EXTRA_DIST += \
test/data/tx394b54bb.hex \
test/data/txcreate1.hex \
test/data/txcreate2.hex \
+ test/data/txcreatedata1.hex \
+ test/data/txcreatedata2.hex \
test/data/txcreatesign.hex
JSON_TEST_FILES = \
@@ -34,6 +36,7 @@ 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/addrman_tests.cpp \
test/alert_tests.cpp \
test/allocator_tests.cpp \
test/base32_tests.cpp \
@@ -50,6 +53,8 @@ BITCOIN_TESTS =\
test/getarg_tests.cpp \
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/miner_tests.cpp \
@@ -59,6 +64,7 @@ BITCOIN_TESTS =\
test/pmt_tests.cpp \
test/policyestimator_tests.cpp \
test/pow_tests.cpp \
+ test/reverselock_tests.cpp \
test/rpc_tests.cpp \
test/sanity_tests.cpp \
test/scheduler_tests.cpp \
@@ -69,10 +75,12 @@ 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 \
test/transaction_tests.cpp \
+ test/txvalidationcache_tests.cpp \
test/uint256_tests.cpp \
test/univalue_tests.cpp \
test/util_tests.cpp
@@ -86,7 +94,7 @@ endif
test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
test_test_bitcoin_CPPFLAGS = $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS)
-test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
+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)
if ENABLE_WALLET
test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
@@ -95,6 +103,10 @@ endif
test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
+if ENABLE_ZMQ
+test_test_bitcoin_LDADD += $(ZMQ_LIBS)
+endif
+
nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES)
$(BITCOIN_TESTS): $(GENERATED_TEST_FILES)
@@ -115,6 +127,7 @@ check-local:
@echo "Running test/bitcoin-util-test.py..."
$(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check
+ $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check
%.json.h: %.json
@$(MKDIR_P) $(@D)
diff --git a/src/addrman.cpp b/src/addrman.cpp
index b605f4351d..078b9e1681 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -329,20 +329,26 @@ 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) {
int nKBucket = GetRandInt(ADDRMAN_TRIED_BUCKET_COUNT);
int nKBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
- if (vvTried[nKBucket][nKBucketPos] == -1)
- continue;
+ while (vvTried[nKBucket][nKBucketPos] == -1) {
+ nKBucket = (nKBucket + insecure_rand()) % ADDRMAN_TRIED_BUCKET_COUNT;
+ nKBucketPos = (nKBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE;
+ }
int nId = vvTried[nKBucket][nKBucketPos];
assert(mapInfo.count(nId) == 1);
CAddrInfo& info = mapInfo[nId];
@@ -356,8 +362,10 @@ CAddrInfo CAddrMan::Select_()
while (1) {
int nUBucket = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT);
int nUBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
- if (vvNew[nUBucket][nUBucketPos] == -1)
- continue;
+ while (vvNew[nUBucket][nUBucketPos] == -1) {
+ nUBucket = (nUBucket + insecure_rand()) % ADDRMAN_NEW_BUCKET_COUNT;
+ nUBucketPos = (nUBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE;
+ }
int nId = vvNew[nUBucket][nUBucketPos];
assert(mapInfo.count(nId) == 1);
CAddrInfo& info = mapInfo[nId];
diff --git a/src/addrman.h b/src/addrman.h
index 2623d89809..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.
@@ -265,7 +267,7 @@ public:
* Notice that vvTried, mapAddr and vVector are never encoded explicitly;
* they are instead reconstructed from the other information.
*
- * vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change,
+ * vvNew is serialized, but only used if ADDRMAN_UNKNOWN_BUCKET_COUNT didn't change,
* otherwise it is reconstructed as well.
*
* This format is more complex, but significantly smaller (at most 1.5 MiB), and supports
@@ -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 ad81e74226..91e54a9178 100644
--- a/src/alert.cpp
+++ b/src/alert.cpp
@@ -11,6 +11,7 @@
#include "timedata.h"
#include "ui_interface.h"
#include "util.h"
+#include "utilstrencodings.h"
#include <stdint.h>
#include <algorithm>
diff --git a/src/amount.cpp b/src/amount.cpp
index 0a394c96fc..b469181984 100644
--- a/src/amount.cpp
+++ b/src/amount.cpp
@@ -7,6 +7,8 @@
#include "tinyformat.h"
+const std::string CURRENCY_UNIT = "BTC";
+
CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nSize)
{
if (nSize > 0)
@@ -27,5 +29,5 @@ CAmount CFeeRate::GetFee(size_t nSize) const
std::string CFeeRate::ToString() const
{
- return strprintf("%d.%08d BTC/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN);
+ return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT);
}
diff --git a/src/amount.h b/src/amount.h
index 7dc62edac4..a4c7764cda 100644
--- a/src/amount.h
+++ b/src/amount.h
@@ -16,6 +16,8 @@ typedef int64_t CAmount;
static const CAmount COIN = 100000000;
static const CAmount CENT = 1000000;
+extern const std::string CURRENCY_UNIT;
+
/** No amount larger than this (in satoshi) is valid.
*
* Note that this constant is *not* the total money supply, which in Bitcoin
@@ -49,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/base58.h b/src/base58.h
index 787979c827..90014b9496 100644
--- a/src/base58.h
+++ b/src/base58.h
@@ -146,7 +146,10 @@ public:
K GetKey() {
K ret;
- ret.Decode(&vchData[0], &vchData[Size]);
+ if (vchData.size() == Size) {
+ //if base58 encouded data not holds a ext key, return a !IsValid() key
+ ret.Decode(&vchData[0]);
+ }
return ret;
}
@@ -154,6 +157,10 @@ public:
SetKey(key);
}
+ CBitcoinExtKeyBase(const std::string& strBase58c) {
+ SetString(strBase58c.c_str(), Params().Base58Prefix(Type).size());
+ }
+
CBitcoinExtKeyBase() {}
};
diff --git a/src/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..89c3b0cc2a
--- /dev/null
+++ b/src/bench/bench.cpp
@@ -0,0 +1,68 @@
+// 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..bf591a2be6
--- /dev/null
+++ b/src/bench/bench.h
@@ -0,0 +1,71 @@
+// 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_H
+#define BITCOIN_BENCH_H
+
+// 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);
+
+ */
+
+
+#include <boost/function.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/stringize.hpp>
+#include <map>
+#include <string>
+
+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_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 1c5a312874..6f22c70494 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -11,11 +11,19 @@
#include "utilstrencodings.h"
#include <boost/filesystem/operations.hpp>
+#include <stdio.h>
-#include "univalue/univalue.h"
+#include <event2/event.h>
+#include <event2/http.h>
+#include <event2/buffer.h>
+#include <event2/keyvalq_struct.h>
+
+#include <univalue.h>
using namespace std;
+static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900;
+
std::string HelpMessageCli()
{
string strUsage;
@@ -23,17 +31,13 @@ std::string HelpMessageCli()
strUsage += HelpMessageOpt("-?", _("This help message"));
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
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."));
+ AppendParamsHelpMessages(strUsage);
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));
strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start"));
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
-
- strUsage += HelpMessageGroup(_("SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
- strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcclienttimeout=<n>", strprintf(_("Timeout during HTTP requests (default: %d)"), DEFAULT_HTTP_CLIENT_TIMEOUT));
return strUsage;
}
@@ -63,7 +67,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" +
@@ -88,36 +92,81 @@ 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(std::exception &e) {
+ fprintf(stderr, "Error: %s\n", e.what());
+ return false;
+ }
+ if (GetBoolArg("-rpcssl", false))
+ {
+ fprintf(stderr, "Error: SSL mode for RPC (-rpcssl) is no longer supported.\n");
return false;
}
return true;
}
-UniValue CallRPC(const string& strMethod, const UniValue& params)
+
+/** Reply structure for request_done to fill in */
+struct HTTPReply
{
- // Connect to localhost
- bool fUseSSL = GetBoolArg("-rpcssl", false);
- boost::asio::io_service io_service;
- boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23);
- context.set_options(boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::no_sslv3);
- boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sslStream(io_service, context);
- SSLIOStreamDevice<boost::asio::ip::tcp> d(sslStream, fUseSSL);
- boost::iostreams::stream< SSLIOStreamDevice<boost::asio::ip::tcp> > stream(d);
-
- const bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort())));
- if (!fConnected)
- throw CConnectionFailed("couldn't connect to server");
+ int status;
+ std::string body;
+};
+
+static void http_request_done(struct evhttp_request *req, void *ctx)
+{
+ HTTPReply *reply = static_cast<HTTPReply*>(ctx);
+
+ if (req == NULL) {
+ /* If req is NULL, it means an error occurred while connecting, but
+ * I'm not sure how to find out which one. We also don't really care.
+ */
+ reply->status = 0;
+ return;
+ }
+
+ reply->status = evhttp_request_get_response_code(req);
+
+ struct evbuffer *buf = evhttp_request_get_input_buffer(req);
+ if (buf)
+ {
+ size_t size = evbuffer_get_length(buf);
+ const char *data = (const char*)evbuffer_pullup(buf, size);
+ if (data)
+ reply->body = std::string(data, size);
+ evbuffer_drain(buf, size);
+ }
+}
- // Find credentials to use
+UniValue CallRPC(const string& strMethod, const UniValue& params)
+{
+ std::string host = GetArg("-rpcconnect", "127.0.0.1");
+ int port = GetArg("-rpcport", BaseParams().RPCPort());
+
+ // Create event base
+ struct event_base *base = event_base_new(); // TODO RAII
+ if (!base)
+ throw runtime_error("cannot create event_base");
+
+ // Synchronously look up hostname
+ struct evhttp_connection *evcon = evhttp_connection_base_new(base, NULL, host.c_str(), port); // TODO RAII
+ if (evcon == NULL)
+ throw runtime_error("create connection failed");
+ evhttp_connection_set_timeout(evcon, GetArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT));
+
+ HTTPReply response;
+ struct evhttp_request *req = evhttp_request_new(http_request_done, (void*)&response); // TODO RAII
+ if (req == NULL)
+ throw runtime_error("create http request failed");
+
+ // Get credentials
std::string strRPCUserColonPass;
if (mapArgs["-rpcpassword"] == "") {
// Try fall back to cookie-based authentication if no password is provided
if (!GetAuthCookie(&strRPCUserColonPass)) {
throw runtime_error(strprintf(
- _("You must set rpcpassword=<password> in the configuration file:\n%s\n"
- "If the file does not exist, create it with owner-readable-only file permissions."),
+ _("Could not locate RPC credentials. No authentication cookie could be found, and no rpcpassword is set in the configuration file (%s)"),
GetConfigFile().string().c_str()));
}
@@ -125,34 +174,41 @@ UniValue CallRPC(const string& strMethod, const UniValue& params)
strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
}
- // HTTP basic authentication
- map<string, string> mapRequestHeaders;
- mapRequestHeaders["Authorization"] = string("Basic ") + EncodeBase64(strRPCUserColonPass);
-
- // Send request
- string strRequest = JSONRPCRequest(strMethod, params, 1);
- string strPost = HTTPPost(strRequest, mapRequestHeaders);
- stream << strPost << std::flush;
-
- // Receive HTTP reply status
- int nProto = 0;
- int nStatus = ReadHTTPStatus(stream, nProto);
+ struct evkeyvalq *output_headers = evhttp_request_get_output_headers(req);
+ assert(output_headers);
+ evhttp_add_header(output_headers, "Host", host.c_str());
+ evhttp_add_header(output_headers, "Connection", "close");
+ evhttp_add_header(output_headers, "Authorization", (std::string("Basic ") + EncodeBase64(strRPCUserColonPass)).c_str());
+
+ // Attach request data
+ std::string strRequest = JSONRPCRequest(strMethod, params, 1);
+ struct evbuffer * output_buffer = evhttp_request_get_output_buffer(req);
+ assert(output_buffer);
+ evbuffer_add(output_buffer, strRequest.data(), strRequest.size());
+
+ int r = evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/");
+ if (r != 0) {
+ evhttp_connection_free(evcon);
+ event_base_free(base);
+ throw CConnectionFailed("send http request failed");
+ }
- // Receive HTTP reply message headers and body
- map<string, string> mapHeaders;
- string strReply;
- ReadHTTPMessage(stream, mapHeaders, strReply, nProto, std::numeric_limits<size_t>::max());
+ event_base_dispatch(base);
+ evhttp_connection_free(evcon);
+ event_base_free(base);
- if (nStatus == HTTP_UNAUTHORIZED)
+ if (response.status == 0)
+ throw CConnectionFailed("couldn't connect to server");
+ else if (response.status == HTTP_UNAUTHORIZED)
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
- else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR)
- throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
- else if (strReply.empty())
+ else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR)
+ throw runtime_error(strprintf("server returned HTTP error %d", response.status));
+ else if (response.body.empty())
throw runtime_error("no response from server");
// Parse reply
UniValue valReply(UniValue::VSTR);
- if (!valReply.read(strReply))
+ if (!valReply.read(response.body))
throw runtime_error("couldn't parse reply from server");
const UniValue& reply = valReply.get_obj();
if (reply.empty())
@@ -248,6 +304,10 @@ int CommandLineRPC(int argc, char *argv[])
int main(int argc, char* argv[])
{
SetupEnvironment();
+ if (!SetupNetworking()) {
+ fprintf(stderr, "Error: Initializing networking failed\n");
+ exit(1);
+ }
try {
if(!AppInitRPC(argc, argv))
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index 9ad57d5c6f..3330fe5d12 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -12,7 +12,7 @@
#include "primitives/transaction.h"
#include "script/script.h"
#include "script/sign.h"
-#include "univalue/univalue.h"
+#include <univalue.h>
#include "util.h"
#include "utilmoneystr.h"
#include "utilstrencodings.h"
@@ -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(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());
@@ -70,6 +71,7 @@ static bool AppInitRawTx(int argc, char* argv[])
strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX"));
+ strUsage += HelpMessageOpt("outdata=[VALUE:]DATA", _("Add data-based output to TX"));
strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX"));
strUsage += HelpMessageOpt("sign=SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " +
_("This command requires JSON registers:") +
@@ -143,13 +145,14 @@ static void RegisterLoad(const string& strInput)
valStr.insert(valStr.size(), buf, bread);
}
- if (ferror(f)) {
+ int error = ferror(f);
+ fclose(f);
+
+ if (error) {
string strErr = "Error reading file " + filename;
throw runtime_error(strErr);
}
- fclose(f);
-
// evaluate as JSON buffer register
RegisterSetJson(key, valStr);
}
@@ -230,6 +233,35 @@ static void MutateTxAddOutAddr(CMutableTransaction& tx, const string& strInput)
tx.vout.push_back(txout);
}
+static void MutateTxAddOutData(CMutableTransaction& tx, const string& strInput)
+{
+ CAmount value = 0;
+
+ // separate [VALUE:]DATA in string
+ size_t pos = strInput.find(':');
+
+ if (pos==0)
+ throw runtime_error("TX output value not specified");
+
+ if (pos != string::npos) {
+ // extract and validate VALUE
+ string strValue = strInput.substr(0, pos);
+ if (!ParseMoney(strValue, value))
+ throw runtime_error("invalid TX output value");
+ }
+
+ // extract and validate DATA
+ string strData = strInput.substr(pos + 1, string::npos);
+
+ if (!IsHex(strData))
+ throw runtime_error("invalid TX output data");
+
+ std::vector<unsigned char> data = ParseHex(strData);
+
+ CTxOut txout(value, CScript() << OP_RETURN << data);
+ tx.vout.push_back(txout);
+}
+
static void MutateTxAddOutScript(CMutableTransaction& tx, const string& strInput)
{
// separate VALUE:SCRIPT in string
@@ -386,8 +418,8 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
CCoinsModifier coins = view.ModifyCoins(txid);
if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
string err("Previous output scriptPubKey mismatch:\n");
- err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+
- scriptPubKey.ToString();
+ err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+
+ ScriptToAsmStr(scriptPubKey);
throw runtime_error(err);
}
if ((unsigned int)nOut >= coins->vout.size())
@@ -469,6 +501,8 @@ static void MutateTx(CMutableTransaction& tx, const string& command,
MutateTxDelOutput(tx, commandVal);
else if (command == "outaddr")
MutateTxAddOutAddr(tx, commandVal);
+ else if (command == "outdata")
+ MutateTxAddOutData(tx, commandVal);
else if (command == "outscript")
MutateTxAddOutScript(tx, commandVal);
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index cce687ac98..d2af897242 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -3,18 +3,23 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include "chainparams.h"
#include "clientversion.h"
#include "rpcserver.h"
#include "init.h"
-#include "main.h"
#include "noui.h"
#include "scheduler.h"
#include "util.h"
+#include "httpserver.h"
+#include "httprpc.h"
+#include "rpcserver.h"
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
+#include <stdio.h>
+
/* Introduction text for doxygen: */
/*! \mainpage Developer documentation
@@ -44,7 +49,7 @@ void WaitForShutdown(boost::thread_group* threadGroup)
}
if (threadGroup)
{
- threadGroup->interrupt_all();
+ Interrupt(*threadGroup);
threadGroup->join_all();
}
}
@@ -67,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";
@@ -102,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(std::exception &e) {
+ fprintf(stderr, "Error: %s\n", e.what());
return false;
}
@@ -154,7 +161,7 @@ bool AppInit(int argc, char* argv[])
if (!fRet)
{
- threadGroup.interrupt_all();
+ Interrupt(threadGroup);
// threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of
// the startup-failure cases to make sure they don't result in a hang due to some
// thread-blocking-waiting-for-another-thread-during-startup case
diff --git a/src/bloom.cpp b/src/bloom.cpp
index 36cba491c4..de87206592 100644
--- a/src/bloom.cpp
+++ b/src/bloom.cpp
@@ -8,6 +8,7 @@
#include "hash.h"
#include "script/script.h"
#include "script/standard.h"
+#include "random.h"
#include "streams.h"
#include <math.h>
@@ -121,6 +122,12 @@ void CBloomFilter::clear()
isEmpty = true;
}
+void CBloomFilter::reset(unsigned int nNewTweak)
+{
+ clear();
+ nTweak = nNewTweak;
+}
+
bool CBloomFilter::IsWithinSizeConstraints() const
{
return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS;
@@ -209,15 +216,17 @@ void CBloomFilter::UpdateEmptyFull()
isEmpty = empty;
}
-CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate, unsigned int nTweak) :
- b1(nElements * 2, fpRate, nTweak), b2(nElements * 2, fpRate, nTweak)
+CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate) :
+ b1(nElements * 2, fpRate, 0), b2(nElements * 2, fpRate, 0)
{
// Implemented using two bloom filters of 2 * nElements each.
// We fill them up, and clear them, staggered, every nElements
// inserted, so at least one always contains the last nElements
// inserted.
- nBloomSize = nElements * 2;
nInsertions = 0;
+ nBloomSize = nElements * 2;
+
+ reset();
}
void CRollingBloomFilter::insert(const std::vector<unsigned char>& vKey)
@@ -234,6 +243,12 @@ void CRollingBloomFilter::insert(const std::vector<unsigned char>& vKey)
}
}
+void CRollingBloomFilter::insert(const uint256& hash)
+{
+ vector<unsigned char> data(hash.begin(), hash.end());
+ insert(data);
+}
+
bool CRollingBloomFilter::contains(const std::vector<unsigned char>& vKey) const
{
if (nInsertions < nBloomSize / 2) {
@@ -242,9 +257,16 @@ bool CRollingBloomFilter::contains(const std::vector<unsigned char>& vKey) const
return b1.contains(vKey);
}
-void CRollingBloomFilter::clear()
+bool CRollingBloomFilter::contains(const uint256& hash) const
+{
+ vector<unsigned char> data(hash.begin(), hash.end());
+ return contains(data);
+}
+
+void CRollingBloomFilter::reset()
{
- b1.clear();
- b2.clear();
+ unsigned int nNewTweak = GetRand(std::numeric_limits<unsigned int>::max());
+ b1.reset(nNewTweak);
+ b2.reset(nNewTweak);
nInsertions = 0;
}
diff --git a/src/bloom.h b/src/bloom.h
index bb17f59c86..a4dba8cb4f 100644
--- a/src/bloom.h
+++ b/src/bloom.h
@@ -89,6 +89,7 @@ public:
bool contains(const uint256& hash) const;
void clear();
+ void reset(unsigned int nNewTweak);
//! True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS
//! (catch a filter which was just deserialized which was too big)
@@ -103,7 +104,11 @@ public:
/**
* RollingBloomFilter is a probabilistic "keep track of most recently inserted" set.
- * Construct it with the number of items to keep track of, and a false-positive rate.
+ * Construct it with the number of items to keep track of, and a false-positive
+ * rate. Unlike CBloomFilter, by default nTweak is set to a cryptographically
+ * secure random value for you. Similarly rather than clear() the method
+ * reset() is provided, which also changes nTweak to decrease the impact of
+ * false-positives.
*
* contains(item) will always return true if item was one of the last N things
* insert()'ed ... but may also return true for items that were not inserted.
@@ -111,12 +116,17 @@ public:
class CRollingBloomFilter
{
public:
- CRollingBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak);
+ // A random bloom filter calls GetRand() at creation time.
+ // Don't create global CRollingBloomFilter objects, as they may be
+ // constructed before the randomizer is properly initialized.
+ CRollingBloomFilter(unsigned int nElements, double nFPRate);
void insert(const std::vector<unsigned char>& vKey);
+ void insert(const uint256& hash);
bool contains(const std::vector<unsigned char>& vKey) const;
+ bool contains(const uint256& hash) const;
- void clear();
+ void reset();
private:
unsigned int nBloomSize;
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 95e20bf61b..dd26c3b31a 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -5,6 +5,7 @@
#include "chainparams.h"
+#include "tinyformat.h"
#include "util.h"
#include "utilstrencodings.h"
@@ -12,17 +13,15 @@
#include <boost/assign/list_of.hpp>
-using namespace std;
-
#include "chainparamsseeds.h"
-static CBlock CreateGenesisBlock(const char* pszTimestamp, CScript genesisOutputScript, uint32_t nTime=1231006505, uint32_t nNonce=2083236893, uint32_t nBits=0x1d00ffff, int32_t nVersion=1, const CAmount& genesisReward=50 * COIN)
+static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
CMutableTransaction txNew;
txNew.nVersion = 1;
txNew.vin.resize(1);
txNew.vout.resize(1);
- txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
+ txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
txNew.vout[0].nValue = genesisReward;
txNew.vout[0].scriptPubKey = genesisOutputScript;
@@ -33,7 +32,7 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, CScript genesisOutput
genesis.nVersion = nVersion;
genesis.vtx.push_back(txNew);
genesis.hashPrevBlock.SetNull();
- genesis.hashMerkleRoot = genesis.BuildMerkleTree();
+ genesis.hashMerkleRoot = genesis.ComputeMerkleRoot();
return genesis;
}
@@ -48,10 +47,10 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, CScript genesisOutput
* CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
* vMerkleTree: 4a5e1e
*/
-static CBlock CreateGenesisBlock(uint32_t nTime=1231006505, uint32_t nNonce=2083236893, uint32_t nBits=0x1d00ffff, int32_t nVersion=1, const CAmount& genesisReward=50 * COIN)
+static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
- CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
+ const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}
@@ -78,6 +77,7 @@ public:
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
@@ -89,9 +89,10 @@ public:
pchMessageStart[3] = 0xd9;
vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284");
nDefaultPort = 8333;
+ nMaxTipAge = 24 * 60 * 60;
nPruneAfterHeight = 100000;
- genesis = CreateGenesisBlock();
+ genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
@@ -117,7 +118,7 @@ public:
fMineBlocksOnDemand = false;
fTestnetToBeDeprecatedFieldRPC = false;
- checkpointData = (Checkpoints::CCheckpointData) {
+ checkpointData = (CCheckpointData) {
boost::assign::map_list_of
( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
@@ -156,17 +157,20 @@ public:
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;
pchMessageStart[3] = 0x07;
vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a");
nDefaultPort = 18333;
+ nMaxTipAge = 0x7fffffff;
nPruneAfterHeight = 1000;
- genesis = CreateGenesisBlock(1296688602, 414098458);
+ genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"));
+ assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
vFixedSeeds.clear();
vSeeds.clear();
@@ -189,7 +193,7 @@ public:
fMineBlocksOnDemand = false;
fTestnetToBeDeprecatedFieldRPC = true;
- checkpointData = (Checkpoints::CCheckpointData) {
+ checkpointData = (CCheckpointData) {
boost::assign::map_list_of
( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")),
1337966069,
@@ -216,16 +220,21 @@ public:
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60;
consensus.fPowAllowMinDifficultyBlocks = true;
+ consensus.fPowNoRetargeting = true;
+
pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf;
pchMessageStart[2] = 0xb5;
pchMessageStart[3] = 0xda;
- genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff);
- consensus.hashGenesisBlock = genesis.GetHash();
+ nMaxTipAge = 24 * 60 * 60;
nDefaultPort = 18444;
- assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
nPruneAfterHeight = 1000;
+ genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN);
+ consensus.hashGenesisBlock = genesis.GetHash();
+ assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
+ assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
+
vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds.
vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds.
@@ -235,7 +244,7 @@ public:
fMineBlocksOnDemand = true;
fTestnetToBeDeprecatedFieldRPC = false;
- checkpointData = (Checkpoints::CCheckpointData){
+ checkpointData = (CCheckpointData){
boost::assign::map_list_of
( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")),
0,
@@ -258,31 +267,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 66d865b620..cb061d596e 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -7,7 +7,6 @@
#define BITCOIN_CHAINPARAMS_H
#include "chainparamsbase.h"
-#include "checkpoints.h"
#include "consensus/params.h"
#include "primitives/block.h"
#include "protocol.h"
@@ -24,6 +23,14 @@ struct SeedSpec6 {
uint16_t port;
};
+typedef std::map<int, uint256> MapCheckpoints;
+
+struct CCheckpointData {
+ MapCheckpoints mapCheckpoints;
+ int64_t nTimeLastCheckpoint;
+ int64_t nTransactionsLastCheckpoint;
+ double fTransactionsPerDay;
+};
/**
* CChainParams defines various tweakable parameters of a given instance of the
@@ -57,6 +64,7 @@ public:
bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; }
/** Policy: Filter transactions that do not match well-defined patterns */
bool RequireStandard() const { return fRequireStandard; }
+ int64_t MaxTipAge() const { return nMaxTipAge; }
int64_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; }
@@ -67,7 +75,7 @@ public:
const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
- const Checkpoints::CCheckpointData& Checkpoints() const { return checkpointData; }
+ const CCheckpointData& Checkpoints() const { return checkpointData; }
protected:
CChainParams() {}
@@ -76,6 +84,7 @@ protected:
//! Raw pub key bytes for the broadcast alert signing key.
std::vector<unsigned char> vAlertPubKey;
int nDefaultPort;
+ long nMaxTipAge;
uint64_t nPruneAfterHeight;
std::vector<CDNSSeedData> vSeeds;
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
@@ -87,7 +96,7 @@ protected:
bool fRequireStandard;
bool fMineBlocksOnDemand;
bool fTestnetToBeDeprecatedFieldRPC;
- Checkpoints::CCheckpointData checkpointData;
+ CCheckpointData checkpointData;
};
/**
@@ -96,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..db2dc751f5 100644
--- a/src/chainparamsbase.cpp
+++ b/src/chainparamsbase.cpp
@@ -5,10 +5,25 @@
#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
*/
@@ -71,31 +86,25 @@ const CBaseChainParams& BaseParams()
return *pCurrentBaseParams;
}
-void SelectBaseParams(CBaseChainParams::Network network)
+void SelectBaseParams(const std::string& chain)
{
- switch (network) {
- case CBaseChainParams::MAIN:
+ if (chain == CBaseChainParams::MAIN)
pCurrentBaseParams = &mainParams;
- break;
- case CBaseChainParams::TESTNET:
+ else if (chain == CBaseChainParams::TESTNET)
pCurrentBaseParams = &testNetParams;
- break;
- case CBaseChainParams::REGTEST:
+ else if (chain == CBaseChainParams::REGTEST)
pCurrentBaseParams = &regTestParams;
- break;
- default:
- assert(false && "Unimplemented network");
- return;
- }
+ else
+ throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, 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 +112,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..095c4cbdcb 100644
--- a/src/chainparamsbase.h
+++ b/src/chainparamsbase.h
@@ -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,25 @@ 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);
-
-/**
- * Looks for -regtest or -testnet and returns the appropriate Network ID.
- * Returns MAX_NETWORK_TYPES if an invalid combination is given.
- */
-CBaseChainParams::Network NetworkIdFromCommandLine();
+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 87f4ad7f2e..a9822eed89 100644
--- a/src/checkpoints.cpp
+++ b/src/checkpoints.cpp
@@ -4,6 +4,7 @@
#include "checkpoints.h"
+#include "chain.h"
#include "chainparams.h"
#include "main.h"
#include "uint256.h"
diff --git a/src/checkpoints.h b/src/checkpoints.h
index 001e3cc801..5fce6fa81e 100644
--- a/src/checkpoints.h
+++ b/src/checkpoints.h
@@ -10,6 +10,7 @@
#include <map>
class CBlockIndex;
+struct CCheckpointData;
/**
* Block-chain checkpoints are compiled-in sanity checks.
@@ -17,14 +18,6 @@ class CBlockIndex;
*/
namespace Checkpoints
{
-typedef std::map<int, uint256> MapCheckpoints;
-
-struct CCheckpointData {
- MapCheckpoints mapCheckpoints;
- int64_t nTimeLastCheckpoint;
- int64_t nTransactionsLastCheckpoint;
- double fTransactionsPerDay;
-};
//! Return conservative estimate of total number of blocks, 0 if unknown
int GetTotalBlocksEstimate(const CCheckpointData& data);
diff --git a/src/coincontrol.h b/src/coincontrol.h
index 3e8de83c39..bc965f9e19 100644
--- a/src/coincontrol.h
+++ b/src/coincontrol.h
@@ -14,6 +14,8 @@ public:
CTxDestination destChange;
//! If false, allows unselected inputs, but requires all selected inputs be used
bool fAllowOtherInputs;
+ //! Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria
+ bool fAllowWatchOnly;
CCoinControl()
{
@@ -24,6 +26,7 @@ public:
{
destChange = CNoDestination();
fAllowOtherInputs = false;
+ fAllowWatchOnly = false;
setSelected.clear();
}
diff --git a/src/compat.h b/src/compat.h
index 5378c2c761..20c2a25143 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -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/consensus/consensus.h b/src/consensus/consensus.h
index f937844e9f..6d6ce7e099 100644
--- a/src/consensus/consensus.h
+++ b/src/consensus/consensus.h
@@ -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/params.h b/src/consensus/params.h
index c480a1cce1..efbbbed352 100644
--- a/src/consensus/params.h
+++ b/src/consensus/params.h
@@ -22,6 +22,7 @@ struct Params {
/** 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 a97d983a31..d6051edc38 100644
--- a/src/consensus/validation.h
+++ b/src/consensus/validation.h
@@ -28,16 +28,19 @@ private:
} mode;
int nDoS;
std::string strRejectReason;
- unsigned char chRejectCode;
+ unsigned int chRejectCode;
bool corruptionPossible;
+ std::string strDebugMessage;
public:
CValidationState() : mode(MODE_VALID), nDoS(0), chRejectCode(0), corruptionPossible(false) {}
bool DoS(int level, bool ret = false,
- unsigned char chRejectCodeIn=0, std::string strRejectReasonIn="",
- bool corruptionIn=false) {
+ unsigned int chRejectCodeIn=0, const std::string &strRejectReasonIn="",
+ bool corruptionIn=false,
+ const std::string &strDebugMessageIn="") {
chRejectCode = chRejectCodeIn;
strRejectReason = strRejectReasonIn;
corruptionPossible = corruptionIn;
+ strDebugMessage = strDebugMessageIn;
if (mode == MODE_ERROR)
return ret;
nDoS += level;
@@ -45,8 +48,9 @@ public:
return ret;
}
bool Invalid(bool ret = false,
- unsigned char _chRejectCode=0, std::string _strRejectReason="") {
- return DoS(0, ret, _chRejectCode, _strRejectReason);
+ unsigned int _chRejectCode=0, const std::string &_strRejectReason="",
+ const std::string &_strDebugMessage="") {
+ return DoS(0, ret, _chRejectCode, _strRejectReason, false, _strDebugMessage);
}
bool Error(const std::string& strRejectReasonIn) {
if (mode == MODE_VALID)
@@ -73,8 +77,9 @@ public:
bool CorruptionPossible() const {
return corruptionPossible;
}
- unsigned char GetRejectCode() const { return chRejectCode; }
+ unsigned int GetRejectCode() const { return chRejectCode; }
std::string GetRejectReason() const { return strRejectReason; }
+ std::string GetDebugMessage() const { return strDebugMessage; }
};
#endif // BITCOIN_CONSENSUS_VALIDATION_H
diff --git a/src/core_io.h b/src/core_io.h
index 115e3199dc..ba5b4e6487 100644
--- a/src/core_io.h
+++ b/src/core_io.h
@@ -16,6 +16,7 @@ class UniValue;
// core_read.cpp
extern CScript ParseScript(const std::string& s);
+extern std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode = false);
extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx);
extern bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
extern uint256 ParseHashUV(const UniValue& v, const std::string& strName);
@@ -25,8 +26,7 @@ extern std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::strin
// core_write.cpp
extern std::string FormatScript(const CScript& script);
extern std::string EncodeHexTx(const CTransaction& tx);
-extern void ScriptPubKeyToUniv(const CScript& scriptPubKey,
- UniValue& out, bool fIncludeHex);
+extern void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
extern void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry);
#endif // BITCOIN_CORE_IO_H
diff --git a/src/core_memusage.h b/src/core_memusage.h
index 711135bb44..a05f59ee0c 100644
--- a/src/core_memusage.h
+++ b/src/core_memusage.h
@@ -48,7 +48,7 @@ static inline size_t RecursiveDynamicUsage(const CMutableTransaction& tx) {
}
static inline size_t RecursiveDynamicUsage(const CBlock& block) {
- size_t mem = memusage::DynamicUsage(block.vtx) + memusage::DynamicUsage(block.vMerkleTree);
+ size_t mem = memusage::DynamicUsage(block.vtx);
for (std::vector<CTransaction>::const_iterator it = block.vtx.begin(); it != block.vtx.end(); it++) {
mem += RecursiveDynamicUsage(*it);
}
diff --git a/src/core_read.cpp b/src/core_read.cpp
index f762f2c3b7..4be24f8e09 100644
--- a/src/core_read.cpp
+++ b/src/core_read.cpp
@@ -9,7 +9,7 @@
#include "script/script.h"
#include "serialize.h"
#include "streams.h"
-#include "univalue/univalue.h"
+#include <univalue.h>
#include "util.h"
#include "utilstrencodings.h"
#include "version.h"
diff --git a/src/core_write.cpp b/src/core_write.cpp
index c3babec2fc..533fedfe7a 100644
--- a/src/core_write.cpp
+++ b/src/core_write.cpp
@@ -10,11 +10,12 @@
#include "script/standard.h"
#include "serialize.h"
#include "streams.h"
-#include "univalue/univalue.h"
+#include <univalue.h>
#include "util.h"
#include "utilmoneystr.h"
#include "utilstrencodings.h"
+#include <boost/assign/list_of.hpp>
#include <boost/foreach.hpp>
using namespace std;
@@ -54,6 +55,67 @@ string FormatScript(const CScript& script)
return ret.substr(0, ret.size() - 1);
}
+const map<unsigned char, string> mapSigHashTypes =
+ boost::assign::map_list_of
+ (static_cast<unsigned char>(SIGHASH_ALL), string("ALL"))
+ (static_cast<unsigned char>(SIGHASH_ALL|SIGHASH_ANYONECANPAY), string("ALL|ANYONECANPAY"))
+ (static_cast<unsigned char>(SIGHASH_NONE), string("NONE"))
+ (static_cast<unsigned char>(SIGHASH_NONE|SIGHASH_ANYONECANPAY), string("NONE|ANYONECANPAY"))
+ (static_cast<unsigned char>(SIGHASH_SINGLE), string("SINGLE"))
+ (static_cast<unsigned char>(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY), string("SINGLE|ANYONECANPAY"))
+ ;
+
+/**
+ * Create the assembly string representation of a CScript object.
+ * @param[in] script CScript object to convert into the asm string representation.
+ * @param[in] fAttemptSighashDecode Whether to attempt to decode sighash types on data within the script that matches the format
+ * of a signature. Only pass true for scripts you believe could contain signatures. For example,
+ * pass false, or omit the this argument (defaults to false), for scriptPubKeys.
+ */
+string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode)
+{
+ string str;
+ opcodetype opcode;
+ vector<unsigned char> vch;
+ CScript::const_iterator pc = script.begin();
+ while (pc < script.end()) {
+ if (!str.empty()) {
+ str += " ";
+ }
+ if (!script.GetOp(pc, opcode, vch)) {
+ str += "[error]";
+ return str;
+ }
+ if (0 <= opcode && opcode <= OP_PUSHDATA4) {
+ if (vch.size() <= static_cast<vector<unsigned char>::size_type>(4)) {
+ str += strprintf("%d", CScriptNum(vch, false).getint());
+ } else {
+ // the IsUnspendable check makes sure not to try to decode OP_RETURN data that may match the format of a signature
+ if (fAttemptSighashDecode && !script.IsUnspendable()) {
+ string strSigHashDecode;
+ // goal: only attempt to decode a defined sighash type from data that looks like a signature within a scriptSig.
+ // this won't decode correctly formatted public keys in Pubkey or Multisig scripts due to
+ // the restrictions on the pubkey formats (see IsCompressedOrUncompressedPubKey) being incongruous with the
+ // checks in CheckSignatureEncoding.
+ if (CheckSignatureEncoding(vch, SCRIPT_VERIFY_STRICTENC, NULL)) {
+ const unsigned char chSigHashType = vch.back();
+ if (mapSigHashTypes.count(chSigHashType)) {
+ strSigHashDecode = "[" + mapSigHashTypes.find(chSigHashType)->second + "]";
+ vch.pop_back(); // remove the sighash type byte. it will be replaced by the decode.
+ }
+ }
+ str += HexStr(vch) + strSigHashDecode;
+ } else {
+ str += HexStr(vch);
+ }
+ }
+ } else {
+ str += GetOpName(opcode);
+ }
+ }
+ return str;
+}
+
string EncodeHexTx(const CTransaction& tx)
{
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
@@ -68,7 +130,7 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey,
vector<CTxDestination> addresses;
int nRequired;
- out.pushKV("asm", scriptPubKey.ToString());
+ out.pushKV("asm", ScriptToAsmStr(scriptPubKey));
if (fIncludeHex)
out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
@@ -101,7 +163,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry)
in.pushKV("txid", txin.prevout.hash.GetHex());
in.pushKV("vout", (int64_t)txin.prevout.n);
UniValue o(UniValue::VOBJ);
- o.pushKV("asm", txin.scriptSig.ToString());
+ o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true));
o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
in.pushKV("scriptSig", o);
}
diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp
new file mode 100644
index 0000000000..b6307cf0bf
--- /dev/null
+++ b/src/dbwrapper.cpp
@@ -0,0 +1,152 @@
+// 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 "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..aa28767508
--- /dev/null
+++ b/src/dbwrapper.h
@@ -0,0 +1,280 @@
+// 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_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(std::exception &e) {
+ 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(std::exception &e) {
+ 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/ecwrapper.cpp b/src/ecwrapper.cpp
index 5e3aec25ba..f94bc954fd 100644
--- a/src/ecwrapper.cpp
+++ b/src/ecwrapper.cpp
@@ -13,6 +13,29 @@
namespace {
+class ecgroup_order
+{
+public:
+ static const EC_GROUP* get()
+ {
+ static const ecgroup_order wrapper;
+ return wrapper.pgroup;
+ }
+
+private:
+ ecgroup_order()
+ : pgroup(EC_GROUP_new_by_curve_name(NID_secp256k1))
+ {
+ }
+
+ ~ecgroup_order()
+ {
+ EC_GROUP_free(pgroup);
+ }
+
+ EC_GROUP* pgroup;
+};
+
/**
* Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields
* recid selects which key is recovered
@@ -92,8 +115,10 @@ err:
} // anon namespace
CECKey::CECKey() {
- pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
+ pkey = EC_KEY_new();
assert(pkey != NULL);
+ int result = EC_KEY_set_group(pkey, ecgroup_order::get());
+ assert(result);
}
CECKey::~CECKey() {
@@ -185,11 +210,9 @@ bool CECKey::TweakPublic(const unsigned char vchTweak[32]) {
bool CECKey::SanityCheck()
{
- EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
- if(pkey == NULL)
+ const EC_GROUP *pgroup = ecgroup_order::get();
+ if(pgroup == NULL)
return false;
- EC_KEY_free(pkey);
-
// TODO Is there more EC functionality that could be missing?
return true;
}
diff --git a/src/httprpc.cpp b/src/httprpc.cpp
new file mode 100644
index 0000000000..98ac750bb1
--- /dev/null
+++ b/src/httprpc.cpp
@@ -0,0 +1,193 @@
+#include "httprpc.h"
+
+#include "base58.h"
+#include "chainparams.h"
+#include "httpserver.h"
+#include "rpcprotocol.h"
+#include "rpcserver.h"
+#include "random.h"
+#include "sync.h"
+#include "util.h"
+#include "utilstrencodings.h"
+#include "ui_interface.h"
+
+#include <boost/algorithm/string.hpp> // boost::trim
+
+/** Simple one-shot callback timer to be used by the RPC mechanism to e.g.
+ * re-lock the wellet.
+ */
+class HTTPRPCTimer : public RPCTimerBase
+{
+public:
+ HTTPRPCTimer(struct event_base* eventBase, boost::function<void(void)>& func, int64_t millis) :
+ ev(eventBase, false, func)
+ {
+ struct timeval tv;
+ tv.tv_sec = millis/1000;
+ tv.tv_usec = (millis%1000)*1000;
+ ev.trigger(&tv);
+ }
+private:
+ HTTPEvent ev;
+};
+
+class HTTPRPCTimerInterface : public RPCTimerInterface
+{
+public:
+ HTTPRPCTimerInterface(struct event_base* base) : base(base)
+ {
+ }
+ const char* Name()
+ {
+ return "HTTP";
+ }
+ RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis)
+ {
+ return new HTTPRPCTimer(base, func, millis);
+ }
+private:
+ struct event_base* base;
+};
+
+
+/* Pre-base64-encoded authentication token */
+static std::string strRPCUserColonPass;
+/* Stored RPC timer interface (for unregistration) */
+static HTTPRPCTimerInterface* httpRPCTimerInterface = 0;
+
+static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const UniValue& id)
+{
+ // Send error reply from json-rpc error object
+ int nStatus = HTTP_INTERNAL_SERVER_ERROR;
+ int code = find_value(objError, "code").get_int();
+
+ if (code == RPC_INVALID_REQUEST)
+ nStatus = HTTP_BAD_REQUEST;
+ else if (code == RPC_METHOD_NOT_FOUND)
+ nStatus = HTTP_NOT_FOUND;
+
+ std::string strReply = JSONRPCReply(NullUniValue, objError, id);
+
+ req->WriteHeader("Content-Type", "application/json");
+ req->WriteReply(nStatus, strReply);
+}
+
+static bool RPCAuthorized(const std::string& strAuth)
+{
+ if (strRPCUserColonPass.empty()) // Belt-and-suspenders measure if InitRPCAuthentication was not called
+ return false;
+ if (strAuth.substr(0, 6) != "Basic ")
+ return false;
+ std::string strUserPass64 = strAuth.substr(6);
+ boost::trim(strUserPass64);
+ std::string strUserPass = DecodeBase64(strUserPass64);
+ return TimingResistantEqual(strUserPass, strRPCUserColonPass);
+}
+
+static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &)
+{
+ // JSONRPC handles only POST
+ if (req->GetRequestMethod() != HTTPRequest::POST) {
+ req->WriteReply(HTTP_BAD_METHOD, "JSONRPC server handles only POST requests");
+ return false;
+ }
+ // Check authorization
+ std::pair<bool, std::string> authHeader = req->GetHeader("authorization");
+ if (!authHeader.first) {
+ req->WriteReply(HTTP_UNAUTHORIZED);
+ return false;
+ }
+
+ if (!RPCAuthorized(authHeader.second)) {
+ LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", req->GetPeer().ToString());
+
+ /* Deter brute-forcing
+ If this results in a DoS the user really
+ shouldn't have their RPC port exposed. */
+ MilliSleep(250);
+
+ req->WriteReply(HTTP_UNAUTHORIZED);
+ return false;
+ }
+
+ JSONRequest jreq;
+ try {
+ // Parse request
+ UniValue valRequest;
+ if (!valRequest.read(req->ReadBody()))
+ throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
+
+ std::string strReply;
+ // singleton request
+ if (valRequest.isObject()) {
+ jreq.parse(valRequest);
+
+ UniValue result = tableRPC.execute(jreq.strMethod, jreq.params);
+
+ // Send reply
+ strReply = JSONRPCReply(result, NullUniValue, jreq.id);
+
+ // array of requests
+ } else if (valRequest.isArray())
+ strReply = JSONRPCExecBatch(valRequest.get_array());
+ else
+ throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
+
+ req->WriteHeader("Content-Type", "application/json");
+ req->WriteReply(HTTP_OK, strReply);
+ } catch (const UniValue& objError) {
+ JSONErrorReply(req, objError, jreq.id);
+ return false;
+ } catch (const std::exception& e) {
+ JSONErrorReply(req, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
+ return false;
+ }
+ return true;
+}
+
+static bool InitRPCAuthentication()
+{
+ if (mapArgs["-rpcpassword"] == "")
+ {
+ LogPrintf("No rpcpassword set - using random cookie authentication\n");
+ if (!GenerateAuthCookie(&strRPCUserColonPass)) {
+ uiInterface.ThreadSafeMessageBox(
+ _("Error: A fatal internal error occurred, see debug.log for details"), // Same message as AbortNode
+ "", CClientUIInterface::MSG_ERROR);
+ return false;
+ }
+ } else {
+ strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
+ }
+ return true;
+}
+
+bool StartHTTPRPC()
+{
+ LogPrint("rpc", "Starting HTTP RPC server\n");
+ if (!InitRPCAuthentication())
+ return false;
+
+ RegisterHTTPHandler("/", true, HTTPReq_JSONRPC);
+
+ assert(EventBase());
+ httpRPCTimerInterface = new HTTPRPCTimerInterface(EventBase());
+ RPCRegisterTimerInterface(httpRPCTimerInterface);
+ return true;
+}
+
+void InterruptHTTPRPC()
+{
+ LogPrint("rpc", "Interrupting HTTP RPC server\n");
+}
+
+void StopHTTPRPC()
+{
+ LogPrint("rpc", "Stopping HTTP RPC server\n");
+ UnregisterHTTPHandler("/", true);
+ if (httpRPCTimerInterface) {
+ RPCUnregisterTimerInterface(httpRPCTimerInterface);
+ delete httpRPCTimerInterface;
+ httpRPCTimerInterface = 0;
+ }
+}
diff --git a/src/httprpc.h b/src/httprpc.h
new file mode 100644
index 0000000000..d354457188
--- /dev/null
+++ b/src/httprpc.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_HTTPRPC_H
+#define BITCOIN_HTTPRPC_H
+
+#include <string>
+#include <map>
+
+class HTTPRequest;
+
+/** Start HTTP RPC subsystem.
+ * Precondition; HTTP and RPC has been started.
+ */
+bool StartHTTPRPC();
+/** Interrupt HTTP RPC subsystem.
+ */
+void InterruptHTTPRPC();
+/** Stop HTTP RPC subsystem.
+ * Precondition; HTTP and RPC has been stopped.
+ */
+void StopHTTPRPC();
+
+/** Start HTTP REST subsystem.
+ * Precondition; HTTP and RPC has been started.
+ */
+bool StartREST();
+/** Interrupt RPC REST subsystem.
+ */
+void InterruptREST();
+/** Stop HTTP REST subsystem.
+ * Precondition; HTTP and RPC has been stopped.
+ */
+void StopREST();
+
+#endif
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
new file mode 100644
index 0000000000..8698abb900
--- /dev/null
+++ b/src/httpserver.cpp
@@ -0,0 +1,654 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "httpserver.h"
+
+#include "chainparamsbase.h"
+#include "compat.h"
+#include "util.h"
+#include "netbase.h"
+#include "rpcprotocol.h" // For HTTP status codes
+#include "sync.h"
+#include "ui_interface.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#include <event2/event.h>
+#include <event2/http.h>
+#include <event2/thread.h>
+#include <event2/buffer.h>
+#include <event2/util.h>
+#include <event2/keyvalq_struct.h>
+
+#ifdef EVENT__HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#ifdef _XOPEN_SOURCE_EXTENDED
+#include <arpa/inet.h>
+#endif
+#endif
+
+#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
+#include <boost/foreach.hpp>
+#include <boost/scoped_ptr.hpp>
+
+/** Maximum size of http request (request line + headers) */
+static const size_t MAX_HEADERS_SIZE = 8192;
+
+/** HTTP request work item */
+class HTTPWorkItem : public HTTPClosure
+{
+public:
+ HTTPWorkItem(HTTPRequest* req, const std::string &path, const HTTPRequestHandler& func):
+ req(req), path(path), func(func)
+ {
+ }
+ void operator()()
+ {
+ func(req.get(), path);
+ }
+
+ boost::scoped_ptr<HTTPRequest> req;
+
+private:
+ std::string path;
+ HTTPRequestHandler func;
+};
+
+/** Simple work queue for distributing work over multiple threads.
+ * Work items are simply callable objects.
+ */
+template <typename WorkItem>
+class WorkQueue
+{
+private:
+ /** Mutex protects entire object */
+ CWaitableCriticalSection cs;
+ CConditionVariable cond;
+ /* XXX in C++11 we can use std::unique_ptr here and avoid manual cleanup */
+ std::deque<WorkItem*> queue;
+ bool running;
+ size_t maxDepth;
+ int numThreads;
+
+ /** RAII object to keep track of number of running worker threads */
+ class ThreadCounter
+ {
+ public:
+ WorkQueue &wq;
+ ThreadCounter(WorkQueue &w): wq(w)
+ {
+ boost::lock_guard<boost::mutex> lock(wq.cs);
+ wq.numThreads += 1;
+ }
+ ~ThreadCounter()
+ {
+ boost::lock_guard<boost::mutex> lock(wq.cs);
+ wq.numThreads -= 1;
+ wq.cond.notify_all();
+ }
+ };
+
+public:
+ WorkQueue(size_t maxDepth) : running(true),
+ maxDepth(maxDepth),
+ numThreads(0)
+ {
+ }
+ /*( Precondition: worker threads have all stopped
+ * (call WaitExit)
+ */
+ ~WorkQueue()
+ {
+ while (!queue.empty()) {
+ delete queue.front();
+ queue.pop_front();
+ }
+ }
+ /** Enqueue a work item */
+ bool Enqueue(WorkItem* item)
+ {
+ boost::unique_lock<boost::mutex> lock(cs);
+ if (queue.size() >= maxDepth) {
+ return false;
+ }
+ queue.push_back(item);
+ cond.notify_one();
+ return true;
+ }
+ /** Thread function */
+ void Run()
+ {
+ ThreadCounter count(*this);
+ while (running) {
+ WorkItem* i = 0;
+ {
+ boost::unique_lock<boost::mutex> lock(cs);
+ while (running && queue.empty())
+ cond.wait(lock);
+ if (!running)
+ break;
+ i = queue.front();
+ queue.pop_front();
+ }
+ (*i)();
+ delete i;
+ }
+ }
+ /** Interrupt and exit loops */
+ void Interrupt()
+ {
+ boost::unique_lock<boost::mutex> lock(cs);
+ running = false;
+ cond.notify_all();
+ }
+ /** Wait for worker threads to exit */
+ void WaitExit()
+ {
+ boost::unique_lock<boost::mutex> lock(cs);
+ while (numThreads > 0)
+ cond.wait(lock);
+ }
+
+ /** Return current depth of queue */
+ size_t Depth()
+ {
+ boost::unique_lock<boost::mutex> lock(cs);
+ return queue.size();
+ }
+};
+
+struct HTTPPathHandler
+{
+ HTTPPathHandler() {}
+ HTTPPathHandler(std::string prefix, bool exactMatch, HTTPRequestHandler handler):
+ prefix(prefix), exactMatch(exactMatch), handler(handler)
+ {
+ }
+ std::string prefix;
+ bool exactMatch;
+ HTTPRequestHandler handler;
+};
+
+/** HTTP module state */
+
+//! libevent event loop
+static struct event_base* eventBase = 0;
+//! HTTP server
+struct evhttp* eventHTTP = 0;
+//! List of subnets to allow RPC connections from
+static std::vector<CSubNet> rpc_allow_subnets;
+//! Work queue for handling longer requests off the event loop thread
+static WorkQueue<HTTPClosure>* workQueue = 0;
+//! Handlers for (sub)paths
+std::vector<HTTPPathHandler> pathHandlers;
+//! Bound listening sockets
+std::vector<evhttp_bound_socket *> boundSockets;
+
+/** Check if a network address is allowed to access the HTTP server */
+static bool ClientAllowed(const CNetAddr& netaddr)
+{
+ if (!netaddr.IsValid())
+ return false;
+ BOOST_FOREACH (const CSubNet& subnet, rpc_allow_subnets)
+ if (subnet.Match(netaddr))
+ return true;
+ return false;
+}
+
+/** Initialize ACL list for HTTP server */
+static bool InitHTTPAllowList()
+{
+ rpc_allow_subnets.clear();
+ rpc_allow_subnets.push_back(CSubNet("127.0.0.0/8")); // always allow IPv4 local subnet
+ rpc_allow_subnets.push_back(CSubNet("::1")); // always allow IPv6 localhost
+ if (mapMultiArgs.count("-rpcallowip")) {
+ const std::vector<std::string>& vAllow = mapMultiArgs["-rpcallowip"];
+ BOOST_FOREACH (std::string strAllow, vAllow) {
+ CSubNet subnet(strAllow);
+ if (!subnet.IsValid()) {
+ uiInterface.ThreadSafeMessageBox(
+ strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow),
+ "", CClientUIInterface::MSG_ERROR);
+ return false;
+ }
+ rpc_allow_subnets.push_back(subnet);
+ }
+ }
+ std::string strAllowed;
+ BOOST_FOREACH (const CSubNet& subnet, rpc_allow_subnets)
+ strAllowed += subnet.ToString() + " ";
+ LogPrint("http", "Allowing HTTP connections from: %s\n", strAllowed);
+ return true;
+}
+
+/** HTTP request method as string - use for logging only */
+static std::string RequestMethodString(HTTPRequest::RequestMethod m)
+{
+ switch (m) {
+ case HTTPRequest::GET:
+ return "GET";
+ break;
+ case HTTPRequest::POST:
+ return "POST";
+ break;
+ case HTTPRequest::HEAD:
+ return "HEAD";
+ break;
+ case HTTPRequest::PUT:
+ return "PUT";
+ break;
+ default:
+ return "unknown";
+ }
+}
+
+/** HTTP request callback */
+static void http_request_cb(struct evhttp_request* req, void* arg)
+{
+ std::auto_ptr<HTTPRequest> hreq(new HTTPRequest(req));
+
+ LogPrint("http", "Received a %s request for %s from %s\n",
+ RequestMethodString(hreq->GetRequestMethod()), hreq->GetURI(), hreq->GetPeer().ToString());
+
+ // Early address-based allow check
+ if (!ClientAllowed(hreq->GetPeer())) {
+ hreq->WriteReply(HTTP_FORBIDDEN);
+ return;
+ }
+
+ // Early reject unknown HTTP methods
+ if (hreq->GetRequestMethod() == HTTPRequest::UNKNOWN) {
+ hreq->WriteReply(HTTP_BADMETHOD);
+ return;
+ }
+
+ // Find registered handler for prefix
+ std::string strURI = hreq->GetURI();
+ std::string path;
+ std::vector<HTTPPathHandler>::const_iterator i = pathHandlers.begin();
+ std::vector<HTTPPathHandler>::const_iterator iend = pathHandlers.end();
+ for (; i != iend; ++i) {
+ bool match = false;
+ if (i->exactMatch)
+ match = (strURI == i->prefix);
+ else
+ match = (strURI.substr(0, i->prefix.size()) == i->prefix);
+ if (match) {
+ path = strURI.substr(i->prefix.size());
+ break;
+ }
+ }
+
+ // Dispatch to worker thread
+ if (i != iend) {
+ std::auto_ptr<HTTPWorkItem> item(new HTTPWorkItem(hreq.release(), path, i->handler));
+ assert(workQueue);
+ if (workQueue->Enqueue(item.get()))
+ item.release(); /* if true, queue took ownership */
+ else
+ item->req->WriteReply(HTTP_INTERNAL, "Work queue depth exceeded");
+ } else {
+ hreq->WriteReply(HTTP_NOTFOUND);
+ }
+}
+
+/** Callback to reject HTTP requests after shutdown. */
+static void http_reject_request_cb(struct evhttp_request* req, void*)
+{
+ LogPrint("http", "Rejecting request while shutting down\n");
+ evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL);
+}
+
+/** Event dispatcher thread */
+static void ThreadHTTP(struct event_base* base, struct evhttp* http)
+{
+ RenameThread("bitcoin-http");
+ LogPrint("http", "Entering http event loop\n");
+ event_base_dispatch(base);
+ // Event loop will be interrupted by InterruptHTTPServer()
+ LogPrint("http", "Exited http event loop\n");
+}
+
+/** Bind HTTP server to specified addresses */
+static bool HTTPBindAddresses(struct evhttp* http)
+{
+ int defaultPort = GetArg("-rpcport", BaseParams().RPCPort());
+ std::vector<std::pair<std::string, uint16_t> > endpoints;
+
+ // Determine what addresses to bind to
+ if (!mapArgs.count("-rpcallowip")) { // Default to loopback if not allowing external IPs
+ endpoints.push_back(std::make_pair("::1", defaultPort));
+ endpoints.push_back(std::make_pair("127.0.0.1", defaultPort));
+ if (mapArgs.count("-rpcbind")) {
+ LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n");
+ }
+ } else if (mapArgs.count("-rpcbind")) { // Specific bind address
+ const std::vector<std::string>& vbind = mapMultiArgs["-rpcbind"];
+ for (std::vector<std::string>::const_iterator i = vbind.begin(); i != vbind.end(); ++i) {
+ int port = defaultPort;
+ std::string host;
+ SplitHostPort(*i, port, host);
+ endpoints.push_back(std::make_pair(host, port));
+ }
+ } else { // No specific bind address specified, bind to any
+ endpoints.push_back(std::make_pair("::", defaultPort));
+ endpoints.push_back(std::make_pair("0.0.0.0", defaultPort));
+ }
+
+ // Bind addresses
+ for (std::vector<std::pair<std::string, uint16_t> >::iterator i = endpoints.begin(); i != endpoints.end(); ++i) {
+ LogPrint("http", "Binding RPC on address %s port %i\n", i->first, i->second);
+ evhttp_bound_socket *bind_handle = evhttp_bind_socket_with_handle(http, i->first.empty() ? NULL : i->first.c_str(), i->second);
+ if (bind_handle) {
+ boundSockets.push_back(bind_handle);
+ } else {
+ LogPrintf("Binding RPC on address %s port %i failed.\n", i->first, i->second);
+ }
+ }
+ return !boundSockets.empty();
+}
+
+/** Simple wrapper to set thread name and run work queue */
+static void HTTPWorkQueueRun(WorkQueue<HTTPClosure>* queue)
+{
+ RenameThread("bitcoin-httpworker");
+ queue->Run();
+}
+
+/** libevent event log callback */
+static void libevent_log_cb(int severity, const char *msg)
+{
+ if (severity >= EVENT_LOG_WARN) // Log warn messages and higher without debug category
+ LogPrintf("libevent: %s\n", msg);
+ else
+ LogPrint("libevent", "libevent: %s\n", msg);
+}
+
+bool InitHTTPServer()
+{
+ struct evhttp* http = 0;
+ struct event_base* base = 0;
+
+ if (!InitHTTPAllowList())
+ return false;
+
+ if (GetBoolArg("-rpcssl", false)) {
+ uiInterface.ThreadSafeMessageBox(
+ "SSL mode for RPC (-rpcssl) is no longer supported.",
+ "", CClientUIInterface::MSG_ERROR);
+ return false;
+ }
+
+ // Redirect libevent's logging to our own log
+ event_set_log_callback(&libevent_log_cb);
+#if LIBEVENT_VERSION_NUMBER >= 0x02010100
+ // If -debug=libevent, set full libevent debugging.
+ // Otherwise, disable all libevent debugging.
+ if (LogAcceptCategory("libevent"))
+ event_enable_debug_logging(EVENT_DBG_ALL);
+ else
+ event_enable_debug_logging(EVENT_DBG_NONE);
+#endif
+#ifdef WIN32
+ evthread_use_windows_threads();
+#else
+ evthread_use_pthreads();
+#endif
+
+ base = event_base_new(); // XXX RAII
+ if (!base) {
+ LogPrintf("Couldn't create an event_base: exiting\n");
+ return false;
+ }
+
+ /* Create a new evhttp object to handle requests. */
+ http = evhttp_new(base); // XXX RAII
+ if (!http) {
+ LogPrintf("couldn't create evhttp. Exiting.\n");
+ event_base_free(base);
+ return false;
+ }
+
+ evhttp_set_timeout(http, GetArg("-rpcservertimeout", DEFAULT_HTTP_SERVER_TIMEOUT));
+ evhttp_set_max_headers_size(http, MAX_HEADERS_SIZE);
+ evhttp_set_max_body_size(http, MAX_SIZE);
+ evhttp_set_gencb(http, http_request_cb, NULL);
+
+ if (!HTTPBindAddresses(http)) {
+ LogPrintf("Unable to bind any endpoint for RPC server\n");
+ evhttp_free(http);
+ event_base_free(base);
+ return false;
+ }
+
+ LogPrint("http", "Initialized HTTP server\n");
+ int workQueueDepth = std::max((long)GetArg("-rpcworkqueue", DEFAULT_HTTP_WORKQUEUE), 1L);
+ LogPrintf("HTTP: creating work queue of depth %d\n", workQueueDepth);
+
+ workQueue = new WorkQueue<HTTPClosure>(workQueueDepth);
+ eventBase = base;
+ eventHTTP = http;
+ return true;
+}
+
+bool StartHTTPServer(boost::thread_group& threadGroup)
+{
+ LogPrint("http", "Starting HTTP server\n");
+ int rpcThreads = std::max((long)GetArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L);
+ LogPrintf("HTTP: starting %d worker threads\n", rpcThreads);
+ threadGroup.create_thread(boost::bind(&ThreadHTTP, eventBase, eventHTTP));
+
+ for (int i = 0; i < rpcThreads; i++)
+ threadGroup.create_thread(boost::bind(&HTTPWorkQueueRun, workQueue));
+ return true;
+}
+
+void InterruptHTTPServer()
+{
+ LogPrint("http", "Interrupting HTTP server\n");
+ if (eventHTTP) {
+ // Unlisten sockets
+ BOOST_FOREACH (evhttp_bound_socket *socket, boundSockets) {
+ evhttp_del_accept_socket(eventHTTP, socket);
+ }
+ // Reject requests on current connections
+ evhttp_set_gencb(eventHTTP, http_reject_request_cb, NULL);
+ }
+ if (eventBase) {
+ // Force-exit event loop after predefined time
+ struct timeval tv;
+ tv.tv_sec = 10;
+ tv.tv_usec = 0;
+ event_base_loopexit(eventBase, &tv);
+ }
+ if (workQueue)
+ workQueue->Interrupt();
+}
+
+void StopHTTPServer()
+{
+ LogPrint("http", "Stopping HTTP server\n");
+ if (workQueue) {
+ LogPrint("http", "Waiting for HTTP worker threads to exit\n");
+ workQueue->WaitExit();
+ delete workQueue;
+ }
+ if (eventHTTP) {
+ evhttp_free(eventHTTP);
+ eventHTTP = 0;
+ }
+ if (eventBase) {
+ event_base_free(eventBase);
+ eventBase = 0;
+ }
+}
+
+struct event_base* EventBase()
+{
+ return eventBase;
+}
+
+static void httpevent_callback_fn(evutil_socket_t, short, void* data)
+{
+ // Static handler: simply call inner handler
+ HTTPEvent *self = ((HTTPEvent*)data);
+ self->handler();
+ if (self->deleteWhenTriggered)
+ delete self;
+}
+
+HTTPEvent::HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const boost::function<void(void)>& handler):
+ deleteWhenTriggered(deleteWhenTriggered), handler(handler)
+{
+ ev = event_new(base, -1, 0, httpevent_callback_fn, this);
+ assert(ev);
+}
+HTTPEvent::~HTTPEvent()
+{
+ event_free(ev);
+}
+void HTTPEvent::trigger(struct timeval* tv)
+{
+ if (tv == NULL)
+ event_active(ev, 0, 0); // immediately trigger event in main thread
+ else
+ evtimer_add(ev, tv); // trigger after timeval passed
+}
+HTTPRequest::HTTPRequest(struct evhttp_request* req) : req(req),
+ replySent(false)
+{
+}
+HTTPRequest::~HTTPRequest()
+{
+ if (!replySent) {
+ // Keep track of whether reply was sent to avoid request leaks
+ LogPrintf("%s: Unhandled request\n", __func__);
+ WriteReply(HTTP_INTERNAL, "Unhandled request");
+ }
+ // evhttpd cleans up the request, as long as a reply was sent.
+}
+
+std::pair<bool, std::string> HTTPRequest::GetHeader(const std::string& hdr)
+{
+ const struct evkeyvalq* headers = evhttp_request_get_input_headers(req);
+ assert(headers);
+ const char* val = evhttp_find_header(headers, hdr.c_str());
+ if (val)
+ return std::make_pair(true, val);
+ else
+ return std::make_pair(false, "");
+}
+
+std::string HTTPRequest::ReadBody()
+{
+ struct evbuffer* buf = evhttp_request_get_input_buffer(req);
+ if (!buf)
+ return "";
+ size_t size = evbuffer_get_length(buf);
+ /** Trivial implementation: if this is ever a performance bottleneck,
+ * internal copying can be avoided in multi-segment buffers by using
+ * evbuffer_peek and an awkward loop. Though in that case, it'd be even
+ * better to not copy into an intermediate string but use a stream
+ * abstraction to consume the evbuffer on the fly in the parsing algorithm.
+ */
+ const char* data = (const char*)evbuffer_pullup(buf, size);
+ if (!data) // returns NULL in case of empty buffer
+ return "";
+ std::string rv(data, size);
+ evbuffer_drain(buf, size);
+ return rv;
+}
+
+void HTTPRequest::WriteHeader(const std::string& hdr, const std::string& value)
+{
+ struct evkeyvalq* headers = evhttp_request_get_output_headers(req);
+ assert(headers);
+ evhttp_add_header(headers, hdr.c_str(), value.c_str());
+}
+
+/** Closure sent to main thread to request a reply to be sent to
+ * a HTTP request.
+ * Replies must be sent in the main loop in the main http thread,
+ * this cannot be done from worker threads.
+ */
+void HTTPRequest::WriteReply(int nStatus, const std::string& strReply)
+{
+ assert(!replySent && req);
+ // Send event to main http thread to send reply message
+ struct evbuffer* evb = evhttp_request_get_output_buffer(req);
+ assert(evb);
+ evbuffer_add(evb, strReply.data(), strReply.size());
+ HTTPEvent* ev = new HTTPEvent(eventBase, true,
+ boost::bind(evhttp_send_reply, req, nStatus, (const char*)NULL, (struct evbuffer *)NULL));
+ ev->trigger(0);
+ replySent = true;
+ req = 0; // transferred back to main thread
+}
+
+CService HTTPRequest::GetPeer()
+{
+ evhttp_connection* con = evhttp_request_get_connection(req);
+ CService peer;
+ if (con) {
+ // evhttp retains ownership over returned address string
+ const char* address = "";
+ uint16_t port = 0;
+ evhttp_connection_get_peer(con, (char**)&address, &port);
+ peer = CService(address, port);
+ }
+ return peer;
+}
+
+std::string HTTPRequest::GetURI()
+{
+ return evhttp_request_get_uri(req);
+}
+
+HTTPRequest::RequestMethod HTTPRequest::GetRequestMethod()
+{
+ switch (evhttp_request_get_command(req)) {
+ case EVHTTP_REQ_GET:
+ return GET;
+ break;
+ case EVHTTP_REQ_POST:
+ return POST;
+ break;
+ case EVHTTP_REQ_HEAD:
+ return HEAD;
+ break;
+ case EVHTTP_REQ_PUT:
+ return PUT;
+ break;
+ default:
+ return UNKNOWN;
+ break;
+ }
+}
+
+void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler)
+{
+ LogPrint("http", "Registering HTTP handler for %s (exactmatch %d)\n", prefix, exactMatch);
+ pathHandlers.push_back(HTTPPathHandler(prefix, exactMatch, handler));
+}
+
+void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch)
+{
+ std::vector<HTTPPathHandler>::iterator i = pathHandlers.begin();
+ std::vector<HTTPPathHandler>::iterator iend = pathHandlers.end();
+ for (; i != iend; ++i)
+ if (i->prefix == prefix && i->exactMatch == exactMatch)
+ break;
+ if (i != iend)
+ {
+ LogPrint("http", "Unregistering HTTP handler for %s (exactmatch %d)\n", prefix, exactMatch);
+ pathHandlers.erase(i);
+ }
+}
+
diff --git a/src/httpserver.h b/src/httpserver.h
new file mode 100644
index 0000000000..b377dc19fc
--- /dev/null
+++ b/src/httpserver.h
@@ -0,0 +1,149 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_HTTPSERVER_H
+#define BITCOIN_HTTPSERVER_H
+
+#include <string>
+#include <stdint.h>
+#include <boost/thread.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/function.hpp>
+
+static const int DEFAULT_HTTP_THREADS=4;
+static const int DEFAULT_HTTP_WORKQUEUE=16;
+static const int DEFAULT_HTTP_SERVER_TIMEOUT=30;
+
+struct evhttp_request;
+struct event_base;
+class CService;
+class HTTPRequest;
+
+/** Initialize HTTP server.
+ * Call this before RegisterHTTPHandler or EventBase().
+ */
+bool InitHTTPServer();
+/** Start HTTP server.
+ * This is separate from InitHTTPServer to give users race-condition-free time
+ * to register their handlers between InitHTTPServer and StartHTTPServer.
+ */
+bool StartHTTPServer(boost::thread_group& threadGroup);
+/** Interrupt HTTP server threads */
+void InterruptHTTPServer();
+/** Stop HTTP server */
+void StopHTTPServer();
+
+/** Handler for requests to a certain HTTP path */
+typedef boost::function<void(HTTPRequest* req, const std::string &)> HTTPRequestHandler;
+/** Register handler for prefix.
+ * If multiple handlers match a prefix, the first-registered one will
+ * be invoked.
+ */
+void RegisterHTTPHandler(const std::string &prefix, bool exactMatch, const HTTPRequestHandler &handler);
+/** Unregister handler for prefix */
+void UnregisterHTTPHandler(const std::string &prefix, bool exactMatch);
+
+/** Return evhttp event base. This can be used by submodules to
+ * queue timers or custom events.
+ */
+struct event_base* EventBase();
+
+/** In-flight HTTP request.
+ * Thin C++ wrapper around evhttp_request.
+ */
+class HTTPRequest
+{
+private:
+ struct evhttp_request* req;
+ bool replySent;
+
+public:
+ HTTPRequest(struct evhttp_request* req);
+ ~HTTPRequest();
+
+ enum RequestMethod {
+ UNKNOWN,
+ GET,
+ POST,
+ HEAD,
+ PUT
+ };
+
+ /** Get requested URI.
+ */
+ std::string GetURI();
+
+ /** Get CService (address:ip) for the origin of the http request.
+ */
+ CService GetPeer();
+
+ /** Get request method.
+ */
+ RequestMethod GetRequestMethod();
+
+ /**
+ * Get the request header specified by hdr, or an empty string.
+ * Return an pair (isPresent,string).
+ */
+ std::pair<bool, std::string> GetHeader(const std::string& hdr);
+
+ /**
+ * Read request body.
+ *
+ * @note As this consumes the underlying buffer, call this only once.
+ * Repeated calls will return an empty string.
+ */
+ std::string ReadBody();
+
+ /**
+ * Write output header.
+ *
+ * @note call this before calling WriteErrorReply or Reply.
+ */
+ void WriteHeader(const std::string& hdr, const std::string& value);
+
+ /**
+ * Write HTTP reply.
+ * nStatus is the HTTP status code to send.
+ * strReply is the body of the reply. Keep it empty to send a standard message.
+ *
+ * @note Can be called only once. As this will give the request back to the
+ * main thread, do not call any other HTTPRequest methods after calling this.
+ */
+ void WriteReply(int nStatus, const std::string& strReply = "");
+};
+
+/** Event handler closure.
+ */
+class HTTPClosure
+{
+public:
+ virtual void operator()() = 0;
+ virtual ~HTTPClosure() {}
+};
+
+/** Event class. This can be used either as an cross-thread trigger or as a timer.
+ */
+class HTTPEvent
+{
+public:
+ /** Create a new event.
+ * deleteWhenTriggered deletes this event object after the event is triggered (and the handler called)
+ * handler is the handler to call when the event is triggered.
+ */
+ HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const boost::function<void(void)>& handler);
+ ~HTTPEvent();
+
+ /** Trigger the event. If tv is 0, trigger it immediately. Otherwise trigger it after
+ * the given time has elapsed.
+ */
+ void trigger(struct timeval* tv);
+
+ bool deleteWhenTriggered;
+ boost::function<void(void)> handler;
+private:
+ struct event* ev;
+};
+
+#endif // BITCOIN_HTTPSERVER_H
diff --git a/src/init.cpp b/src/init.cpp
index 4addc663c8..920fc3069e 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -11,9 +11,13 @@
#include "addrman.h"
#include "amount.h"
+#include "chain.h"
+#include "chainparams.h"
#include "checkpoints.h"
#include "compat/sanity.h"
#include "consensus/validation.h"
+#include "httpserver.h"
+#include "httprpc.h"
#include "key.h"
#include "main.h"
#include "miner.h"
@@ -23,15 +27,17 @@
#include "script/standard.h"
#include "scheduler.h"
#include "txdb.h"
+#include "txmempool.h"
#include "ui_interface.h"
#include "util.h"
#include "utilmoneystr.h"
+#include "utilstrencodings.h"
#include "validationinterface.h"
#ifdef ENABLE_WALLET
+#include "wallet/db.h"
#include "wallet/wallet.h"
#include "wallet/walletdb.h"
#endif
-
#include <stdint.h>
#include <stdio.h>
@@ -48,6 +54,10 @@
#include <boost/thread.hpp>
#include <openssl/crypto.h>
+#if ENABLE_ZMQ
+#include "zmq/zmqnotificationinterface.h"
+#endif
+
using namespace std;
#ifdef ENABLE_WALLET
@@ -55,6 +65,10 @@ CWallet* pwalletMain = NULL;
#endif
bool fFeeEstimatesInitialized = false;
+#if ENABLE_ZMQ
+static CZMQNotificationInterface* pzmqNotificationInterface = NULL;
+#endif
+
#ifdef WIN32
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
// accessing block files don't count towards the fd_set size limit
@@ -139,6 +153,15 @@ public:
static CCoinsViewDB *pcoinsdbview = NULL;
static CCoinsViewErrorCatcher *pcoinscatcher = NULL;
+void Interrupt(boost::thread_group& threadGroup)
+{
+ InterruptHTTPServer();
+ InterruptHTTPRPC();
+ InterruptRPC();
+ InterruptREST();
+ threadGroup.interrupt_all();
+}
+
void Shutdown()
{
LogPrintf("%s: In progress...\n", __func__);
@@ -153,7 +176,11 @@ void Shutdown()
/// module was initialized.
RenameThread("bitcoin-shutoff");
mempool.AddTransactionsUpdated(1);
- StopRPCThreads();
+
+ StopHTTPRPC();
+ StopREST();
+ StopRPC();
+ StopHTTPServer();
#ifdef ENABLE_WALLET
if (pwalletMain)
pwalletMain->Flush(false);
@@ -191,6 +218,16 @@ void Shutdown()
if (pwalletMain)
pwalletMain->Flush(true);
#endif
+
+#if ENABLE_ZMQ
+ if (pzmqNotificationInterface) {
+ UnregisterValidationInterface(pzmqNotificationInterface);
+ pzmqNotificationInterface->Shutdown();
+ delete pzmqNotificationInterface;
+ pzmqNotificationInterface = NULL;
+ }
+#endif
+
#ifndef WIN32
try {
boost::filesystem::remove(GetPidFile());
@@ -275,7 +312,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
if (mode == HMM_BITCOIND)
{
-#if !defined(WIN32)
+#ifndef WIN32
strUsage += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands"));
#endif
}
@@ -283,16 +320,18 @@ std::string HelpMessage(HelpMessageMode mode)
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("-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"));
#endif
- strUsage += HelpMessageOpt("-prune=<n>", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. "
+ strUsage += HelpMessageOpt("-prune=<n>", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. "
"Warning: Reverting this setting requires re-downloading the entire blockchain. "
"(default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)"), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current blk000??.dat files on startup"));
-#if !defined(WIN32)
+#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));
@@ -309,7 +348,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-externalip=<ip>", _("Specify your own public address"));
strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0));
strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)"));
- strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125));
+ strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), DEFAULT_MAX_PEER_CONNECTIONS));
strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000));
strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000));
strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy"));
@@ -330,23 +369,24 @@ 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("-whiteconnections=<n>", strprintf(_("Reserve this many inbound connections for whitelisted peers (default: %d)"), 0));
+ strUsage += HelpMessageOpt("-maxuploadtarget=<n>", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), 0));
#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 BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)",
- FormatMoney(CWallet::minTxFee.GetFeePerK())));
- strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())));
+ strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)",
+ CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK())));
+ strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"),
+ CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup"));
strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup"));
strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0));
strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1));
strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET));
- strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"),
- FormatMoney(maxTxFee)));
+ strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"),
+ CURRENCY_UNIT, FormatMoney(maxTxFee)));
strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup"));
strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat"));
strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), true));
@@ -355,6 +395,14 @@ std::string HelpMessage(HelpMessageMode mode)
" " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
#endif
+#if ENABLE_ZMQ
+ strUsage += HelpMessageGroup(_("ZeroMQ notification options:"));
+ strUsage += HelpMessageOpt("-zmqpubhashblock=<address>", _("Enable publish hash block in <address>"));
+ strUsage += HelpMessageOpt("-zmqpubhashtransaction=<address>", _("Enable publish hash transaction in <address>"));
+ strUsage += HelpMessageOpt("-zmqpubrawblock=<address>", _("Enable publish raw block in <address>"));
+ strUsage += HelpMessageOpt("-zmqpubrawtransaction=<address>", _("Enable publish raw transaction in <address>"));
+#endif
+
strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
if (showDebug)
{
@@ -366,8 +414,12 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", "Randomly fuzz 1 of every <n> network messages");
strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", 1));
strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0));
+ strUsage += HelpMessageOpt("-limitancestorcount=<n>", strprintf("Do not accept transactions if number of in-mempool ancestors is <n> or more (default: %u)", DEFAULT_ANCESTOR_LIMIT));
+ strUsage += HelpMessageOpt("-limitancestorsize=<n>", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds <n> kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT));
+ strUsage += HelpMessageOpt("-limitdescendantcount=<n>", strprintf("Do not accept transactions if any ancestor would have <n> or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT));
+ strUsage += HelpMessageOpt("-limitdescendantsize=<n>", strprintf("Do not accept transactions if any ancestor would have more than <n> kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT));
}
- string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net, proxy, prune"; // Don't translate these and qt below
+ string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, mempoolrej, net, proxy, prune, http, libevent"; // Don't translate these and qt below
if (mode == HMM_BITCOIN_QT)
debugCategories += ", qt";
strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
@@ -379,21 +431,22 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1));
if (showDebug)
{
+ 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)", 15));
strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", 1));
strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> entries (default: %u)", 50000));
}
- strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())));
+ strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for relaying (default: %s)"),
+ CURRENCY_UNIT, FormatMoney(::minRelayTxFee.GetFeePerK())));
strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file"));
if (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("-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)
@@ -416,14 +469,11 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332));
strUsage += HelpMessageOpt("-rpcallowip=<ip>", _("Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times"));
- strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4));
- strUsage += HelpMessageOpt("-rpckeepalive", strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1));
-
- strUsage += HelpMessageGroup(_("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
- strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
- strUsage += HelpMessageOpt("-rpcsslcertificatechainfile=<file.cert>", strprintf(_("Server certificate file (default: %s)"), "server.cert"));
- strUsage += HelpMessageOpt("-rpcsslprivatekeyfile=<file.pem>", strprintf(_("Server private key (default: %s)"), "server.pem"));
- strUsage += HelpMessageOpt("-rpcsslciphers=<ciphers>", strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"));
+ strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS));
+ if (showDebug) {
+ strUsage += HelpMessageOpt("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE));
+ strUsage += HelpMessageOpt("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT));
+ }
if (mode == HMM_BITCOIN_QT)
{
@@ -436,6 +486,9 @@ std::string HelpMessage(HelpMessageMode mode)
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;
@@ -592,6 +645,23 @@ bool InitSanityCheck(void)
return true;
}
+bool AppInitServers(boost::thread_group& threadGroup)
+{
+ RPCServer::OnStopped(&OnRPCStopped);
+ RPCServer::OnPreCommand(&OnRPCPreCommand);
+ if (!InitHTTPServer())
+ return false;
+ if (!StartRPC())
+ return false;
+ if (!StartHTTPRPC())
+ return false;
+ if (GetBoolArg("-rest", false) && !StartREST())
+ return false;
+ if (!StartHTTPServer(threadGroup))
+ return false;
+ return true;
+}
+
/** Initialize bitcoin.
* @pre Parameters should be parsed and config file should be read.
*/
@@ -619,17 +689,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD);
PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy");
if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE);
-
- // Initialize Windows Sockets
- WSADATA wsadata;
- int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
- if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2)
- {
- return InitError(strprintf("Error: Winsock library failed to start (WSAStartup returned error %d)", ret));
- }
#endif
-#ifndef WIN32
+ if (!SetupNetworking())
+ return InitError("Error: Initializing networking failed");
+
+#ifndef WIN32
if (GetBoolArg("-sysperms", false)) {
#ifdef ENABLE_WALLET
if (!GetBoolArg("-disablewallet", false))
@@ -654,11 +719,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
sa_hup.sa_flags = 0;
sigaction(SIGHUP, &sa_hup, NULL);
-#if defined (__SVR4) && defined (__sun)
- // ignore SIGPIPE on Solaris
+ // Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
signal(SIGPIPE, SIG_IGN);
#endif
-#endif
// ********************************************************* Step 2: parameter interactions
const CChainParams& chainparams = Params();
@@ -666,8 +729,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Set this early so that parameter interactions go to console
fPrintToConsole = GetBoolArg("-printtoconsole", false);
fLogTimestamps = GetBoolArg("-logtimestamps", true);
+ fLogTimeMicros = GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS);
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")) {
@@ -739,27 +806,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Make sure enough file descriptors are available
int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1);
- int nUserMaxConnections = GetArg("-maxconnections", 125);
+ int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
nMaxConnections = std::max(nUserMaxConnections, 0);
- int nUserWhiteConnections = GetArg("-whiteconnections", 0);
- nWhiteConnections = std::max(nUserWhiteConnections, 0);
-
- if ((mapArgs.count("-whitelist")) || (mapArgs.count("-whitebind"))) {
- if (!(mapArgs.count("-maxconnections"))) {
- // User is using whitelist feature,
- // but did not specify -maxconnections parameter.
- // Silently increase the default to compensate,
- // so that the whitelist connection reservation feature
- // does not inadvertently reduce the default
- // inbound connection capacity of the network.
- nMaxConnections += nWhiteConnections;
- }
- } else {
- // User not using whitelist feature.
- // Silently disable connection reservation,
- // for the same reason as above.
- nWhiteConnections = 0;
- }
// Trim requested connection counts, to fit into system limitations
nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0);
@@ -771,13 +819,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (nMaxConnections < nUserMaxConnections)
InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations."), nUserMaxConnections, nMaxConnections));
- // Connection capacity is prioritized in this order:
- // outbound connections (hardcoded to 8),
- // then whitelisted connections,
- // then non-whitelisted connections get whatever's left (if any).
- if ((nWhiteConnections > 0) && (nWhiteConnections >= (nMaxConnections - 8)))
- InitWarning(strprintf(_("All non-whitelisted incoming connections will be dropped, because -whiteconnections is %d and -maxconnections is only %d."), nWhiteConnections, nMaxConnections));
-
// ********************************************************* Step 3: parameter-to-internal-flags
fDebug = !mapMultiArgs["-debug"].empty();
@@ -804,6 +845,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
fCheckpointsEnabled = GetBoolArg("-checkpoints", true);
+ // -mempoollimit limits
+ int64_t nMempoolSizeLimit = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
+ int64_t nMempoolDescendantSizeLimit = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000;
+ if (nMempoolSizeLimit < 0 || nMempoolSizeLimit < nMempoolDescendantSizeLimit * 40)
+ return InitError(strprintf(_("Error: -maxmempool must be at least %d MB"), GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) / 25));
+
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
if (nScriptCheckThreads <= 0)
@@ -815,7 +862,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
fServer = GetBoolArg("-server", false);
- // block pruning; get the amount of disk space (in MB) to allot for block & undo files
+ // block pruning; get the amount of disk space (in MiB) to allot for block & undo files
int64_t nSignedPruneTarget = GetArg("-prune", 0) * 1024 * 1024;
if (nSignedPruneTarget < 0) {
return InitError(_("Prune cannot be configured with a negative value."));
@@ -823,7 +870,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
nPruneTarget = (uint64_t) nSignedPruneTarget;
if (nPruneTarget) {
if (nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES) {
- return InitError(strprintf(_("Prune configured below the minimum of %d MB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
+ return InitError(strprintf(_("Prune configured below the minimum of %d MiB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
}
LogPrintf("Prune configured to target %uMiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024);
fPruneMode = true;
@@ -908,6 +955,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Option to startup with mocktime set (used for regression testing):
SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op
+ if (GetBoolArg("-peerbloomfilters", true))
+ nLocalServices |= NODE_BLOOM;
+
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
// Initialize elliptic curve code
@@ -941,8 +991,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
#endif
if (GetBoolArg("-shrinkdebugfile", !fDebug))
ShrinkDebugFile();
- LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
- LogPrintf("Bitcoin version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
+
+ if (fPrintToDebugLog)
+ OpenDebugLog();
+
LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
#ifdef ENABLE_WALLET
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
@@ -953,8 +1005,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
LogPrintf("Using data directory %s\n", strDataDir);
LogPrintf("Using config file %s\n", GetConfigFile().string());
LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
- if (nWhiteConnections > 0)
- LogPrintf("Reserving %i of these connections for whitelisted inbound peers\n", nWhiteConnections);
std::ostringstream strErrors;
LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads);
@@ -975,9 +1025,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (fServer)
{
uiInterface.InitMessage.connect(SetRPCWarmupStatus);
- RPCServer::OnStopped(&OnRPCStopped);
- RPCServer::OnPreCommand(&OnRPCPreCommand);
- StartRPCThreads();
+ if (!AppInitServers(threadGroup))
+ return InitError(_("Unable to start HTTP server. See debug log for details."));
}
int64_t nStart;
@@ -997,7 +1046,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (!warningString.empty())
InitWarning(warningString);
if (!errorString.empty())
- return InitError(warningString);
+ return InitError(errorString);
} // (!fDisableWallet)
#endif // ENABLE_WALLET
@@ -1005,6 +1054,20 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
RegisterNodeSignals(GetNodeSignals());
+ // sanitize comments per BIP-0014, format user agent and check total size
+ std::vector<string> uacomments;
+ BOOST_FOREACH(string cmt, mapMultiArgs["-uacomment"])
+ {
+ if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT))
+ return InitError(strprintf("User Agent comment (%s) contains unsafe characters.", cmt));
+ uacomments.push_back(SanitizeString(cmt, SAFE_CHARS_UA_COMMENT));
+ }
+ strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments);
+ if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) {
+ return InitError(strprintf("Total length of network version string %i exceeds maximum of %i characters. Reduce the number and/or size of uacomments.",
+ strSubVersion.size(), MAX_SUBVERSION_LENGTH));
+ }
+
if (mapArgs.count("-onlynet")) {
std::set<enum Network> nets;
BOOST_FOREACH(const std::string& snet, mapMultiArgs["-onlynet"]) {
@@ -1106,6 +1169,18 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
BOOST_FOREACH(const std::string& strDest, mapMultiArgs["-seednode"])
AddOneShot(strDest);
+#if ENABLE_ZMQ
+ pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs);
+
+ if (pzmqNotificationInterface) {
+ pzmqNotificationInterface->Initialize();
+ RegisterValidationInterface(pzmqNotificationInterface);
+ }
+#endif
+ if (mapArgs.count("-maxuploadtarget")) {
+ CNode::SetMaxOutboundTarget(GetArg("-maxuploadtarget", 0)*1024*1024);
+ }
+
// ********************************************************* Step 7: load block chain
fReindex = GetBoolArg("-reindex", false);
@@ -1215,6 +1290,18 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
LogPrintf("Prune: pruned datadir may not have more than %d blocks; -checkblocks=%d may fail\n",
MIN_BLOCKS_TO_KEEP, GetArg("-checkblocks", 288));
}
+
+ {
+ LOCK(cs_main);
+ CBlockIndex* tip = chainActive.Tip();
+ if (tip && tip->nTime > GetAdjustedTime() + 2 * 60 * 60) {
+ strLoadError = _("The block database contains a block which appears to be from the future. "
+ "This may be due to your computer's date and time being set incorrectly. "
+ "Only rebuild the block database if you are sure that your computer's date and time are correct");
+ break;
+ }
+ }
+
if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", 3),
GetArg("-checkblocks", 288))) {
strLoadError = _("Corrupted block database detected");
@@ -1265,15 +1352,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
mempool.ReadFeeEstimates(est_filein);
fFeeEstimatesInitialized = true;
- // if prune mode, unset NODE_NETWORK and prune block files
- if (fPruneMode) {
- LogPrintf("Unsetting NODE_NETWORK on prune mode\n");
- nLocalServices &= ~NODE_NETWORK;
- if (!fReindex) {
- PruneAndFlush();
- }
- }
-
// ********************************************************* Step 8: load wallet
#ifdef ENABLE_WALLET
if (fDisableWallet) {
@@ -1427,7 +1505,21 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
#else // ENABLE_WALLET
LogPrintf("No wallet support compiled in!\n");
#endif // !ENABLE_WALLET
- // ********************************************************* Step 9: import blocks
+
+ // ********************************************************* Step 9: data directory maintenance
+
+ // if pruning, unset the service bit and perform the initial blockstore prune
+ // after any wallet rescanning has taken place.
+ if (fPruneMode) {
+ LogPrintf("Unsetting NODE_NETWORK on prune mode\n");
+ nLocalServices &= ~NODE_NETWORK;
+ if (!fReindex) {
+ uiInterface.InitMessage(_("Pruning blockstore..."));
+ PruneAndFlush();
+ }
+ }
+
+ // ********************************************************* Step 10: import blocks
if (mapArgs.count("-blocknotify"))
uiInterface.NotifyBlockTip.connect(BlockNotifyCallback);
@@ -1451,7 +1543,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
MilliSleep(10);
}
- // ********************************************************* Step 10: start node
+ // ********************************************************* Step 11: start node
if (!CheckDiskSpace())
return false;
@@ -1481,7 +1573,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Generate coins in the background
GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), Params());
- // ********************************************************* Step 11: finished
+ // ********************************************************* Step 12: finished
SetRPCWarmupFinished();
uiInterface.InitMessage(_("Done loading"));
diff --git a/src/init.h b/src/init.h
index dcb2b29360..8cd51b0286 100644
--- a/src/init.h
+++ b/src/init.h
@@ -20,6 +20,8 @@ extern CWallet* pwalletMain;
void StartShutdown();
bool ShutdownRequested();
+/** Interrupt threads */
+void Interrupt(boost::thread_group& threadGroup);
void Shutdown();
bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler);
diff --git a/src/keystore.cpp b/src/keystore.cpp
index 3bae24b7b9..cf49ba83ad 100644
--- a/src/keystore.cpp
+++ b/src/keystore.cpp
@@ -6,23 +6,30 @@
#include "keystore.h"
#include "key.h"
+#include "pubkey.h"
#include "util.h"
#include <boost/foreach.hpp>
-bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
+bool CKeyStore::AddKey(const CKey &key) {
+ return AddKeyPubKey(key, key.GetPubKey());
+}
+
+bool CBasicKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
{
CKey key;
- if (!GetKey(address, key))
+ if (!GetKey(address, key)) {
+ WatchKeyMap::const_iterator it = mapWatchKeys.find(address);
+ if (it != mapWatchKeys.end()) {
+ vchPubKeyOut = it->second;
+ return true;
+ }
return false;
+ }
vchPubKeyOut = key.GetPubKey();
return true;
}
-bool CKeyStore::AddKey(const CKey &key) {
- return AddKeyPubKey(key, key.GetPubKey());
-}
-
bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
{
LOCK(cs_KeyStore);
@@ -58,10 +65,29 @@ bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut)
return false;
}
+static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut)
+{
+ //TODO: Use Solver to extract this?
+ CScript::const_iterator pc = dest.begin();
+ opcodetype opcode;
+ std::vector<unsigned char> vch;
+ if (!dest.GetOp(pc, opcode, vch) || vch.size() < 33 || vch.size() > 65)
+ return false;
+ pubKeyOut = CPubKey(vch);
+ if (!pubKeyOut.IsFullyValid())
+ return false;
+ if (!dest.GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG || dest.GetOp(pc, opcode, vch))
+ return false;
+ return true;
+}
+
bool CBasicKeyStore::AddWatchOnly(const CScript &dest)
{
LOCK(cs_KeyStore);
setWatchOnly.insert(dest);
+ CPubKey pubKey;
+ if (ExtractPubKey(dest, pubKey))
+ mapWatchKeys[pubKey.GetID()] = pubKey;
return true;
}
@@ -69,6 +95,9 @@ bool CBasicKeyStore::RemoveWatchOnly(const CScript &dest)
{
LOCK(cs_KeyStore);
setWatchOnly.erase(dest);
+ CPubKey pubKey;
+ if (ExtractPubKey(dest, pubKey))
+ mapWatchKeys.erase(pubKey.GetID());
return true;
}
diff --git a/src/keystore.h b/src/keystore.h
index 4a4b6d20af..b917bf20b4 100644
--- a/src/keystore.h
+++ b/src/keystore.h
@@ -32,7 +32,7 @@ public:
virtual bool HaveKey(const CKeyID &address) const =0;
virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0;
virtual void GetKeys(std::set<CKeyID> &setAddress) const =0;
- virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
+ virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const =0;
//! Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki
virtual bool AddCScript(const CScript& redeemScript) =0;
@@ -47,6 +47,7 @@ public:
};
typedef std::map<CKeyID, CKey> KeyMap;
+typedef std::map<CKeyID, CPubKey> WatchKeyMap;
typedef std::map<CScriptID, CScript > ScriptMap;
typedef std::set<CScript> WatchOnlySet;
@@ -55,11 +56,13 @@ class CBasicKeyStore : public CKeyStore
{
protected:
KeyMap mapKeys;
+ WatchKeyMap mapWatchKeys;
ScriptMap mapScripts;
WatchOnlySet setWatchOnly;
public:
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
+ bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
bool HaveKey(const CKeyID &address) const
{
bool result;
diff --git a/src/leveldbwrapper.cpp b/src/leveldbwrapper.cpp
deleted file mode 100644
index c353dfa6d9..0000000000
--- a/src/leveldbwrapper.cpp
+++ /dev/null
@@ -1,88 +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::DestroyDB(path.string(), options);
- }
- 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 e8ea549653..5456dfc7c4 100644
--- a/src/limitedmap.h
+++ b/src/limitedmap.h
@@ -27,7 +27,11 @@ protected:
size_type nMaxSize;
public:
- limitedmap(size_type nMaxSizeIn = 0) { nMaxSize = nMaxSizeIn; }
+ limitedmap(size_type nMaxSizeIn)
+ {
+ assert(nMaxSizeIn > 0);
+ nMaxSize = nMaxSizeIn;
+ }
const_iterator begin() const { return map.begin(); }
const_iterator end() const { return map.end(); }
size_type size() const { return map.size(); }
@@ -38,13 +42,12 @@ public:
{
std::pair<iterator, bool> ret = map.insert(x);
if (ret.second) {
- if (nMaxSize && map.size() == nMaxSize) {
+ if (map.size() > nMaxSize) {
map.erase(rmap.begin()->second);
rmap.erase(rmap.begin());
}
rmap.insert(make_pair(x.second, ret.first));
}
- return;
}
void erase(const key_type& k)
{
@@ -81,11 +84,11 @@ public:
size_type max_size() const { return nMaxSize; }
size_type max_size(size_type s)
{
- if (s)
- while (map.size() > s) {
- map.erase(rmap.begin()->second);
- rmap.erase(rmap.begin());
- }
+ assert(s > 0);
+ while (map.size() > s) {
+ map.erase(rmap.begin()->second);
+ rmap.erase(rmap.begin());
+ }
nMaxSize = s;
return nMaxSize;
}
diff --git a/src/main.cpp b/src/main.cpp
index fb90d7578c..e038fe3663 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -13,17 +13,25 @@
#include "checkqueue.h"
#include "consensus/consensus.h"
#include "consensus/validation.h"
+#include "hash.h"
#include "init.h"
#include "merkleblock.h"
#include "net.h"
#include "policy/policy.h"
#include "pow.h"
+#include "primitives/block.h"
+#include "primitives/transaction.h"
+#include "script/script.h"
+#include "script/sigcache.h"
+#include "script/standard.h"
+#include "tinyformat.h"
#include "txdb.h"
#include "txmempool.h"
#include "ui_interface.h"
#include "undo.h"
#include "util.h"
#include "utilmoneystr.h"
+#include "utilstrencodings.h"
#include "validationinterface.h"
#include <sstream>
@@ -75,9 +83,9 @@ struct COrphanTx {
CTransaction tx;
NodeId fromPeer;
};
-map<uint256, COrphanTx> mapOrphanTransactions;
-map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
-void EraseOrphansFor(NodeId peer);
+map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);;
+map<uint256, set<uint256> > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);;
+void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/**
* Returns true if there are nRequired or more blocks of minVersion or above
@@ -154,6 +162,29 @@ namespace {
*/
map<uint256, NodeId> mapBlockSource;
+ /**
+ * Filter for transactions that were recently rejected by
+ * AcceptToMemoryPool. These are not rerequested until the chain tip
+ * changes, at which point the entire filter is reset. Protected by
+ * cs_main.
+ *
+ * Without this filter we'd be re-requesting txs from each of our peers,
+ * increasing bandwidth consumption considerably. For instance, with 100
+ * peers, half of which relay a tx we don't accept, that might be a 50x
+ * bandwidth increase. A flooding attacker attempting to roll-over the
+ * filter using minimum-sized, 60byte, transactions might manage to send
+ * 1000/sec if we have fast peers, so we pick 120,000 to give our peers a
+ * two minute window to send invs to us.
+ *
+ * Decreasing the false positive rate is fairly cheap, so we pick one in a
+ * million to make it highly unlikely for users to have issues with this
+ * filter.
+ *
+ * Memory used: 1.7MB
+ */
+ boost::scoped_ptr<CRollingBloomFilter> recentRejects;
+ uint256 hashRecentRejectsChainTip;
+
/** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
struct QueuedBlock {
uint256 hash;
@@ -527,7 +558,7 @@ CBlockTreeDB *pblocktree = NULL;
// mapOrphanTransactions
//
-bool AddOrphanTx(const CTransaction& tx, NodeId peer)
+bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
uint256 hash = tx.GetHash();
if (mapOrphanTransactions.count(hash))
@@ -557,7 +588,7 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer)
return true;
}
-void static EraseOrphanTx(uint256 hash)
+void static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
if (it == mapOrphanTransactions.end())
@@ -591,7 +622,7 @@ void EraseOrphansFor(NodeId peer)
}
-unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
+unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
unsigned int nEvicted = 0;
while (mapOrphanTransactions.size() > nMaxOrphans)
@@ -619,10 +650,35 @@ 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;
+
+ // Timestamps on the other hand don't get any special treatment,
+ // because we can't know what timestamp the next block will have,
+ // and there aren't timestamp applications where it matters.
+ // However this changes once median past time-locks are enforced:
+ const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST)
+ ? chainActive.Tip()->GetMedianTimePast()
+ : GetAdjustedTime();
+
+ return IsFinalTx(tx, nBlockHeight, nBlockTime);
}
unsigned int GetLegacySigOpCount(const CTransaction& tx)
@@ -665,30 +721,24 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
{
// Basic checks that don't depend on any context
if (tx.vin.empty())
- return state.DoS(10, error("CheckTransaction(): vin empty"),
- REJECT_INVALID, "bad-txns-vin-empty");
+ return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty");
if (tx.vout.empty())
- return state.DoS(10, error("CheckTransaction(): vout empty"),
- REJECT_INVALID, "bad-txns-vout-empty");
+ return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty");
// Size limits
if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
- return state.DoS(100, error("CheckTransaction(): size limits failed"),
- REJECT_INVALID, "bad-txns-oversize");
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize");
// Check for negative or overflow output values
CAmount nValueOut = 0;
BOOST_FOREACH(const CTxOut& txout, tx.vout)
{
if (txout.nValue < 0)
- return state.DoS(100, error("CheckTransaction(): txout.nValue negative"),
- REJECT_INVALID, "bad-txns-vout-negative");
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-negative");
if (txout.nValue > MAX_MONEY)
- return state.DoS(100, error("CheckTransaction(): txout.nValue too high"),
- REJECT_INVALID, "bad-txns-vout-toolarge");
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-toolarge");
nValueOut += txout.nValue;
if (!MoneyRange(nValueOut))
- return state.DoS(100, error("CheckTransaction(): txout total out of range"),
- REJECT_INVALID, "bad-txns-txouttotal-toolarge");
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-txouttotal-toolarge");
}
// Check for duplicate inputs
@@ -696,39 +746,33 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
if (vInOutPoints.count(txin.prevout))
- return state.DoS(100, error("CheckTransaction(): duplicate inputs"),
- REJECT_INVALID, "bad-txns-inputs-duplicate");
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-duplicate");
vInOutPoints.insert(txin.prevout);
}
if (tx.IsCoinBase())
{
if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
- return state.DoS(100, error("CheckTransaction(): coinbase script size"),
- REJECT_INVALID, "bad-cb-length");
+ return state.DoS(100, false, REJECT_INVALID, "bad-cb-length");
}
else
{
BOOST_FOREACH(const CTxIn& txin, tx.vin)
if (txin.prevout.IsNull())
- return state.DoS(10, error("CheckTransaction(): prevout is null"),
- REJECT_INVALID, "bad-txns-prevout-null");
+ return state.DoS(10, false, REJECT_INVALID, "bad-txns-prevout-null");
}
return true;
}
-CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
+CAmount GetMinRelayFee(const CTransaction& tx, const CTxMemPool& pool, 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;
- }
+ uint256 hash = tx.GetHash();
+ double dPriorityDelta = 0;
+ CAmount nFeeDelta = 0;
+ pool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
+ if (dPriorityDelta > 0 || nFeeDelta > 0)
+ return 0;
CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes);
@@ -747,40 +791,44 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF
return nMinFee;
}
+/** Convert CValidationState to a human-readable message for logging */
+static std::string FormatStateMessage(const CValidationState &state)
+{
+ return strprintf("%s%s (code %i)",
+ state.GetRejectReason(),
+ state.GetDebugMessage().empty() ? "" : ", "+state.GetDebugMessage(),
+ state.GetRejectCode());
+}
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
- bool* pfMissingInputs, bool fRejectAbsurdFee)
+ bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee)
{
AssertLockHeld(cs_main);
if (pfMissingInputs)
*pfMissingInputs = false;
if (!CheckTransaction(tx, state))
- return error("AcceptToMemoryPool: CheckTransaction failed");
+ return false;
// Coinbase is only valid in a block, not as a loose transaction
if (tx.IsCoinBase())
- return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),
- REJECT_INVALID, "coinbase");
+ return state.DoS(100, false, REJECT_INVALID, "coinbase");
// Rather not work on nonstandard transactions (unless -testnet/-regtest)
string reason;
if (fRequireStandard && !IsStandardTx(tx, reason))
- return state.DoS(0,
- error("AcceptToMemoryPool: nonstandard transaction: %s", reason),
- REJECT_NONSTANDARD, reason);
+ return state.DoS(0, false, REJECT_NONSTANDARD, reason);
// Only accept nLockTime-using transactions that can be mined in the next
// block; we don't want our mempool filled up with transactions that can't
// be mined yet.
- if (!CheckFinalTx(tx))
- return state.DoS(0, error("AcceptToMemoryPool: non-final"),
- REJECT_NONSTANDARD, "non-final");
+ if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
+ return state.DoS(0, false, REJECT_NONSTANDARD, "non-final");
// is it already in the memory pool?
uint256 hash = tx.GetHash();
if (pool.exists(hash))
- return false;
+ return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-in-mempool");
// Check for conflicts with in-memory transactions
{
@@ -791,7 +839,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
if (pool.mapNextTx.count(outpoint))
{
// Disable replacement feature for now
- return false;
+ return state.Invalid(false, REJECT_CONFLICT, "txn-mempool-conflict");
}
}
}
@@ -808,7 +856,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// do we already have it?
if (view.HaveCoins(hash))
- return false;
+ return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-known");
// do all inputs exist?
// Note that this does not check for the presence of actual outputs (see the next check for that),
@@ -817,14 +865,13 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
if (!view.HaveCoins(txin.prevout.hash)) {
if (pfMissingInputs)
*pfMissingInputs = true;
- return false;
+ return false; // fMissingInputs and !state.IsInvalid() is used to detect this condition, don't set state.Invalid()
}
}
// are the actual inputs available?
if (!view.HaveInputs(tx))
- return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),
- REJECT_DUPLICATE, "bad-txns-inputs-spent");
+ return state.Invalid(false, REJECT_DUPLICATE, "bad-txns-inputs-spent");
// Bring the best block into scope
view.GetBestBlock();
@@ -837,7 +884,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Check for non-standard pay-to-script-hash in inputs
if (fRequireStandard && !AreInputsStandard(tx, view))
- return error("AcceptToMemoryPool: nonstandard transaction input");
+ 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
@@ -847,27 +894,27 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
unsigned int nSigOps = GetLegacySigOpCount(tx);
nSigOps += GetP2SHSigOpCount(tx, view);
if (nSigOps > MAX_STANDARD_TX_SIGOPS)
- return state.DoS(0,
- error("AcceptToMemoryPool: too many sigops %s, %d > %d",
- hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS),
- REJECT_NONSTANDARD, "bad-txns-too-many-sigops");
+ return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false,
+ strprintf("%d > %d", nSigOps, MAX_STANDARD_TX_SIGOPS));
CAmount nValueOut = tx.GetValueOut();
CAmount nFees = nValueIn-nValueOut;
double dPriority = view.GetPriority(tx, chainActive.Height());
- CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx));
+ CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx));
unsigned int nSize = entry.GetTxSize();
// Don't accept it if it can't get into a block
- CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
+ CAmount txMinFee = GetMinRelayFee(tx, pool, nSize, true);
if (fLimitFree && nFees < txMinFee)
- return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",
- hash.ToString(), nFees, txMinFee),
- REJECT_INSUFFICIENTFEE, "insufficient fee");
-
- // 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))) {
+ return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false,
+ strprintf("%d < %d", nFees, txMinFee));
+
+ CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize);
+ if (mempoolRejectFee > 0 && nFees < mempoolRejectFee) {
+ return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee));
+ } else if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, 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");
}
@@ -889,23 +936,31 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// -limitfreerelay unit is thousand-bytes-per-minute
// At default rate it would take over a month to fill 1GB
if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
- return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"),
- REJECT_INSUFFICIENTFEE, "rate limited free transaction");
+ return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "rate limited free transaction");
LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
dFreeCount += nSize;
}
if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000)
- return error("AcceptToMemoryPool: absurdly high fees %s, %d > %d",
- hash.ToString(),
- nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
+ return state.Invalid(false,
+ REJECT_HIGHFEE, "absurdly-high-fee",
+ strprintf("%d > %d", nFees, ::minRelayTxFee.GetFee(nSize) * 10000));
+
+ // Calculate in-mempool ancestors, up to a limit.
+ CTxMemPool::setEntries setAncestors;
+ size_t nLimitAncestors = GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
+ size_t nLimitAncestorSize = GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000;
+ size_t nLimitDescendants = GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
+ size_t nLimitDescendantSize = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000;
+ std::string errString;
+ if (!pool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) {
+ return state.DoS(0, false, REJECT_NONSTANDARD, "too-long-mempool-chain", false, errString);
+ }
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true))
- {
- return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString());
- }
+ return false;
// Check again against just the consensus-critical mandatory script
// verification flags, in case of bugs in the standard flags that cause
@@ -918,11 +973,23 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// can be exploited as a DoS attack.
if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
{
- return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
+ return error("%s: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s, %s",
+ __func__, hash.ToString(), FormatStateMessage(state));
}
// Store transaction in memory
- pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
+ pool.addUnchecked(hash, entry, setAncestors, !IsInitialBlockDownload());
+
+ // trim mempool and check if tx was trimmed
+ if (!fOverrideMempoolLimit) {
+ int expired = pool.Expire(GetTime() - GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
+ if (expired != 0)
+ LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired);
+
+ pool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
+ if (!pool.exists(tx.GetHash()))
+ return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool full");
+ }
}
SyncWithWallets(tx, NULL);
@@ -934,47 +1001,45 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
{
CBlockIndex *pindexSlow = NULL;
+
+ LOCK(cs_main);
+
+ if (mempool.lookup(hash, txOut))
{
- LOCK(cs_main);
- {
- if (mempool.lookup(hash, txOut))
- {
- return true;
- }
- }
+ return true;
+ }
- if (fTxIndex) {
- CDiskTxPos postx;
- if (pblocktree->ReadTxIndex(hash, postx)) {
- CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
- if (file.IsNull())
- return error("%s: OpenBlockFile failed", __func__);
- CBlockHeader header;
- try {
- file >> header;
- fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
- file >> txOut;
- } catch (const std::exception& e) {
- return error("%s: Deserialize or I/O error - %s", __func__, e.what());
- }
- hashBlock = header.GetHash();
- if (txOut.GetHash() != hash)
- return error("%s: txid mismatch", __func__);
- return true;
+ if (fTxIndex) {
+ CDiskTxPos postx;
+ if (pblocktree->ReadTxIndex(hash, postx)) {
+ CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
+ if (file.IsNull())
+ return error("%s: OpenBlockFile failed", __func__);
+ CBlockHeader header;
+ try {
+ file >> header;
+ fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
+ file >> txOut;
+ } catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
+ hashBlock = header.GetHash();
+ if (txOut.GetHash() != hash)
+ return error("%s: txid mismatch", __func__);
+ return true;
}
+ }
- if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
- int nHeight = -1;
- {
- CCoinsViewCache &view = *pcoinsTip;
- const CCoins* coins = view.AccessCoins(hash);
- if (coins)
- nHeight = coins->nHeight;
- }
- if (nHeight > 0)
- pindexSlow = chainActive[nHeight];
+ if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
+ int nHeight = -1;
+ {
+ CCoinsViewCache &view = *pcoinsTip;
+ const CCoins* coins = view.AccessCoins(hash);
+ if (coins)
+ nHeight = coins->nHeight;
}
+ if (nHeight > 0)
+ pindexSlow = chainActive[nHeight];
}
if (pindexSlow) {
@@ -1003,7 +1068,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
// CBlock and CBlockIndex
//
-bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
+bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
{
// Open history file to append
CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
@@ -1083,7 +1148,7 @@ bool IsInitialBlockDownload()
if (lockIBDState)
return false;
bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 ||
- pindexBestHeader->GetBlockTime() < GetTime() - 24 * 60 * 60);
+ pindexBestHeader->GetBlockTime() < GetTime() - chainParams.MaxTipAge());
if (!state)
lockIBDState = true;
return state;
@@ -1196,9 +1261,11 @@ void static InvalidChainFound(CBlockIndex* pindexNew)
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight,
log(pindexNew->nChainWork.getdouble())/log(2.0), DateTimeStrFormat("%Y-%m-%d %H:%M:%S",
pindexNew->GetBlockTime()));
+ CBlockIndex *tip = chainActive.Tip();
+ assert (tip);
LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", __func__,
- chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0),
- DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()));
+ tip->GetBlockHash().ToString(), chainActive.Height(), log(tip->nChainWork.getdouble())/log(2.0),
+ DateTimeStrFormat("%Y-%m-%d %H:%M:%S", tip->GetBlockTime()));
CheckForkWarningConditions();
}
@@ -1207,7 +1274,8 @@ void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state
if (state.IsInvalid(nDoS)) {
std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
if (it != mapBlockSource.end() && State(it->second)) {
- CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
+ assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
+ CBlockReject reject = {(unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
State(it->second)->rejects.push_back(reject);
if (nDoS > 0)
Misbehaving(it->second, nDoS);
@@ -1257,7 +1325,7 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
bool CScriptCheck::operator()() {
const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) {
- return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
+ return false;
}
return true;
}
@@ -1275,7 +1343,7 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins
// This doesn't trigger the DoS code on purpose; if it did, it would make it easier
// for an attacker to attempt to split the network.
if (!inputs.HaveInputs(tx))
- return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
+ return state.Invalid(false, 0, "", "Inputs unavailable");
CAmount nValueIn = 0;
CAmount nFees = 0;
@@ -1288,33 +1356,29 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins
// If prev is coinbase, check that it's matured
if (coins->IsCoinBase()) {
if (nSpendHeight - coins->nHeight < COINBASE_MATURITY)
- return state.Invalid(
- error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
- REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
+ return state.Invalid(false,
+ REJECT_INVALID, "bad-txns-premature-spend-of-coinbase",
+ strprintf("tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight));
}
// Check for negative or overflow input values
nValueIn += coins->vout[prevout.n].nValue;
if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
- return state.DoS(100, error("CheckInputs(): txin values out of range"),
- REJECT_INVALID, "bad-txns-inputvalues-outofrange");
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputvalues-outofrange");
}
if (nValueIn < tx.GetValueOut())
- return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s)",
- tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())),
- REJECT_INVALID, "bad-txns-in-belowout");
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", false,
+ strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())));
// Tally transaction fees
CAmount nTxFee = nValueIn - tx.GetValueOut();
if (nTxFee < 0)
- return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()),
- REJECT_INVALID, "bad-txns-fee-negative");
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-negative");
nFees += nTxFee;
if (!MoneyRange(nFees))
- return state.DoS(100, error("CheckInputs(): nFees out of range"),
- REJECT_INVALID, "bad-txns-fee-outofrange");
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-outofrange");
return true;
}
}// namespace Consensus
@@ -1438,7 +1502,7 @@ bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
strMiscWarning = strMessage;
LogPrintf("*** %s\n", strMessage);
uiInterface.ThreadSafeMessageBox(
- userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage,
+ userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage,
"", CClientUIInterface::MSG_ERROR);
StartShutdown();
return false;
@@ -1485,7 +1549,7 @@ static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const CO
return fClean;
}
-bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
+bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
{
assert(pindex->GetBlockHash() == view.GetBestBlock());
@@ -1712,11 +1776,18 @@ 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;
+ }
+
CBlockUndo blockundo;
CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
@@ -1760,7 +1831,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
std::vector<CScriptCheck> vChecks;
if (!CheckInputs(tx, state, view, fScriptChecks, flags, false, nScriptCheckThreads ? &vChecks : NULL))
- return false;
+ return error("ConnectBlock(): CheckInputs on %s failed with %s",
+ tx.GetHash().ToString(), FormatStateMessage(state));
control.Add(vChecks);
}
@@ -1852,7 +1924,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
std::set<int> setFilesToPrune;
bool fFlushForPrune = false;
try {
- if (fPruneMode && fCheckForPruning) {
+ if (fPruneMode && fCheckForPruning && !fReindex) {
FindFilesToPrune(setFilesToPrune);
fCheckForPruning = false;
if (!setFilesToPrune.empty()) {
@@ -1991,7 +2063,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
}
}
-/** Disconnect chainActive's tip. */
+/** Disconnect chainActive's tip. You want to manually re-limit mempool size after this */
bool static DisconnectTip(CValidationState &state) {
CBlockIndex *pindexDelete = chainActive.Tip();
assert(pindexDelete);
@@ -2013,13 +2085,23 @@ bool static DisconnectTip(CValidationState &state) {
if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
return false;
// Resurrect mempool transactions from the disconnected block.
+ std::vector<uint256> vHashUpdate;
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
// ignore validation errors in resurrected transactions
list<CTransaction> removed;
CValidationState stateDummy;
- if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
+ if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL, true)) {
mempool.remove(tx, removed, true);
+ } else if (mempool.exists(tx.GetHash())) {
+ vHashUpdate.push_back(tx.GetHash());
+ }
}
+ // AcceptToMemoryPool/addUnchecked all assume that new mempool entries have
+ // no in-mempool children, which is generally not true when adding
+ // previously-confirmed transactions back to the mempool.
+ // UpdateTransactionsFromBlock finds descendants of any transactions in this
+ // block that were added back and cleans up the mempool state.
+ mempool.UpdateTransactionsFromBlock(vHashUpdate);
mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight);
mempool.check(pcoinsTip);
// Update chainActive and related variables.
@@ -2042,7 +2124,7 @@ static int64_t nTimePostConnect = 0;
* Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
* corresponding to pindexNew, to bypass loading it again from disk.
*/
-bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
+bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, const CBlock *pblock) {
assert(pindexNew->pprev == chainActive.Tip());
mempool.check(pcoinsTip);
// Read block from disk.
@@ -2174,16 +2256,18 @@ static void PruneBlockIndexCandidates() {
* Try to make some progress towards making pindexMostWork the active block.
* pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
*/
-static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
+static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, const CBlock *pblock) {
AssertLockHeld(cs_main);
bool fInvalidFound = false;
const CBlockIndex *pindexOldTip = chainActive.Tip();
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))
return false;
+ fBlocksDisconnected = true;
}
// Build list of new blocks to connect.
@@ -2229,6 +2313,9 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
}
}
+ if (fBlocksDisconnected)
+ mempool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
+
// Callbacks/notifications for a new best chain.
if (fInvalidFound)
CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
@@ -2243,7 +2330,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
* or an activated best chain. pblock is either NULL or a pointer to a block
* that is already loaded (to avoid loading it again from disk).
*/
-bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
+bool ActivateBestChain(CValidationState &state, const CBlock *pblock) {
CBlockIndex *pindexNewTip = NULL;
CBlockIndex *pindexMostWork = NULL;
const CChainParams& chainParams = Params();
@@ -2274,15 +2361,14 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
int nBlockEstimate = 0;
if (fCheckpointsEnabled)
nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints());
- // Don't relay blocks if pruning -- could cause a peer to try to download, resulting
- // in a stalled download if the block file is pruned before the request.
- if (nLocalServices & NODE_NETWORK) {
+ {
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
}
// Notify external listeners about the new tip.
+ GetMainSignals().UpdatedBlockTip(pindexNewTip);
uiInterface.NotifyBlockTip(hashNewTip);
}
} while(pindexMostWork != chainActive.Tip());
@@ -2316,6 +2402,8 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
}
}
+ mempool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
+
// The resulting new best tip may not be in setBlockIndexCandidates anymore, so
// add it again.
BlockMap::iterator it = mapBlockIndex.begin();
@@ -2545,6 +2633,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
{
// These are checks that are independent of context.
+ if (block.fChecked)
+ return true;
+
// Check that the header is valid (particularly PoW). This is mostly
// redundant with the call in AcceptBlockHeader.
if (!CheckBlockHeader(block, state, fCheckPOW))
@@ -2553,7 +2644,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
// Check the merkle root.
if (fCheckMerkleRoot) {
bool mutated;
- uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
+ uint256 hashMerkleRoot2 = block.ComputeMerkleRoot(&mutated);
if (block.hashMerkleRoot != hashMerkleRoot2)
return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"),
REJECT_INVALID, "bad-txnmrklroot", true);
@@ -2587,7 +2678,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
// Check transactions
BOOST_FOREACH(const CTransaction& tx, block.vtx)
if (!CheckTransaction(tx, state))
- return error("CheckBlock(): CheckTransaction failed");
+ return error("CheckBlock(): CheckTransaction of %s failed with %s",
+ tx.GetHash().ToString(),
+ FormatStateMessage(state));
unsigned int nSigOps = 0;
BOOST_FOREACH(const CTransaction& tx, block.vtx)
@@ -2598,6 +2691,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"),
REJECT_INVALID, "bad-blk-sigops", true);
+ if (fCheckPOW && fCheckMerkleRoot)
+ block.fChecked = true;
+
return true;
}
@@ -2638,6 +2734,11 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
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;
}
@@ -2647,10 +2748,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):
@@ -2714,7 +2820,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
return true;
}
-bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
+bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
{
const CChainParams& chainparams = Params();
AssertLockHeld(cs_main);
@@ -2726,9 +2832,15 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
// Try to process all requested blocks that we don't have, but only
// process an unrequested block if it's new and has enough work to
- // advance our tip.
+ // advance our tip, and isn't too many blocks ahead.
bool fAlreadyHave = pindex->nStatus & BLOCK_HAVE_DATA;
bool fHasMoreWork = (chainActive.Tip() ? pindex->nChainWork > chainActive.Tip()->nChainWork : true);
+ // Blocks that are too out-of-order needlessly limit the effectiveness of
+ // pruning, because pruning will not delete block files that contain any
+ // blocks which are too close in height to the tip. Apply this test
+ // regardless of whether pruning is enabled; it should generally be safe to
+ // not process unrequested blocks.
+ bool fTooFarAhead = (pindex->nHeight > int(chainActive.Height() + MIN_BLOCKS_TO_KEEP));
// TODO: deal better with return value and error conditions for duplicate
// and unrequested blocks.
@@ -2736,6 +2848,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
if (!fRequested) { // If we didn't ask for it:
if (pindex->nTx != 0) return true; // This is a previously-processed block that was pruned
if (!fHasMoreWork) return true; // Don't process less-work chains
+ if (fTooFarAhead) return true; // Block height is too high
}
if ((!CheckBlock(block, state)) || !ContextualCheckBlock(block, state, pindex->pprev)) {
@@ -2784,7 +2897,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned
}
-bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
+bool ProcessNewBlock(CValidationState &state, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp)
{
// Preliminary checks
bool checked = CheckBlock(*pblock, state);
@@ -3233,6 +3346,7 @@ void UnloadBlockIndex()
setDirtyBlockIndex.clear();
setDirtyFileInfo.clear();
mapNodeState.clear();
+ recentRejects.reset(NULL);
BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
delete entry.second;
@@ -3253,6 +3367,10 @@ bool LoadBlockIndex()
bool InitBlockIndex() {
const CChainParams& chainparams = Params();
LOCK(cs_main);
+
+ // Initialize global variables that cannot be constructed at startup.
+ recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
+
// Check whether we're already initialized
if (chainActive.Genesis() != NULL)
return true;
@@ -3383,7 +3501,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
}
}
} catch (const std::exception& e) {
- LogPrintf("%s: Deserialize or I/O error - %s", __func__, e.what());
+ LogPrintf("%s: Deserialize or I/O error - %s\n", __func__, e.what());
}
}
} catch (const std::runtime_error& e) {
@@ -3649,16 +3767,27 @@ std::string GetWarnings(const std::string& strFor)
//
-bool static AlreadyHave(const CInv& inv)
+bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
switch (inv.type)
{
case MSG_TX:
{
- bool txInMap = false;
- txInMap = mempool.exists(inv.hash);
- return txInMap || mapOrphanTransactions.count(inv.hash) ||
- pcoinsTip->HaveCoins(inv.hash);
+ assert(recentRejects);
+ if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip)
+ {
+ // If the chain tip has changed previously rejected transactions
+ // might be now valid, e.g. due to a nLockTime'd tx becoming valid,
+ // or a double-spend. Reset the rejects filter and give those
+ // txs a second chance.
+ hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash();
+ recentRejects->reset();
+ }
+
+ return recentRejects->contains(inv.hash) ||
+ mempool.exists(inv.hash) ||
+ mapOrphanTransactions.count(inv.hash) ||
+ pcoinsTip->HaveCoins(inv.hash);
}
case MSG_BLOCK:
return mapBlockIndex.count(inv.hash);
@@ -3706,6 +3835,16 @@ void static ProcessGetData(CNode* pfrom)
}
}
}
+ // disconnect node in case we have reached the outbound limit for serving historical blocks
+ 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) )
+ {
+ 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))
@@ -3844,7 +3983,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (!vRecv.empty())
vRecv >> addrFrom >> nNonce;
if (!vRecv.empty()) {
- vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
+ vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH);
pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
}
if (!vRecv.empty())
@@ -4131,6 +4270,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
LogPrint("net", " getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
break;
}
+ // If pruning, don't inv blocks unless we have on disk and are likely to still have
+ // for some reasonable time window (1 hour) that block relay might require.
+ const int nPrunedBlocksLikelyToHave = MIN_BLOCKS_TO_KEEP - 3600 / chainparams.GetConsensus().nPowTargetSpacing;
+ if (fPruneMode && (!(pindex->nStatus & BLOCK_HAVE_DATA) || pindex->nHeight <= chainActive.Tip()->nHeight - nPrunedBlocksLikelyToHave))
+ {
+ LogPrint("net", " getblocks stopping, pruned or too old block at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ break;
+ }
pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
if (--nLimit <= 0)
{
@@ -4203,16 +4350,20 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
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))
{
mempool.check(pcoinsTip);
RelayTransaction(tx);
vWorkQueue.push_back(inv.hash);
- LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n",
- pfrom->id, pfrom->cleanSubVer,
+ LogPrint("mempool", "AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u txn, %u kB)\n",
+ pfrom->id,
tx.GetHash().ToString(),
- mempool.mapTx.size());
+ mempool.size(), mempool.DynamicMemoryUsage() / 1000);
// Recursively process any orphan transactions that depended on this one
set<NodeId> setMisbehaving;
@@ -4258,6 +4409,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// Probably non-standard or insufficient fee/priority
LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString());
vEraseQueue.push_back(orphanHash);
+ assert(recentRejects);
+ recentRejects->insert(orphanHash);
}
mempool.check(pcoinsTip);
}
@@ -4275,20 +4428,30 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
if (nEvicted > 0)
LogPrint("mempool", "mapOrphan overflow, removed %u tx\n", nEvicted);
- } else if (pfrom->fWhitelisted) {
- // Always relay transactions received from whitelisted peers, even
- // if they are already in the mempool (allowing the node to function
- // as a gateway for nodes hidden behind it).
- RelayTransaction(tx);
+ } else {
+ assert(recentRejects);
+ recentRejects->insert(tx.GetHash());
+
+ if (pfrom->fWhitelisted) {
+ // Always relay transactions received from whitelisted peers, even
+ // if they were rejected from the mempool, allowing the node to
+ // function as a gateway for nodes hidden behind it.
+ //
+ // FIXME: This includes invalid transactions, which means a
+ // whitelisted peer could get us banned! We may want to change
+ // that.
+ RelayTransaction(tx);
+ }
}
int nDoS = 0;
if (state.IsInvalid(nDoS))
{
- LogPrint("mempool", "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
- pfrom->id, pfrom->cleanSubVer,
- state.GetRejectReason());
- pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
- state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
+ LogPrint("mempoolrej", "%s from peer=%d was not accepted: %s\n", tx.GetHash().ToString(),
+ pfrom->id,
+ FormatStateMessage(state));
+ if (state.GetRejectCode() < REJECT_INTERNAL) // Never send AcceptToMemoryPool's internal codes over P2P
+ pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
+ state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
if (nDoS > 0)
Misbehaving(pfrom->GetId(), nDoS);
}
@@ -4360,10 +4523,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
pfrom->AddInventoryKnown(inv);
CValidationState state;
- // Process all blocks from whitelisted peers, even if not requested.
- ProcessNewBlock(state, pfrom, &block, pfrom->fWhitelisted, NULL);
+ // Process all blocks from whitelisted peers, even if not requested,
+ // unless we're still syncing with the network.
+ // Such an unrequested block may still be processed, subject to the
+ // conditions in AcceptBlock().
+ bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
+ ProcessNewBlock(state, pfrom, &block, forceProcessing, NULL);
int nDoS;
if (state.IsInvalid(nDoS)) {
+ assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
if (nDoS > 0) {
@@ -4456,6 +4624,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (pingUsecTime > 0) {
// Successful ping time measurement, replace previous
pfrom->nPingUsecTime = pingUsecTime;
+ pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime, pingUsecTime);
} else {
// This should never happen
sProblem = "Timing mishap";
@@ -4479,9 +4648,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
if (!(sProblem.empty())) {
- LogPrint("net", "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
+ LogPrint("net", "pong peer=%d: %s, %x expected, %x received, %u bytes\n",
pfrom->id,
- pfrom->cleanSubVer,
sProblem,
pfrom->nPingNonceSent,
nonce,
@@ -4524,6 +4692,21 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
+ else if (!(nLocalServices & NODE_BLOOM) &&
+ (strCommand == "filterload" ||
+ strCommand == "filteradd" ||
+ strCommand == "filterclear") &&
+ //TODO: Remove this line after reasonable network upgrade
+ pfrom->nVersion >= NO_BLOOM_VERSION)
+ {
+ if (pfrom->nVersion >= NO_BLOOM_VERSION)
+ Misbehaving(pfrom->GetId(), 100);
+ //TODO: Enable this after reasonable network upgrade
+ //else
+ // pfrom->fDisconnect = true;
+ }
+
+
else if (strCommand == "filterload")
{
CBloomFilter filter;
@@ -4778,7 +4961,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
{
// Periodically clear addrKnown to allow refresh broadcasts
if (nLastRebroadcast)
- pnode->addrKnown.clear();
+ pnode->addrKnown.reset();
// Rebroadcast our address
AdvertizeLocal(pnode);
@@ -4842,7 +5025,16 @@ 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());
}
diff --git a/src/main.h b/src/main.h
index ce18bd709f..65732d770f 100644
--- a/src/main.h
+++ b/src/main.h
@@ -12,18 +12,10 @@
#include "amount.h"
#include "chain.h"
-#include "chainparams.h"
#include "coins.h"
#include "net.h"
-#include "primitives/block.h"
-#include "primitives/transaction.h"
-#include "script/script.h"
-#include "script/sigcache.h"
-#include "script/standard.h"
+#include "script/script_error.h"
#include "sync.h"
-#include "tinyformat.h"
-#include "txmempool.h"
-#include "uint256.h"
#include <algorithm>
#include <exception>
@@ -41,6 +33,7 @@ class CBlockTreeDB;
class CBloomFilter;
class CInv;
class CScriptCheck;
+class CTxMemPool;
class CValidationInterface;
class CValidationState;
@@ -50,6 +43,18 @@ struct CNodeStateStats;
static const bool DEFAULT_ALERTS = true;
/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */
static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100;
+/** Default for -limitancestorcount, max number of in-mempool ancestors */
+static const unsigned int DEFAULT_ANCESTOR_LIMIT = 100;
+/** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */
+static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 900;
+/** Default for -limitdescendantcount, max number of in-mempool descendants */
+static const unsigned int DEFAULT_DESCENDANT_LIMIT = 1000;
+/** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */
+static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 2500;
+/** Default for -maxmempool, maximum megabytes of mempool memory usage */
+static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300;
+/** 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) */
@@ -149,7 +154,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, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp);
+bool ProcessNewBlock(CValidationState &state, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp);
/** Check whether enough disk space is available for an incoming block */
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
/** Open a block file (blk?????.dat) */
@@ -186,7 +191,7 @@ std::string GetWarnings(const std::string& strFor);
/** Retrieve a transaction (from memory pool, or from disk, if possible) */
bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false);
/** Find the best known block, and make it the tip of the block chain */
-bool ActivateBestChain(CValidationState &state, CBlock *pblock = NULL);
+bool ActivateBestChain(CValidationState &state, const CBlock *pblock = NULL);
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
/**
@@ -224,7 +229,7 @@ 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);
struct CNodeStateStats {
@@ -303,8 +308,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
@@ -342,7 +349,7 @@ public:
/** Functions for disk access for blocks */
-bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart);
+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);
@@ -353,7 +360,7 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex);
* In case pfClean is provided, operation will try to be tolerant about errors, and *pfClean
* will be true if no problems were found. Otherwise, the return value will be false in case
* of problems. Note that in any case, coins may be modified. */
-bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL);
+bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL);
/** Apply the effects of this block (with given index) on the UTXO set represented by coins */
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false);
@@ -370,7 +377,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
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(CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp);
+bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp);
bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL);
@@ -462,4 +469,16 @@ extern CBlockTreeDB *pblocktree;
*/
int GetSpendHeight(const CCoinsViewCache& inputs);
+/** Reject codes greater or equal to this can be returned by AcceptToMemPool
+ * for transactions, to signal internal conditions. They cannot and should not
+ * be sent over the P2P network.
+ */
+static const unsigned int REJECT_INTERNAL = 0x100;
+/** Too high fee. Can not be triggered by P2P transactions */
+static const unsigned int REJECT_HIGHFEE = 0x100;
+/** Transaction is already known (either in mempool or blockchain) */
+static const unsigned int REJECT_ALREADY_KNOWN = 0x101;
+/** Transaction conflicts with a transaction already known */
+static const unsigned int REJECT_CONFLICT = 0x102;
+
#endif // BITCOIN_MAIN_H
diff --git a/src/memusage.h b/src/memusage.h
index be3964df1b..b475c3313b 100644
--- a/src/memusage.h
+++ b/src/memusage.h
@@ -74,18 +74,30 @@ static inline size_t DynamicUsage(const std::vector<X>& v)
return MallocUsage(v.capacity() * sizeof(X));
}
-template<typename X>
-static inline size_t DynamicUsage(const std::set<X>& s)
+template<typename X, typename Y>
+static inline size_t DynamicUsage(const std::set<X, Y>& s)
{
return MallocUsage(sizeof(stl_tree_node<X>)) * s.size();
}
template<typename X, typename Y>
-static inline size_t DynamicUsage(const std::map<X, Y>& m)
+static inline size_t IncrementalDynamicUsage(const std::set<X, Y>& s)
+{
+ return MallocUsage(sizeof(stl_tree_node<X>));
+}
+
+template<typename X, typename Y, typename Z>
+static inline size_t DynamicUsage(const std::map<X, Y, Z>& m)
{
return MallocUsage(sizeof(stl_tree_node<std::pair<const X, Y> >)) * m.size();
}
+template<typename X, typename Y, typename Z>
+static inline size_t IncrementalDynamicUsage(const std::map<X, Y, Z>& m)
+{
+ return MallocUsage(sizeof(stl_tree_node<std::pair<const X, Y> >));
+}
+
// Boost data structures
template<typename X>
diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp
index 4d90fd8cd7..f8e877df25 100644
--- a/src/merkleblock.cpp
+++ b/src/merkleblock.cpp
@@ -168,7 +168,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
// traverse the partial tree
unsigned int nBitsUsed = 0, nHashUsed = 0;
uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch);
- // verify that no problems occured during the tree traversal
+ // verify that no problems occurred during the tree traversal
if (fBad)
return uint256();
// verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence)
diff --git a/src/miner.cpp b/src/miner.cpp
index 5e575f45f1..053d9cdbc4 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -6,7 +6,9 @@
#include "miner.h"
#include "amount.h"
+#include "chain.h"
#include "chainparams.h"
+#include "coins.h"
#include "consensus/consensus.h"
#include "consensus/validation.h"
#include "hash.h"
@@ -15,7 +17,9 @@
#include "policy/policy.h"
#include "pow.h"
#include "primitives/transaction.h"
+#include "script/standard.h"
#include "timedata.h"
+#include "txmempool.h"
#include "util.h"
#include "utilmoneystr.h"
#include "validationinterface.h"
@@ -80,13 +84,19 @@ public:
}
};
-void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
+int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
{
- pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+ int64_t nOldTime = pblock->nTime;
+ int64_t nNewTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+
+ if (nOldTime < nNewTime)
+ pblock->nTime = nNewTime;
// Updating time can change work required on testnet:
if (consensusParams.fPowAllowMinDifficultyBlocks)
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
+
+ return nNewTime - nOldTime;
}
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
@@ -138,6 +148,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
CBlockIndex* pindexPrev = chainActive.Tip();
const int nHeight = pindexPrev->nHeight + 1;
pblock->nTime = GetAdjustedTime();
+ const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast();
CCoinsViewCache view(pcoinsTip);
// Priority order to process transactions
@@ -148,11 +159,16 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
// This vector will be sorted into a priority queue:
vector<TxPriority> vecPriority;
vecPriority.reserve(mempool.mapTx.size());
- for (map<uint256, CTxMemPoolEntry>::iterator mi = mempool.mapTx.begin();
+ for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin();
mi != mempool.mapTx.end(); ++mi)
{
- const CTransaction& tx = mi->second.GetTx();
- if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, pblock->nTime))
+ const CTransaction& tx = mi->GetTx();
+
+ int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST)
+ ? nMedianTimePast
+ : pblock->GetBlockTime();
+
+ if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, nLockTimeCutoff))
continue;
COrphan* porphan = NULL;
@@ -186,7 +202,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
}
mapDependers[txin.prevout.hash].push_back(porphan);
porphan->setDependsOn.insert(txin.prevout.hash);
- nTotalIn += mempool.mapTx[txin.prevout.hash].GetTx().vout[txin.prevout.n].nValue;
+ nTotalIn += mempool.mapTx.find(txin.prevout.hash)->GetTx().vout[txin.prevout.n].nValue;
continue;
}
const CCoins* coins = view.AccessCoins(txin.prevout.hash);
@@ -216,7 +232,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
porphan->feeRate = feeRate;
}
else
- vecPriority.push_back(TxPriority(dPriority, feeRate, &mi->second.GetTx()));
+ vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx())));
}
// Collect transactions into block
@@ -342,7 +358,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
return pblocktemplate.release();
}
-void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
+void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
{
// Update nExtraNonce
static uint256 hashPrevBlock;
@@ -358,7 +374,7 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
assert(txCoinbase.vin[0].scriptSig.size() <= 100);
pblock->vtx[0] = txCoinbase;
- pblock->hashMerkleRoot = pblock->BuildMerkleTree();
+ pblock->hashMerkleRoot = pblock->ComputeMerkleRoot();
}
//////////////////////////////////////////////////////////////////////////////
@@ -399,7 +415,7 @@ bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phas
}
}
-static bool ProcessBlockFound(CBlock* pblock, const CChainParams& chainparams)
+static bool ProcessBlockFound(const CBlock* pblock, const CChainParams& chainparams)
{
LogPrintf("%s\n", pblock->ToString());
LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
@@ -434,8 +450,10 @@ void static BitcoinMiner(const CChainParams& chainparams)
GetMainSignals().ScriptForMining(coinbaseScript);
try {
- //throw an error if no script was provided
- if (!coinbaseScript->reserveScript.size())
+ // Throw an error if no script was provided. This can happen
+ // due to some internal error but also if the keypool is empty.
+ // In the latter case, already the pointer is NULL.
+ if (!coinbaseScript || coinbaseScript->reserveScript.empty())
throw std::runtime_error("No coinbase script available (mining requires a wallet)");
while (true) {
@@ -517,7 +535,9 @@ void static BitcoinMiner(const CChainParams& chainparams)
break;
// Update nTime every few seconds
- UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
+ if (UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev) < 0)
+ break; // Recreate the block if the clock has run backwards,
+ // so that we can use the correct time.
if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks)
{
// Changing pblock->nTime can change work required on testnet:
diff --git a/src/miner.h b/src/miner.h
index 777a091967..7e0e58d540 100644
--- a/src/miner.h
+++ b/src/miner.h
@@ -29,7 +29,7 @@ void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainpar
/** Generate a new block, without valid proof-of-work */
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn);
/** Modify the extranonce in a block */
-void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
-void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
+void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
+int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
#endif // BITCOIN_MINER_H
diff --git a/src/net.cpp b/src/net.cpp
index 3d369c7dd1..e18e8d0e29 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -12,10 +12,13 @@
#include "addrman.h"
#include "chainparams.h"
#include "clientversion.h"
+#include "consensus/consensus.h"
+#include "crypto/common.h"
+#include "hash.h"
#include "primitives/transaction.h"
#include "scheduler.h"
#include "ui_interface.h"
-#include "crypto/common.h"
+#include "utilstrencodings.h"
#ifdef WIN32
#include <string.h>
@@ -78,9 +81,9 @@ static CNode* pnodeLocalHost = NULL;
uint64_t nLocalHostNonce = 0;
static std::vector<ListenSocket> vhListenSocket;
CAddrMan addrman;
-int nMaxConnections = 125;
-int nWhiteConnections = 0;
+int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS;
bool fAddressesInitialized = false;
+std::string strSubVersion;
vector<CNode*> vNodes;
CCriticalSection cs_vNodes;
@@ -324,6 +327,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);
@@ -443,7 +451,7 @@ void CNode::PushVersion()
else
LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id);
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
- nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight, true);
+ nLocalHostNonce, strSubVersion, nBestHeight, true);
}
@@ -626,6 +634,7 @@ void CNode::copyStats(CNodeStats &stats)
// Raw ping time is in microseconds, but show it to user as whole seconds (Bitcoin users should be well used to small numbers with many decimal places by now :)
stats.dPingTime = (((double)nPingUsecTime) / 1e6);
+ stats.dPingMin = (((double)nMinPingUsecTime) / 1e6);
stats.dPingWait = (((double)nPingUsecWait) / 1e6);
// Leave string empty if addrLocal invalid (not filled in yet)
@@ -656,7 +665,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
return false;
if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
- LogPrint("net", "Oversized message from peer=%i, disconnecting", GetId());
+ LogPrint("net", "Oversized message from peer=%i, disconnecting\n", GetId());
return false;
}
@@ -773,6 +782,231 @@ void SocketSendData(CNode *pnode)
static list<CNode*> vNodesDisconnected;
+class CNodeRef {
+public:
+ CNodeRef(CNode *pnode) : _pnode(pnode) {
+ LOCK(cs_vNodes);
+ _pnode->AddRef();
+ }
+
+ ~CNodeRef() {
+ LOCK(cs_vNodes);
+ _pnode->Release();
+ }
+
+ CNode& operator *() const {return *_pnode;};
+ CNode* operator ->() const {return _pnode;};
+
+ CNodeRef& operator =(const CNodeRef& other)
+ {
+ if (this != &other) {
+ LOCK(cs_vNodes);
+
+ _pnode->Release();
+ _pnode = other._pnode;
+ _pnode->AddRef();
+ }
+ return *this;
+ }
+
+ CNodeRef(const CNodeRef& other):
+ _pnode(other._pnode)
+ {
+ LOCK(cs_vNodes);
+ _pnode->AddRef();
+ }
+private:
+ CNode *_pnode;
+};
+
+static bool ReverseCompareNodeMinPingTime(const CNodeRef &a, const CNodeRef &b)
+{
+ return a->nMinPingUsecTime > b->nMinPingUsecTime;
+}
+
+static bool ReverseCompareNodeTimeConnected(const CNodeRef &a, const CNodeRef &b)
+{
+ return a->nTimeConnected > b->nTimeConnected;
+}
+
+class CompareNetGroupKeyed
+{
+ std::vector<unsigned char> vchSecretKey;
+public:
+ CompareNetGroupKeyed()
+ {
+ vchSecretKey.resize(32, 0);
+ GetRandBytes(vchSecretKey.data(), vchSecretKey.size());
+ }
+
+ bool operator()(const CNodeRef &a, const CNodeRef &b)
+ {
+ std::vector<unsigned char> vchGroupA, vchGroupB;
+ CSHA256 hashA, hashB;
+ std::vector<unsigned char> vchA(32), vchB(32);
+
+ vchGroupA = a->addr.GetGroup();
+ vchGroupB = b->addr.GetGroup();
+
+ hashA.Write(begin_ptr(vchGroupA), vchGroupA.size());
+ hashB.Write(begin_ptr(vchGroupB), vchGroupB.size());
+
+ hashA.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
+ hashB.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
+
+ hashA.Finalize(begin_ptr(vchA));
+ hashB.Finalize(begin_ptr(vchB));
+
+ return vchA < vchB;
+ }
+};
+
+static bool AttemptToEvictConnection(bool fPreferNewConnection) {
+ std::vector<CNodeRef> vEvictionCandidates;
+ {
+ LOCK(cs_vNodes);
+
+ BOOST_FOREACH(CNode *node, vNodes) {
+ if (node->fWhitelisted)
+ continue;
+ if (!node->fInbound)
+ continue;
+ if (node->fDisconnect)
+ continue;
+ if (node->addr.IsLocal())
+ continue;
+ vEvictionCandidates.push_back(CNodeRef(node));
+ }
+ }
+
+ if (vEvictionCandidates.empty()) return false;
+
+ // Protect connections with certain characteristics
+
+ // Deterministically select 4 peers to protect by netgroup.
+ // An attacker cannot predict which netgroups will be protected.
+ static CompareNetGroupKeyed comparerNetGroupKeyed;
+ std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), comparerNetGroupKeyed);
+ vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
+
+ if (vEvictionCandidates.empty()) return false;
+
+ // Protect the 8 nodes with the best ping times.
+ // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
+ std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime);
+ vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(8, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
+
+ if (vEvictionCandidates.empty()) return false;
+
+ // Protect the half of the remaining nodes which have been connected the longest.
+ // This replicates the existing implicit behavior.
+ std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
+ vEvictionCandidates.erase(vEvictionCandidates.end() - static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end());
+
+ if (vEvictionCandidates.empty()) return false;
+
+ // Identify the network group with the most connections
+ std::vector<unsigned char> naMostConnections;
+ unsigned int nMostConnections = 0;
+ std::map<std::vector<unsigned char>, std::vector<CNodeRef> > mapAddrCounts;
+ BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) {
+ mapAddrCounts[node->addr.GetGroup()].push_back(node);
+
+ if (mapAddrCounts[node->addr.GetGroup()].size() > nMostConnections) {
+ nMostConnections = mapAddrCounts[node->addr.GetGroup()].size();
+ naMostConnections = node->addr.GetGroup();
+ }
+ }
+
+ // Reduce to the network group with the most connections
+ vEvictionCandidates = mapAddrCounts[naMostConnections];
+
+ // Do not disconnect peers if there is only 1 connection from their network group
+ if (vEvictionCandidates.size() <= 1)
+ // unless we prefer the new connection (for whitelisted peers)
+ if (!fPreferNewConnection)
+ return false;
+
+ // Disconnect the most recent connection from the network group with the most connections
+ std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
+ vEvictionCandidates[0]->fDisconnect = true;
+
+ return true;
+}
+
+static void AcceptConnection(const ListenSocket& hListenSocket) {
+ struct sockaddr_storage sockaddr;
+ socklen_t len = sizeof(sockaddr);
+ SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
+ CAddress addr;
+ int nInbound = 0;
+ int nMaxInbound = nMaxConnections - MAX_OUTBOUND_CONNECTIONS;
+
+ if (hSocket != INVALID_SOCKET)
+ if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
+ LogPrintf("Warning: Unknown socket family\n");
+
+ bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange(addr);
+ {
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ if (pnode->fInbound)
+ nInbound++;
+ }
+
+ if (hSocket == INVALID_SOCKET)
+ {
+ int nErr = WSAGetLastError();
+ if (nErr != WSAEWOULDBLOCK)
+ LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
+ return;
+ }
+
+ if (!IsSelectableSocket(hSocket))
+ {
+ LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
+ CloseSocket(hSocket);
+ return;
+ }
+
+ // 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());
+ CloseSocket(hSocket);
+ return;
+ }
+
+ if (nInbound >= nMaxInbound)
+ {
+ if (!AttemptToEvictConnection(whitelisted)) {
+ // No connection to evict, disconnect the new connection
+ LogPrint("net", "failed to find an eviction candidate - connection dropped (full)\n");
+ CloseSocket(hSocket);
+ return;
+ }
+ }
+
+ CNode* pnode = new CNode(hSocket, addr, "", true);
+ pnode->AddRef();
+ pnode->fWhitelisted = whitelisted;
+
+ LogPrint("net", "connection from %s accepted\n", addr.ToString());
+
+ {
+ LOCK(cs_vNodes);
+ vNodes.push_back(pnode);
+ }
+}
+
void ThreadSocketHandler()
{
unsigned int nPrevNodeCount = 0;
@@ -930,64 +1164,7 @@ void ThreadSocketHandler()
{
if (hListenSocket.socket != INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv))
{
- struct sockaddr_storage sockaddr;
- socklen_t len = sizeof(sockaddr);
- SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
- CAddress addr;
- int nInbound = 0;
- int nMaxInbound = nMaxConnections - MAX_OUTBOUND_CONNECTIONS;
-
- if (hSocket != INVALID_SOCKET)
- if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
- LogPrintf("Warning: Unknown socket family\n");
-
- bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange(addr);
- {
- LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
- if (pnode->fInbound)
- nInbound++;
- }
-
- if (hSocket == INVALID_SOCKET)
- {
- int nErr = WSAGetLastError();
- if (nErr != WSAEWOULDBLOCK)
- LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
- }
- else if (!IsSelectableSocket(hSocket))
- {
- LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
- CloseSocket(hSocket);
- }
- else if (nInbound >= nMaxInbound)
- {
- LogPrint("net", "connection from %s dropped (full)\n", addr.ToString());
- CloseSocket(hSocket);
- }
- else if (!whitelisted && (nInbound >= (nMaxInbound - nWhiteConnections)))
- {
- LogPrint("net", "connection from %s dropped (non-whitelisted)\n", addr.ToString());
- CloseSocket(hSocket);
- }
- else if (CNode::IsBanned(addr) && !whitelisted)
- {
- LogPrintf("connection from %s dropped (banned)\n", addr.ToString());
- CloseSocket(hSocket);
- }
- else
- {
- CNode* pnode = new CNode(hSocket, addr, "", true);
- pnode->AddRef();
- pnode->fWhitelisted = whitelisted;
-
- LogPrint("net", "connection from %s accepted\n", addr.ToString());
-
- {
- LOCK(cs_vNodes);
- vNodes.push_back(pnode);
- }
- }
+ AcceptConnection(hListenSocket);
}
}
@@ -1117,10 +1294,14 @@ void ThreadMapPort()
#ifndef UPNPDISCOVER_SUCCESS
/* miniupnpc 1.5 */
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
-#else
+#elif MINIUPNPC_API_VERSION < 14
/* miniupnpc 1.6 */
int error = 0;
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
+#else
+ /* miniupnpc 1.9.20150730 */
+ int error = 0;
+ devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
#endif
struct UPNPUrls urls;
@@ -1622,8 +1803,13 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste
setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
#endif
// Allow binding if the port is still in TIME_WAIT state after
- // the program was closed and restarted. Not an issue on windows!
+ // the program was closed and restarted.
setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
+ // 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
@@ -1903,6 +2089,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 < recommendedMinimum)
+ LogPrintf("Max outbound target is very small (%s) and will be overshot. Recommended minimum is %s\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()
@@ -2058,7 +2332,7 @@ unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) :
ssSend(SER_NETWORK, INIT_PROTO_VERSION),
- addrKnown(5000, 0.001, insecure_rand()),
+ addrKnown(5000, 0.001),
setInventoryKnown(SendBufferSize() / 1000)
{
nServices = 0;
@@ -2093,6 +2367,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
nPingUsecStart = 0;
nPingUsecTime = 0;
fPingQueued = false;
+ nMinPingUsecTime = std::numeric_limits<int64_t>::max();
{
LOCK(cs_nLastNodeId);
@@ -2183,8 +2458,10 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
Fuzz(GetArg("-fuzzmessagestest", 10));
if (ssSend.size() == 0)
+ {
+ LEAVE_CRITICAL_SECTION(cs_vSend);
return;
-
+ }
// Set the size
unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
@@ -2314,7 +2591,7 @@ void DumpBanlist()
{
int64_t nStart = GetTimeMillis();
- CNode::SweepBanned(); //clean unused entires (if bantime has expired)
+ CNode::SweepBanned(); //clean unused entries (if bantime has expired)
CBanDB bandb;
banmap_t banmap;
diff --git a/src/net.h b/src/net.h
index 86d74e2174..f90b3385af 100644
--- a/src/net.h
+++ b/src/net.h
@@ -8,7 +8,6 @@
#include "bloom.h"
#include "compat.h"
-#include "hash.h"
#include "limitedmap.h"
#include "mruset.h"
#include "netbase.h"
@@ -17,7 +16,6 @@
#include "streams.h"
#include "sync.h"
#include "uint256.h"
-#include "utilstrencodings.h"
#include <deque>
#include <stdint.h>
@@ -31,7 +29,6 @@
#include <boost/signals2/signal.hpp>
class CAddrMan;
-class CBlockIndex;
class CScheduler;
class CNode;
@@ -49,6 +46,8 @@ static const unsigned int MAX_INV_SZ = 50000;
static const unsigned int MAX_ADDR_TO_SEND = 1000;
/** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024;
+/** Maximum length of strSubVer in `version` message */
+static const unsigned int MAX_SUBVERSION_LENGTH = 256;
/** -listen default */
static const bool DEFAULT_LISTEN = true;
/** -upnp default */
@@ -59,6 +58,8 @@ static const bool DEFAULT_UPNP = false;
#endif
/** The maximum number of entries in mapAskFor */
static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ;
+/** The maximum number of peer connections to maintain. */
+static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
unsigned int ReceiveFloodSize();
unsigned int SendBufferSize();
@@ -142,19 +143,8 @@ extern uint64_t nLocalServices;
extern uint64_t nLocalHostNonce;
extern CAddrMan addrman;
-// The allocation of connections against the maximum allowed (nMaxConnections)
-// is prioritized as follows:
-// 1st: Outbound connections (MAX_OUTBOUND_CONNECTIONS)
-// 2nd: Inbound connections from whitelisted peers (nWhiteConnections)
-// 3rd: Inbound connections from non-whitelisted peers
-// Thus, the number of connection slots for the general public to use is:
-// nMaxConnections - (MAX_OUTBOUND_CONNECTIONS + nWhiteConnections)
-// Any additional inbound connections beyond limits will be immediately closed
-
/** Maximum number of connections to simultaneously allow (aka connection slots) */
extern int nMaxConnections;
-/** Number of connection slots to reserve for inbound from whitelisted peers */
-extern int nWhiteConnections;
extern std::vector<CNode*> vNodes;
extern CCriticalSection cs_vNodes;
@@ -169,6 +159,9 @@ extern CCriticalSection cs_vAddedNodes;
extern NodeId nLastNodeId;
extern CCriticalSection cs_nLastNodeId;
+/** Subversion as sent to the P2P network in `version` messages */
+extern std::string strSubVersion;
+
struct LocalServiceInfo {
int nScore;
int nPort;
@@ -196,6 +189,7 @@ public:
bool fWhitelisted;
double dPingTime;
double dPingWait;
+ double dPingMin;
std::string addrLocal;
};
@@ -391,6 +385,8 @@ public:
int64_t nPingUsecStart;
// Last measured round-trip time.
int64_t nPingUsecTime;
+ // Best measured round-trip time.
+ int64_t nMinPingUsecTime;
// Whether a ping is requested.
bool fPingQueued;
@@ -404,6 +400,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&);
@@ -691,7 +693,7 @@ public:
static bool BannedSetIsDirty();
//!set the "dirty" flag for the banlist
static void SetBannedSetDirty(bool dirty=true);
- //!clean unused entires (if bantime has expired)
+ //!clean unused entries (if bantime has expired)
static void SweepBanned();
void copyStats(CNodeStats &stats);
@@ -705,6 +707,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();
};
diff --git a/src/netbase.cpp b/src/netbase.cpp
index b7e2e57917..f5316965ce 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -349,7 +349,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
}
if (pchRetA[0] != 0x01 || pchRetA[1] != 0x00) {
CloseSocket(hSocket);
- return error("Proxy authentication unsuccesful");
+ return error("Proxy authentication unsuccessful");
}
} else if (pchRet1[1] == 0x00) {
// Perform no authentication
@@ -444,12 +444,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()));
@@ -983,7 +990,7 @@ std::vector<unsigned char> CNetAddr::GetGroup() const
nBits -= 8;
}
if (nBits > 0)
- vchRet.push_back(GetByte(15 - nStartByte) | ((1 << nBits) - 1));
+ vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1));
return vchRet;
}
@@ -1311,17 +1318,57 @@ bool CSubNet::Match(const CNetAddr &addr) const
return true;
}
+static inline int NetmaskBits(uint8_t x)
+{
+ switch(x) {
+ case 0x00: return 0; break;
+ case 0x80: return 1; break;
+ case 0xc0: return 2; break;
+ case 0xe0: return 3; break;
+ case 0xf0: return 4; break;
+ case 0xf8: return 5; break;
+ case 0xfc: return 6; break;
+ case 0xfe: return 7; break;
+ case 0xff: return 8; break;
+ default: return -1; break;
+ }
+}
+
std::string CSubNet::ToString() const
{
+ /* Parse binary 1{n}0{N-n} to see if mask can be represented as /n */
+ int cidr = 0;
+ bool valid_cidr = true;
+ int n = network.IsIPv4() ? 12 : 0;
+ for (; n < 16 && netmask[n] == 0xff; ++n)
+ cidr += 8;
+ if (n < 16) {
+ int bits = NetmaskBits(netmask[n]);
+ if (bits < 0)
+ valid_cidr = false;
+ else
+ cidr += bits;
+ ++n;
+ }
+ for (; n < 16 && valid_cidr; ++n)
+ if (netmask[n] != 0x00)
+ valid_cidr = false;
+
+ /* Format output */
std::string strNetmask;
- if (network.IsIPv4())
- strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]);
- else
- strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
- netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3],
- netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7],
- netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11],
- netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]);
+ if (valid_cidr) {
+ strNetmask = strprintf("%u", cidr);
+ } else {
+ if (network.IsIPv4())
+ strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]);
+ else
+ strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
+ netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3],
+ netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7],
+ netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11],
+ netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]);
+ }
+
return network.ToString() + "/" + strNetmask;
}
diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp
index b1491cec01..ffe31d1942 100644
--- a/src/policy/fees.cpp
+++ b/src/policy/fees.cpp
@@ -249,7 +249,7 @@ unsigned int TxConfirmStats::NewTx(unsigned int nBlockHeight, double val)
unsigned int bucketindex = bucketMap.lower_bound(val)->second;
unsigned int blockIndex = nBlockHeight % unconfTxs.size();
unconfTxs[blockIndex][bucketindex]++;
- LogPrint("estimatefee", "adding to %s\n", dataTypeString);
+ LogPrint("estimatefee", "adding to %s", dataTypeString);
return bucketindex;
}
@@ -261,7 +261,7 @@ void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHe
blocksAgo = 0;
if (blocksAgo < 0) {
LogPrint("estimatefee", "Blockpolicy error, blocks ago is negative for mempool tx\n");
- return; //This can't happen becasue we call this with our best seen height, no entries can have higher
+ return; //This can't happen because we call this with our best seen height, no entries can have higher
}
if (blocksAgo >= (int)unconfTxs.size()) {
@@ -390,8 +390,9 @@ void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, boo
mapMemPoolTxs[hash].bucketIndex = feeStats.NewTx(txHeight, (double)feeRate.GetFeePerK());
}
else {
- LogPrint("estimatefee", "not adding\n");
+ LogPrint("estimatefee", "not adding");
}
+ LogPrint("estimatefee", "\n");
}
void CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry& entry)
diff --git a/src/policy/fees.h b/src/policy/fees.h
index ce4d782566..15577d128a 100644
--- a/src/policy/fees.h
+++ b/src/policy/fees.h
@@ -118,7 +118,7 @@ public:
/**
* Initialize the data structures. This is called by BlockPolicyEstimator's
* constructor with default values.
- * @param defaultBuckets contains the upper limits for the bucket boundries
+ * @param defaultBuckets contains the upper limits for the bucket boundaries
* @param maxConfirms max number of confirms to track
* @param decay how much to decay the historical moving average per block
* @param dataTypeString for logging purposes
diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp
index 169fef4af4..4c96fbf5a5 100644
--- a/src/policy/policy.cpp
+++ b/src/policy/policy.cpp
@@ -49,7 +49,9 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
return false;
if (m < 1 || m > n)
return false;
- }
+ } else if (whichType == TX_NULL_DATA &&
+ (!GetBoolArg("-datacarrier", true) || scriptPubKey.size() > nMaxDatacarrierBytes))
+ return false;
return whichType != TX_NONSTANDARD;
}
diff --git a/src/policy/policy.h b/src/policy/policy.h
index 1551aecde8..7027f1402f 100644
--- a/src/policy/policy.h
+++ b/src/policy/policy.h
@@ -37,11 +37,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
diff --git a/src/pow.cpp b/src/pow.cpp
index bb53ad204b..5ace3fbc9b 100644
--- a/src/pow.cpp
+++ b/src/pow.cpp
@@ -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);
diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp
index 5b9c13d870..7a58074d24 100644
--- a/src/primitives/block.cpp
+++ b/src/primitives/block.cpp
@@ -15,7 +15,7 @@ uint256 CBlockHeader::GetHash() const
return SerializeHash(*this);
}
-uint256 CBlock::BuildMerkleTree(bool* fMutated) const
+uint256 CBlock::ComputeMerkleRoot(bool* fMutated) const
{
/* WARNING! If you're reading this because you're learning about crypto
and/or designing a new system that will use merkle trees, keep in mind
@@ -52,7 +52,7 @@ uint256 CBlock::BuildMerkleTree(bool* fMutated) const
known ways of changing the transactions without affecting the merkle
root.
*/
- vMerkleTree.clear();
+ std::vector<uint256> vMerkleTree;
vMerkleTree.reserve(vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes.
for (std::vector<CTransaction>::const_iterator it(vtx.begin()); it != vtx.end(); ++it)
vMerkleTree.push_back(it->GetHash());
@@ -78,37 +78,6 @@ uint256 CBlock::BuildMerkleTree(bool* fMutated) const
return (vMerkleTree.empty() ? uint256() : vMerkleTree.back());
}
-std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
-{
- if (vMerkleTree.empty())
- BuildMerkleTree();
- std::vector<uint256> vMerkleBranch;
- int j = 0;
- for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
- {
- int i = std::min(nIndex^1, nSize-1);
- vMerkleBranch.push_back(vMerkleTree[j+i]);
- nIndex >>= 1;
- j += nSize;
- }
- return vMerkleBranch;
-}
-
-uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
-{
- if (nIndex == -1)
- return uint256();
- for (std::vector<uint256>::const_iterator it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it)
- {
- if (nIndex & 1)
- hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash));
- else
- hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it));
- nIndex >>= 1;
- }
- return hash;
-}
-
std::string CBlock::ToString() const
{
std::stringstream s;
@@ -123,9 +92,5 @@ std::string CBlock::ToString() const
{
s << " " << vtx[i].ToString() << "\n";
}
- s << " vMerkleTree: ";
- for (unsigned int i = 0; i < vMerkleTree.size(); i++)
- s << " " << vMerkleTree[i].ToString();
- s << "\n";
return s.str();
}
diff --git a/src/primitives/block.h b/src/primitives/block.h
index 59f46deb1c..54731ff557 100644
--- a/src/primitives/block.h
+++ b/src/primitives/block.h
@@ -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;
@@ -78,7 +78,7 @@ public:
std::vector<CTransaction> vtx;
// memory only
- mutable std::vector<uint256> vMerkleTree;
+ mutable bool fChecked;
CBlock()
{
@@ -103,7 +103,7 @@ public:
{
CBlockHeader::SetNull();
vtx.clear();
- vMerkleTree.clear();
+ fChecked = false;
}
CBlockHeader GetBlockHeader() const
@@ -118,14 +118,12 @@ public:
return block;
}
- // Build the in-memory merkle tree for this block and return the merkle root.
+ // Build the merkle tree for this block and return the merkle root.
// If non-NULL, *mutated is set to whether mutation was detected in the merkle
// tree (a duplication of transactions in the block leading to an identical
// merkle root).
- uint256 BuildMerkleTree(bool* mutated = NULL) const;
+ uint256 ComputeMerkleRoot(bool* mutated = NULL) const;
- std::vector<uint256> GetMerkleBranch(int nIndex) const;
- static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex);
std::string ToString() const;
};
diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp
index 606dbea798..46d3cbbe2e 100644
--- a/src/primitives/transaction.cpp
+++ b/src/primitives/transaction.cpp
@@ -36,7 +36,7 @@ std::string CTxIn::ToString() const
if (prevout.IsNull())
str += strprintf(", coinbase %s", HexStr(scriptSig));
else
- str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24));
+ str += strprintf(", scriptSig=%s", HexStr(scriptSig).substr(0, 24));
if (nSequence != std::numeric_limits<unsigned int>::max())
str += strprintf(", nSequence=%u", nSequence);
str += ")";
@@ -56,7 +56,7 @@ uint256 CTxOut::GetHash() const
std::string CTxOut::ToString() const
{
- return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30));
+ return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0, 30));
}
CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}
diff --git a/src/protocol.h b/src/protocol.h
index b5e65032a2..50aeaf44ba 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -75,6 +75,10 @@ enum {
// Bitcoin Core does not support this but a patch set called Bitcoin XT does.
// See BIP 64 for details on how this is implemented.
NODE_GETUTXO = (1 << 1),
+ // NODE_BLOOM means the node is capable and willing to handle bloom-filtered connections.
+ // Bitcoin Core nodes used to support this by default, without advertising this bit,
+ // but no longer do as of protocol version 70011 (= NO_BLOOM_VERSION)
+ NODE_BLOOM = (1 << 2),
// Bits 24-31 are reserved for temporary experiments. Just pick a bit that
// isn't getting used, or one not being used much, and notify the
diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp
index af6801919c..8bd1586446 100644
--- a/src/qt/addressbookpage.cpp
+++ b/src/qt/addressbookpage.cpp
@@ -14,14 +14,14 @@
#include "csvmodelwriter.h"
#include "editaddressdialog.h"
#include "guiutil.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include <QIcon>
#include <QMenu>
#include <QMessageBox>
#include <QSortFilterProxyModel>
-AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
+AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode mode, Tabs tab, QWidget *parent) :
QDialog(parent),
ui(new Ui::AddressBookPage),
model(0),
@@ -30,17 +30,17 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
{
ui->setupUi(this);
-#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
- ui->newAddress->setIcon(QIcon());
- ui->copyAddress->setIcon(QIcon());
- ui->deleteAddress->setIcon(QIcon());
- ui->exportButton->setIcon(QIcon());
-#else
- ui->newAddress->setIcon(SingleColorIcon(":/icons/add"));
- ui->copyAddress->setIcon(SingleColorIcon(":/icons/editcopy"));
- ui->deleteAddress->setIcon(SingleColorIcon(":/icons/remove"));
- ui->exportButton->setIcon(SingleColorIcon(":/icons/export"));
-#endif
+ if (!platformStyle->getImagesOnButtons()) {
+ ui->newAddress->setIcon(QIcon());
+ ui->copyAddress->setIcon(QIcon());
+ ui->deleteAddress->setIcon(QIcon());
+ ui->exportButton->setIcon(QIcon());
+ } else {
+ ui->newAddress->setIcon(platformStyle->SingleColorIcon(":/icons/add"));
+ ui->copyAddress->setIcon(platformStyle->SingleColorIcon(":/icons/editcopy"));
+ ui->deleteAddress->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->exportButton->setIcon(platformStyle->SingleColorIcon(":/icons/export"));
+ }
switch(mode)
{
diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h
index 09634ce336..92e6cab9ac 100644
--- a/src/qt/addressbookpage.h
+++ b/src/qt/addressbookpage.h
@@ -9,6 +9,7 @@
class AddressTableModel;
class OptionsModel;
+class PlatformStyle;
namespace Ui {
class AddressBookPage;
@@ -39,7 +40,7 @@ public:
ForEditing /**< Open address book for editing */
};
- explicit AddressBookPage(Mode mode, Tabs tab, QWidget *parent);
+ explicit AddressBookPage(const PlatformStyle *platformStyle, Mode mode, Tabs tab, QWidget *parent);
~AddressBookPage();
void setModel(AddressTableModel *model);
diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp
new file mode 100644
index 0000000000..33792af5ba
--- /dev/null
+++ b/src/qt/bantablemodel.cpp
@@ -0,0 +1,181 @@
+// Copyright (c) 2011-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "bantablemodel.h"
+
+#include "clientmodel.h"
+#include "guiconstants.h"
+#include "guiutil.h"
+
+#include "sync.h"
+#include "utiltime.h"
+
+#include <QDebug>
+#include <QList>
+
+bool BannedNodeLessThan::operator()(const CCombinedBan& left, const CCombinedBan& right) const
+{
+ const CCombinedBan* pLeft = &left;
+ const CCombinedBan* pRight = &right;
+
+ if (order == Qt::DescendingOrder)
+ std::swap(pLeft, pRight);
+
+ switch(column)
+ {
+ case BanTableModel::Address:
+ return pLeft->subnet.ToString().compare(pRight->subnet.ToString()) < 0;
+ case BanTableModel::Bantime:
+ return pLeft->banEntry.nBanUntil < pRight->banEntry.nBanUntil;
+ }
+
+ return false;
+}
+
+// private implementation
+class BanTablePriv
+{
+public:
+ /** Local cache of peer information */
+ QList<CCombinedBan> cachedBanlist;
+ /** Column to sort nodes by */
+ int sortColumn;
+ /** Order (ascending or descending) to sort nodes by */
+ Qt::SortOrder sortOrder;
+
+ /** Pull a full list of banned nodes from CNode into our cache */
+ void refreshBanlist()
+ {
+ banmap_t banMap;
+ CNode::GetBanned(banMap);
+
+ cachedBanlist.clear();
+#if QT_VERSION >= 0x040700
+ cachedBanlist.reserve(banMap.size());
+#endif
+ for (banmap_t::iterator it = banMap.begin(); it != banMap.end(); it++)
+ {
+ CCombinedBan banEntry;
+ banEntry.subnet = (*it).first;
+ banEntry.banEntry = (*it).second;
+ cachedBanlist.append(banEntry);
+ }
+
+ if (sortColumn >= 0)
+ // sort cachedBanlist (use stable sort to prevent rows jumping around unneceesarily)
+ qStableSort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder));
+ }
+
+ int size() const
+ {
+ return cachedBanlist.size();
+ }
+
+ CCombinedBan *index(int idx)
+ {
+ if (idx >= 0 && idx < cachedBanlist.size())
+ return &cachedBanlist[idx];
+
+ return 0;
+ }
+};
+
+BanTableModel::BanTableModel(ClientModel *parent) :
+ QAbstractTableModel(parent),
+ clientModel(parent)
+{
+ columns << tr("IP/Netmask") << tr("Banned Until");
+ priv = new BanTablePriv();
+ // default to unsorted
+ priv->sortColumn = -1;
+
+ // load initial data
+ refresh();
+}
+
+int BanTableModel::rowCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return priv->size();
+}
+
+int BanTableModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return columns.length();;
+}
+
+QVariant BanTableModel::data(const QModelIndex &index, int role) const
+{
+ if(!index.isValid())
+ return QVariant();
+
+ CCombinedBan *rec = static_cast<CCombinedBan*>(index.internalPointer());
+
+ if (role == Qt::DisplayRole) {
+ switch(index.column())
+ {
+ case Address:
+ return QString::fromStdString(rec->subnet.ToString());
+ case Bantime:
+ QDateTime date = QDateTime::fromMSecsSinceEpoch(0);
+ date = date.addSecs(rec->banEntry.nBanUntil);
+ return date.toString(Qt::SystemLocaleLongDate);
+ }
+ }
+
+ return QVariant();
+}
+
+QVariant BanTableModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if(orientation == Qt::Horizontal)
+ {
+ if(role == Qt::DisplayRole && section < columns.size())
+ {
+ return columns[section];
+ }
+ }
+ return QVariant();
+}
+
+Qt::ItemFlags BanTableModel::flags(const QModelIndex &index) const
+{
+ if(!index.isValid())
+ return 0;
+
+ Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+ return retval;
+}
+
+QModelIndex BanTableModel::index(int row, int column, const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ CCombinedBan *data = priv->index(row);
+
+ if (data)
+ return createIndex(row, column, data);
+ return QModelIndex();
+}
+
+void BanTableModel::refresh()
+{
+ Q_EMIT layoutAboutToBeChanged();
+ priv->refreshBanlist();
+ Q_EMIT layoutChanged();
+}
+
+void BanTableModel::sort(int column, Qt::SortOrder order)
+{
+ priv->sortColumn = column;
+ priv->sortOrder = order;
+ refresh();
+}
+
+bool BanTableModel::shouldShow()
+{
+ if (priv->size() > 0)
+ return true;
+ return false;
+} \ No newline at end of file
diff --git a/src/qt/bantablemodel.h b/src/qt/bantablemodel.h
new file mode 100644
index 0000000000..c21dd04e31
--- /dev/null
+++ b/src/qt/bantablemodel.h
@@ -0,0 +1,72 @@
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_BANTABLEMODEL_H
+#define BITCOIN_QT_BANTABLEMODEL_H
+
+#include "net.h"
+
+#include <QAbstractTableModel>
+#include <QStringList>
+
+class ClientModel;
+class BanTablePriv;
+
+struct CCombinedBan {
+ CSubNet subnet;
+ CBanEntry banEntry;
+};
+
+class BannedNodeLessThan
+{
+public:
+ BannedNodeLessThan(int nColumn, Qt::SortOrder fOrder) :
+ column(nColumn), order(fOrder) {}
+ bool operator()(const CCombinedBan& left, const CCombinedBan& right) const;
+
+private:
+ int column;
+ Qt::SortOrder order;
+};
+
+/**
+ Qt model providing information about connected peers, similar to the
+ "getpeerinfo" RPC call. Used by the rpc console UI.
+ */
+class BanTableModel : public QAbstractTableModel
+{
+ Q_OBJECT
+
+public:
+ explicit BanTableModel(ClientModel *parent = 0);
+ void startAutoRefresh();
+ void stopAutoRefresh();
+
+ enum ColumnIndex {
+ Address = 0,
+ Bantime = 1
+ };
+
+ /** @name Methods overridden from QAbstractTableModel
+ @{*/
+ int rowCount(const QModelIndex &parent) const;
+ int columnCount(const QModelIndex &parent) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+ QModelIndex index(int row, int column, const QModelIndex &parent) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ void sort(int column, Qt::SortOrder order);
+ bool shouldShow();
+ /*@}*/
+
+public Q_SLOTS:
+ void refresh();
+
+private:
+ ClientModel *clientModel;
+ QStringList columns;
+ BanTablePriv *priv;
+};
+
+#endif // BITCOIN_QT_BANTABLEMODEL_H
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index ec02c4be9f..bda8acff15 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -8,12 +8,14 @@
#include "bitcoingui.h"
+#include "chainparams.h"
#include "clientmodel.h"
#include "guiconstants.h"
#include "guiutil.h"
#include "intro.h"
#include "networkstyle.h"
#include "optionsmodel.h"
+#include "platformstyle.h"
#include "splashscreen.h"
#include "utilitydialog.h"
#include "winshutdownmonitor.h"
@@ -24,7 +26,6 @@
#endif
#include "init.h"
-#include "main.h"
#include "rpcserver.h"
#include "scheduler.h"
#include "ui_interface.h"
@@ -59,7 +60,9 @@ Q_IMPORT_PLUGIN(qtwcodecs)
Q_IMPORT_PLUGIN(qkrcodecs)
Q_IMPORT_PLUGIN(qtaccessiblewidgets)
#else
+#if QT_VERSION < 0x050400
Q_IMPORT_PLUGIN(AccessibleFactory)
+#endif
#if defined(QT_QPA_PLATFORM_XCB)
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
#elif defined(QT_QPA_PLATFORM_WINDOWS)
@@ -239,6 +242,7 @@ private:
WalletModel *walletModel;
#endif
int returnValue;
+ const PlatformStyle *platformStyle;
void startThread();
};
@@ -262,13 +266,6 @@ void BitcoinCore::initialize()
{
qDebug() << __func__ << ": Running AppInit2 in thread";
int rv = AppInit2(threadGroup, scheduler);
- if(rv)
- {
- /* Start a dummy RPC thread if no RPC thread is active yet
- * to handle timeouts.
- */
- StartDummyRPCThread();
- }
Q_EMIT initializeResult(rv);
} catch (const std::exception& e) {
handleRunawayException(&e);
@@ -282,7 +279,7 @@ void BitcoinCore::shutdown()
try
{
qDebug() << __func__ << ": Running Shutdown in thread";
- threadGroup.interrupt_all();
+ Interrupt(threadGroup);
threadGroup.join_all();
Shutdown();
qDebug() << __func__ << ": Shutdown finished";
@@ -308,6 +305,22 @@ BitcoinApplication::BitcoinApplication(int &argc, char **argv):
returnValue(0)
{
setQuitOnLastWindowClosed(false);
+
+ // UI per-platform customization
+ // This must be done inside the BitcoinApplication constructor, or after it, because
+ // PlatformStyle::instantiate requires a QApplication
+#if defined(Q_OS_MAC)
+ std::string platformName = "macosx";
+#elif defined(Q_OS_WIN)
+ std::string platformName = "windows";
+#else
+ std::string platformName = "other";
+#endif
+ platformName = GetArg("-uiplatform", platformName);
+ platformStyle = PlatformStyle::instantiate(QString::fromStdString(platformName));
+ if (!platformStyle) // Fall back to "other" if specified name not found
+ platformStyle = PlatformStyle::instantiate("other");
+ assert(platformStyle);
}
BitcoinApplication::~BitcoinApplication()
@@ -328,6 +341,8 @@ BitcoinApplication::~BitcoinApplication()
#endif
delete optionsModel;
optionsModel = 0;
+ delete platformStyle;
+ platformStyle = 0;
}
#ifdef ENABLE_WALLET
@@ -344,7 +359,7 @@ void BitcoinApplication::createOptionsModel()
void BitcoinApplication::createWindow(const NetworkStyle *networkStyle)
{
- window = new BitcoinGUI(networkStyle, 0);
+ window = new BitcoinGUI(platformStyle, networkStyle, 0);
pollShutdownTimer = new QTimer(window);
connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown()));
@@ -419,6 +434,8 @@ void BitcoinApplication::initializeResult(int retval)
returnValue = retval ? 0 : 1;
if(retval)
{
+ // Log this only after AppInit2 finishes, as then logging setup is guaranteed complete
+ qWarning() << "Platform customization:" << platformStyle->getName();
#ifdef ENABLE_WALLET
PaymentServer::LoadRootCAs();
paymentServer->setOptionsModel(optionsModel);
@@ -430,7 +447,7 @@ void BitcoinApplication::initializeResult(int retval)
#ifdef ENABLE_WALLET
if(pwalletMain)
{
- walletModel = new WalletModel(pwalletMain, optionsModel);
+ walletModel = new WalletModel(platformStyle, pwalletMain, optionsModel);
window->addWallet(BitcoinGUI::DEFAULT_WALLET, walletModel);
window->setCurrentWallet(BitcoinGUI::DEFAULT_WALLET);
@@ -546,7 +563,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();
@@ -580,8 +597,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
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 396435f12b..d930d15953 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -13,8 +13,8 @@
#include "openuridialog.h"
#include "optionsdialog.h"
#include "optionsmodel.h"
+#include "platformstyle.h"
#include "rpcconsole.h"
-#include "scicon.h"
#include "utilitydialog.h"
#ifdef ENABLE_WALLET
@@ -60,7 +60,7 @@
const QString BitcoinGUI::DEFAULT_WALLET = "~Default";
-BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
+BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent) :
QMainWindow(parent),
clientModel(0),
walletFrame(0),
@@ -97,8 +97,10 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
trayIconMenu(0),
notificator(0),
rpcConsole(0),
+ helpMessageDialog(0),
prevBlocks(0),
- spinnerFrame(0)
+ spinnerFrame(0),
+ platformStyle(platformStyle)
{
GUIUtil::restoreWindowGeometry("nWindow", QSize(850, 550), this);
@@ -130,12 +132,13 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
setUnifiedTitleAndToolBarOnMac(true);
#endif
- rpcConsole = new RPCConsole(0);
+ rpcConsole = new RPCConsole(platformStyle, 0);
+ helpMessageDialog = new HelpMessageDialog(this, false);
#ifdef ENABLE_WALLET
if(enableWallet)
{
/** Create wallet frame and make it the central widget */
- walletFrame = new WalletFrame(this);
+ walletFrame = new WalletFrame(platformStyle, this);
setCentralWidget(walletFrame);
} else
#endif // ENABLE_WALLET
@@ -175,7 +178,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
frameBlocksLayout->setContentsMargins(3,0,3,0);
frameBlocksLayout->setSpacing(3);
- unitDisplayControl = new UnitDisplayStatusBarControl();
+ unitDisplayControl = new UnitDisplayStatusBarControl(platformStyle);
labelEncryptionIcon = new QLabel();
labelConnectionsIcon = new QLabel();
labelBlocksIcon = new QLabel();
@@ -212,11 +215,6 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
statusBar()->addWidget(progressBar);
statusBar()->addPermanentWidget(frameBlocks);
- connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));
-
- // prevents an open debug window from becoming stuck/unusable on client shutdown
- connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide()));
-
// Install event filter to be able to catch status tip events (QEvent::StatusTip)
this->installEventFilter(this);
@@ -247,36 +245,36 @@ void BitcoinGUI::createActions()
{
QActionGroup *tabGroup = new QActionGroup(this);
- overviewAction = new QAction(SingleColorIcon(":/icons/overview"), tr("&Overview"), this);
+ overviewAction = new QAction(platformStyle->SingleColorIcon(":/icons/overview"), tr("&Overview"), this);
overviewAction->setStatusTip(tr("Show general overview of wallet"));
overviewAction->setToolTip(overviewAction->statusTip());
overviewAction->setCheckable(true);
overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1));
tabGroup->addAction(overviewAction);
- sendCoinsAction = new QAction(SingleColorIcon(":/icons/send"), tr("&Send"), this);
+ sendCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/send"), tr("&Send"), this);
sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address"));
sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
sendCoinsAction->setCheckable(true);
sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
tabGroup->addAction(sendCoinsAction);
- sendCoinsMenuAction = new QAction(TextColorIcon(":/icons/send"), sendCoinsAction->text(), this);
+ sendCoinsMenuAction = new QAction(platformStyle->TextColorIcon(":/icons/send"), sendCoinsAction->text(), this);
sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip());
sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip());
- receiveCoinsAction = new QAction(SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
+ receiveCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)"));
receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
receiveCoinsAction->setCheckable(true);
receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
tabGroup->addAction(receiveCoinsAction);
- receiveCoinsMenuAction = new QAction(TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this);
+ receiveCoinsMenuAction = new QAction(platformStyle->TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this);
receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip());
receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip());
- historyAction = new QAction(SingleColorIcon(":/icons/history"), tr("&Transactions"), this);
+ historyAction = new QAction(platformStyle->SingleColorIcon(":/icons/history"), tr("&Transactions"), this);
historyAction->setStatusTip(tr("Browse transaction history"));
historyAction->setToolTip(historyAction->statusTip());
historyAction->setCheckable(true);
@@ -300,46 +298,46 @@ void BitcoinGUI::createActions()
connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
#endif // ENABLE_WALLET
- quitAction = new QAction(TextColorIcon(":/icons/quit"), tr("E&xit"), this);
+ quitAction = new QAction(platformStyle->TextColorIcon(":/icons/quit"), tr("E&xit"), this);
quitAction->setStatusTip(tr("Quit application"));
quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
quitAction->setMenuRole(QAction::QuitRole);
- aboutAction = new QAction(TextColorIcon(":/icons/about"), tr("&About Bitcoin Core"), this);
+ aboutAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&About Bitcoin Core"), this);
aboutAction->setStatusTip(tr("Show information about Bitcoin Core"));
aboutAction->setMenuRole(QAction::AboutRole);
- aboutQtAction = new QAction(TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this);
+ aboutQtAction = new QAction(platformStyle->TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this);
aboutQtAction->setStatusTip(tr("Show information about Qt"));
aboutQtAction->setMenuRole(QAction::AboutQtRole);
- optionsAction = new QAction(TextColorIcon(":/icons/options"), tr("&Options..."), this);
+ optionsAction = new QAction(platformStyle->TextColorIcon(":/icons/options"), tr("&Options..."), this);
optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin Core"));
optionsAction->setMenuRole(QAction::PreferencesRole);
- toggleHideAction = new QAction(TextColorIcon(":/icons/about"), tr("&Show / Hide"), this);
+ toggleHideAction = new QAction(platformStyle->TextColorIcon(":/icons/about"), tr("&Show / Hide"), this);
toggleHideAction->setStatusTip(tr("Show or hide the main Window"));
- encryptWalletAction = new QAction(TextColorIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
+ encryptWalletAction = new QAction(platformStyle->TextColorIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet"));
encryptWalletAction->setCheckable(true);
- backupWalletAction = new QAction(TextColorIcon(":/icons/filesave"), tr("&Backup Wallet..."), this);
+ backupWalletAction = new QAction(platformStyle->TextColorIcon(":/icons/filesave"), tr("&Backup Wallet..."), this);
backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
- changePassphraseAction = new QAction(TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this);
+ changePassphraseAction = new QAction(platformStyle->TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this);
changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
- signMessageAction = new QAction(TextColorIcon(":/icons/edit"), tr("Sign &message..."), this);
+ signMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/edit"), tr("Sign &message..."), this);
signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
- verifyMessageAction = new QAction(TextColorIcon(":/icons/verify"), tr("&Verify message..."), this);
+ verifyMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/verify"), tr("&Verify message..."), this);
verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
- openRPCConsoleAction = new QAction(TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this);
+ openRPCConsoleAction = new QAction(platformStyle->TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this);
openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console"));
- usedSendingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this);
+ usedSendingAddressesAction = new QAction(platformStyle->TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this);
usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels"));
- usedReceivingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Receiving addresses..."), this);
+ usedReceivingAddressesAction = new QAction(platformStyle->TextColorIcon(":/icons/address-book"), tr("&Receiving addresses..."), this);
usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels"));
- openAction = new QAction(TextColorIcon(":/icons/open"), tr("Open &URI..."), this);
+ openAction = new QAction(platformStyle->TextColorIcon(":/icons/open"), tr("Open &URI..."), this);
openAction->setStatusTip(tr("Open a bitcoin: URI or payment request"));
- showHelpMessageAction = new QAction(TextColorIcon(":/icons/info"), tr("&Command-line options"), this);
+ showHelpMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/info"), tr("&Command-line options"), this);
showHelpMessageAction->setMenuRole(QAction::NoRole);
showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options"));
@@ -349,6 +347,10 @@ void BitcoinGUI::createActions()
connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden()));
connect(showHelpMessageAction, SIGNAL(triggered()), this, SLOT(showHelpMessageClicked()));
+ connect(openRPCConsoleAction, SIGNAL(triggered()), this, SLOT(showDebugWindow()));
+ // prevents an open debug window from becoming stuck/unusable on client shutdown
+ connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide()));
+
#ifdef ENABLE_WALLET
if(walletFrame)
{
@@ -587,11 +589,17 @@ void BitcoinGUI::aboutClicked()
dlg.exec();
}
+void BitcoinGUI::showDebugWindow()
+{
+ rpcConsole->showNormal();
+ rpcConsole->show();
+ rpcConsole->raise();
+ rpcConsole->activateWindow();
+}
+
void BitcoinGUI::showHelpMessageClicked()
{
- HelpMessageDialog *help = new HelpMessageDialog(this, false);
- help->setAttribute(Qt::WA_DeleteOnClose);
- help->show();
+ helpMessageDialog->show();
}
#ifdef ENABLE_WALLET
@@ -650,7 +658,7 @@ void BitcoinGUI::setNumConnections(int count)
case 7: case 8: case 9: icon = ":/icons/connect_3"; break;
default: icon = ":/icons/connect_4"; break;
}
- labelConnectionsIcon->setPixmap(SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+ labelConnectionsIcon->setPixmap(platformStyle->SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count));
}
@@ -691,7 +699,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate)
if(secs < 90*60)
{
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
- labelBlocksIcon->setPixmap(SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
+ labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
#ifdef ENABLE_WALLET
if(walletFrame)
@@ -737,7 +745,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate)
tooltip = tr("Catching up...") + QString("<br>") + tooltip;
if(count != prevBlocks)
{
- labelBlocksIcon->setPixmap(SingleColorIcon(QString(
+ labelBlocksIcon->setPixmap(platformStyle->SingleColorIcon(QString(
":/movies/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')))
.pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES;
@@ -931,7 +939,7 @@ void BitcoinGUI::setEncryptionStatus(int status)
break;
case WalletModel::Unlocked:
labelEncryptionIcon->show();
- labelEncryptionIcon->setPixmap(SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+ labelEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
encryptWalletAction->setChecked(true);
changePassphraseAction->setEnabled(true);
@@ -939,7 +947,7 @@ void BitcoinGUI::setEncryptionStatus(int status)
break;
case WalletModel::Locked:
labelEncryptionIcon->show();
- labelEncryptionIcon->setPixmap(SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+ labelEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
encryptWalletAction->setChecked(true);
changePassphraseAction->setEnabled(true);
@@ -1041,7 +1049,7 @@ void BitcoinGUI::unsubscribeFromCoreSignals()
uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
}
-UnitDisplayStatusBarControl::UnitDisplayStatusBarControl() :
+UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *platformStyle) :
optionsModel(0),
menu(0)
{
@@ -1056,7 +1064,7 @@ UnitDisplayStatusBarControl::UnitDisplayStatusBarControl() :
}
setMinimumSize(max_width, 0);
setAlignment(Qt::AlignRight | Qt::AlignVCenter);
- setStyleSheet(QString("QLabel { color : %1 }").arg(SingleColor().name()));
+ setStyleSheet(QString("QLabel { color : %1 }").arg(platformStyle->SingleColor().name()));
}
/** So that it responds to button clicks */
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 4e50b1712a..717f2bd12d 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -22,11 +22,13 @@ class ClientModel;
class NetworkStyle;
class Notificator;
class OptionsModel;
+class PlatformStyle;
class RPCConsole;
class SendCoinsRecipient;
class UnitDisplayStatusBarControl;
class WalletFrame;
class WalletModel;
+class HelpMessageDialog;
class CWallet;
@@ -47,7 +49,7 @@ class BitcoinGUI : public QMainWindow
public:
static const QString DEFAULT_WALLET;
- explicit BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent = 0);
+ explicit BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent = 0);
~BitcoinGUI();
/** Set the client model.
@@ -112,11 +114,14 @@ private:
QMenu *trayIconMenu;
Notificator *notificator;
RPCConsole *rpcConsole;
+ HelpMessageDialog *helpMessageDialog;
/** Keep track of previous number of blocks, to detect progress */
int prevBlocks;
int spinnerFrame;
+ const PlatformStyle *platformStyle;
+
/** Create the main UI actions. */
void createActions();
/** Create the menu bar and sub-menus. */
@@ -191,6 +196,8 @@ private Q_SLOTS:
void optionsClicked();
/** Show about dialog */
void aboutClicked();
+ /** Show debug window */
+ void showDebugWindow();
/** Show help message dialog */
void showHelpMessageClicked();
#ifndef Q_OS_MAC
@@ -215,7 +222,7 @@ class UnitDisplayStatusBarControl : public QLabel
Q_OBJECT
public:
- explicit UnitDisplayStatusBarControl();
+ explicit UnitDisplayStatusBarControl(const PlatformStyle *platformStyle);
/** Lets the control know about the Options Model (and its signals) */
void setOptionsModel(OptionsModel *optionsModel);
diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp
index b259d038f2..3cde2657cf 100644
--- a/src/qt/bitcoinstrings.cpp
+++ b/src/qt/bitcoinstrings.cpp
@@ -17,9 +17,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or "
"a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"An error occurred while setting up the RPC address %s port %u for listening: "
-"%s"),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Bind to given address and always listen on it. Use [host]:port notation for "
"IPv6"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
@@ -33,9 +30,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Cannot obtain a lock on data directory %s. Bitcoin Core is probably already "
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Continuously rate-limit free transactions to <n>*1000 bytes per minute "
-"(default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Create new files with system default permissions, instead of umask 077 (only "
"effective with disabled wallet functionality)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
@@ -48,9 +42,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Distributed under the MIT software license, see the accompanying file "
"COPYING or <http://www.opensource.org/licenses/mit-license.php>."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Enter regression test mode, which uses a special chain in which blocks can "
-"be solved instantly."),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error: Listening for incoming connections failed (listen returned error %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error: Unsupported argument -socks found. Setting SOCKS version isn't "
@@ -65,42 +56,40 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Execute command when the best block changes (%s in cmd is replaced by block "
"hash)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Fees (in BTC/Kb) smaller than this are considered zero fee for relaying "
+"Fees (in %s/kB) smaller than this are considered zero fee for relaying "
"(default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Fees (in BTC/Kb) smaller than this are considered zero fee for transaction "
-"creation (default: %s)"),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Flush database activity from memory pool to disk log every <n> megabytes "
-"(default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"How thorough the block verification of -checkblocks is (0-4, default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"If <category> is not supplied or if <category> = 1, output all debugging "
+"information."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"If paytxfee is not set, include enough fee so transactions begin "
"confirmation on average within n blocks (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"In this mode -genproclimit controls how many blocks are generated "
-"immediately."),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay "
"fee of %s to prevent stuck transactions)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Log transaction priority and fee per kB when mining blocks (default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Maintain a full transaction index, used by the getrawtransaction rpc call "
"(default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Maximum size of data in data carrier transactions we relay and mine "
"(default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Maximum total fees to use in a single wallet transaction; setting this too "
-"low may abort large transactions (default: %s)"),
+"Maximum total fees (in %s) to use in a single wallet transaction; setting "
+"this too low may abort large transactions (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Number of seconds to keep misbehaving peers from reconnecting (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Output debugging information (default: %u, supplying <category> is optional)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Prune configured below the minimum of %d MB. Please use a higher number."),
+"Please check that your computer's date and time are correct! If your clock "
+"is wrong Bitcoin Core will not work properly."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Prune configured below the minimum of %d MiB. Please use a higher number."),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Prune: last wallet synchronisation goes beyond pruned data. You need to -"
+"reindex (download the whole blockchain again in case of pruned node)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Query for peer addresses via DNS lookup, if low on addresses (default: 1 "
"unless -connect)"),
@@ -108,13 +97,13 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Randomize credentials for every proxy connection. This enables Tor stream "
"isolation (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Reduce storage requirements by pruning (deleting) old blocks. This mode "
-"disables wallet support and is incompatible with -txindex. Warning: "
-"Reverting this setting requires re-downloading the entire blockchain. "
-"(default: 0 = disable pruning blocks, >%u = target size in MiB to use for "
-"block files)"),
+"Reduce storage requirements by pruning (deleting) old blocks. This mode is "
+"incompatible with -txindex and -rescan. Warning: Reverting this setting "
+"requires re-downloading the entire blockchain. (default: 0 = disable pruning "
+"blocks, >%u = target size in MiB to use for block files)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Require high priority for relaying free or low-fee transactions (default: %u)"),
+"Rescans are not possible in pruned mode. You will need to use -reindex which "
+"will download the whole blockchain again."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
@@ -124,6 +113,11 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Set the number of threads for coin generation if enabled (-1 = all cores, "
"default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"The block database contains a block which appears to be from the future. "
+"This may be due to your computer's date and time being set incorrectly. Only "
+"rebuild the block database if you are sure that your computer's date and "
+"time are correct"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"The transaction amount is too small to send after the fee has been deducted"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"This is a pre-release test build - use at your own risk - do not use for "
@@ -133,34 +127,26 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software "
"written by Eric Young and UPnP software written by Thomas Bernard."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"To use bitcoind, or the -server option to bitcoin-qt, you must set an "
-"rpcpassword in the configuration file:\n"
-"%s\n"
-"It is recommended you use the following random password:\n"
-"rpcuser=bitcoinrpc\n"
-"rpcpassword=%s\n"
-"(you do not need to remember this password)\n"
-"The username and password MUST NOT be the same.\n"
-"If the file does not exist, create it with owner-readable-only file "
-"permissions.\n"
-"It is also recommended to set alertnotify so you are notified of problems;\n"
-"for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Unable to bind to %s on this computer. Bitcoin Core is probably already "
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Use UPnP to map the listening port (default: 1 when listening and no -proxy)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: "
"%s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"WARNING: abnormally high number of blocks generated, %d blocks received in "
+"the last %d hours (%d expected)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"WARNING: check your network connection, %d blocks received in the last %d "
+"hours (%d expected)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: -maxtxfee is set very high! Fees this large could be paid on a "
"single transaction."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: -paytxfee is set very high! This is the transaction fee you will "
"pay if you send a transaction."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Warning: Please check that your computer's date and time are correct! If "
-"your clock is wrong Bitcoin Core will not work properly."),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: The network does not appear to fully agree! Some miners appear to "
"be experiencing issues."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
@@ -189,15 +175,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "<category> can be:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1 if no -proxy or -connect)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept public REST requests (default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Acceptable ciphers (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Activating best chain..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"),
QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Allow self signed root certificates (default: 0)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Always query for peer addresses via DNS lookup (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to recover private keys from a corrupt wallet.dat"),
QT_TRANSLATE_NOOP("bitcoin-core", "Block creation options:"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Can't run with a wallet in prune mode."),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"),
@@ -210,12 +193,14 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses,
QT_TRANSLATE_NOOP("bitcoin-core", "Connection options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Copyright (C) 2009-%i The Bitcoin Core Developers"),
QT_TRANSLATE_NOOP("bitcoin-core", "Corrupted block database detected"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Could not parse -rpcbind value %s as network address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Debugging/Testing options:"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Disable safemode, override a real safe mode event (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Do not load the wallet and disable wallet RPC calls"),
QT_TRANSLATE_NOOP("bitcoin-core", "Do you want to rebuild the block database now?"),
QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish hash block in <address>"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish hash transaction in <address>"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish raw block in <address>"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Enable publish raw transaction in <address>"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing block database"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing wallet database environment %s!"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading block database"),
@@ -225,15 +210,13 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires new
QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error reading from database, shutting down."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occured, see debug.log for details"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occurred, see debug.log for details"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unsupported argument -tor found, use -onion."),
QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."),
-QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in BTC/kB) to add to transactions you send (default: %s)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Force safe mode (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in %s/kB) to add to transactions you send (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: %u, 0 = all)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "If <category> is not supplied, output all debugging information."),
QT_TRANSLATE_NOOP("bitcoin-core", "Importing..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000??.dat file"),
QT_TRANSLATE_NOOP("bitcoin-core", "Include IP addresses in debug output (default: %u)"),
@@ -250,7 +233,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s' (
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable transactions in memory (default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Limit size of signature cache to <n> entries (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: %u or testnet: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
@@ -263,29 +245,24 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000
QT_TRANSLATE_NOOP("bitcoin-core", "Need to specify a port with -whitebind: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Node relay options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Not enough file descriptors available."),
-QT_TRANSLATE_NOOP("bitcoin-core", "Only accept block chain matching built-in checkpoints (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (ipv4, ipv6 or onion)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Prune cannot be configured with a negative value."),
QT_TRANSLATE_NOOP("bitcoin-core", "Prune mode is incompatible with -txindex."),
-QT_TRANSLATE_NOOP("bitcoin-core", "RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Pruning blockstore..."),
QT_TRANSLATE_NOOP("bitcoin-core", "RPC server options:"),
-QT_TRANSLATE_NOOP("bitcoin-core", "RPC support for HTTP persistent connections (default: %d)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Randomly drop 1 of every <n> network messages"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Randomly fuzz 1 of every <n> network messages"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild block chain index from current blk000??.dat files on startup"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Receive and display P2P network alerts (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Reducing -maxconnections from %d to %d, because of system limitations."),
QT_TRANSLATE_NOOP("bitcoin-core", "Relay and mine data carrier transactions (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Relay non-P2SH multisig (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."),
-QT_TRANSLATE_NOOP("bitcoin-core", "Run a thread to flush wallet periodically (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: %s)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set SSL root certificates for payment request (default: -system-)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: %u)"),
@@ -293,7 +270,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Set language, for example \"de_DE\" (default:
QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: %d)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set minimum block size in bytes (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: %d)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Show all debugging options (usage: --help -help-debug)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Show splash screen on startup (default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Shrink debug.log file on client startup (default: 1 when no -debug)"),
@@ -306,11 +282,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)")
QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Stop running after importing blocks from disk (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "The transaction amount is too small to pay the fee"),
QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."),
-QT_TRANSLATE_NOOP("bitcoin-core", "This is intended for regression testing tools and app development."),
QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amount too small"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"),
@@ -318,11 +292,10 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large for fee policy"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large"),
QT_TRANSLATE_NOOP("bitcoin-core", "UI Options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Unable to start HTTP server. See debug log for details."),
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: %u)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: 1 when listening)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"),
QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Verifying blocks..."),
@@ -336,6 +309,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -benchmark igno
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Unsupported argument -debugnet ignored, use -debug=net."),
QT_TRANSLATE_NOOP("bitcoin-core", "You need to rebuild the database using -reindex to change -txindex"),
QT_TRANSLATE_NOOP("bitcoin-core", "Zapping all transactions from wallet..."),
+QT_TRANSLATE_NOOP("bitcoin-core", "ZeroMQ notification options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "on startup"),
QT_TRANSLATE_NOOP("bitcoin-core", "wallet.dat corrupt, salvage failed"),
};
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 92a9ef279d..0900a35cc4 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -4,6 +4,7 @@
#include "clientmodel.h"
+#include "bantablemodel.h"
#include "guiconstants.h"
#include "peertablemodel.h"
@@ -11,7 +12,6 @@
#include "chainparams.h"
#include "checkpoints.h"
#include "clientversion.h"
-#include "main.h"
#include "net.h"
#include "ui_interface.h"
#include "util.h"
@@ -27,6 +27,7 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
QObject(parent),
optionsModel(optionsModel),
peerTableModel(0),
+ banTableModel(0),
cachedNumBlocks(0),
cachedBlockDate(QDateTime()),
cachedReindexing(0),
@@ -34,6 +35,7 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
pollTimer(0)
{
peerTableModel = new PeerTableModel(this);
+ banTableModel = new BanTableModel(this);
pollTimer = new QTimer(this);
connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
pollTimer->start(MODEL_UPDATE_DELAY);
@@ -177,11 +179,21 @@ PeerTableModel *ClientModel::getPeerTableModel()
return peerTableModel;
}
+BanTableModel *ClientModel::getBanTableModel()
+{
+ return banTableModel;
+}
+
QString ClientModel::formatFullVersion() const
{
return QString::fromStdString(FormatFullVersion());
}
+QString ClientModel::formatSubVersion() const
+{
+ return QString::fromStdString(strSubVersion);
+}
+
QString ClientModel::formatBuildDate() const
{
return QString::fromStdString(CLIENT_DATE);
@@ -202,6 +214,11 @@ QString ClientModel::formatClientStartupTime() const
return QDateTime::fromTime_t(nClientStartupTime).toString();
}
+void ClientModel::updateBanlist()
+{
+ banTableModel->refresh();
+}
+
// Handlers for core signals
static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
{
@@ -226,12 +243,19 @@ static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, Ch
Q_ARG(int, status));
}
+static void BannedListChanged(ClientModel *clientmodel)
+{
+ qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
+ QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
+}
+
void ClientModel::subscribeToCoreSignals()
{
// Connect signals to client
uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2));
+ uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
}
void ClientModel::unsubscribeFromCoreSignals()
@@ -240,4 +264,5 @@ void ClientModel::unsubscribeFromCoreSignals()
uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2));
+ uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
}
diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h
index 68434f404c..627bdf862d 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -9,6 +9,7 @@
#include <QDateTime>
class AddressTableModel;
+class BanTableModel;
class OptionsModel;
class PeerTableModel;
class TransactionTableModel;
@@ -44,6 +45,7 @@ public:
OptionsModel *getOptionsModel();
PeerTableModel *getPeerTableModel();
+ BanTableModel *getBanTableModel();
//! Return number of connections, default is in- and outbound (total)
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
@@ -63,6 +65,7 @@ public:
QString getStatusBarWarnings() const;
QString formatFullVersion() const;
+ QString formatSubVersion() const;
QString formatBuildDate() const;
bool isReleaseVersion() const;
QString clientName() const;
@@ -71,6 +74,7 @@ public:
private:
OptionsModel *optionsModel;
PeerTableModel *peerTableModel;
+ BanTableModel *banTableModel;
int cachedNumBlocks;
QDateTime cachedBlockDate;
@@ -98,6 +102,7 @@ public Q_SLOTS:
void updateTimer();
void updateNumConnections(int numConnections);
void updateAlert(const QString &hash, int status);
+ void updateBanlist();
};
#endif // BITCOIN_QT_CLIENTMODEL_H
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index 778dbcb1ca..51008ad2de 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -9,12 +9,13 @@
#include "bitcoinunits.h"
#include "guiutil.h"
#include "optionsmodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
+#include "txmempool.h"
#include "walletmodel.h"
#include "coincontrol.h"
#include "init.h"
-#include "main.h"
+#include "main.h" // For minRelayTxFee
#include "wallet/wallet.h"
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
@@ -34,10 +35,11 @@ QList<CAmount> CoinControlDialog::payAmounts;
CCoinControl* CoinControlDialog::coinControl = new CCoinControl();
bool CoinControlDialog::fSubtractFeeFromAmount = false;
-CoinControlDialog::CoinControlDialog(QWidget *parent) :
+CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent) :
QDialog(parent),
ui(new Ui::CoinControlDialog),
- model(0)
+ model(0),
+ platformStyle(platformStyle)
{
ui->setupUi(this);
@@ -279,7 +281,7 @@ void CoinControlDialog::lockCoin()
COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
model->lockCoin(outpt);
contextMenuItem->setDisabled(true);
- contextMenuItem->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed"));
+ contextMenuItem->setIcon(COLUMN_CHECKBOX, platformStyle->SingleColorIcon(":/icons/lock_closed"));
updateLabelLocked();
}
@@ -790,7 +792,7 @@ void CoinControlDialog::updateView()
COutPoint outpt(txhash, out.i);
coinControl->UnSelect(outpt); // just to be sure
itemOutput->setDisabled(true);
- itemOutput->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed"));
+ itemOutput->setIcon(COLUMN_CHECKBOX, platformStyle->SingleColorIcon(":/icons/lock_closed"));
}
// set checkbox
diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h
index 0566b02c96..8ff1eac709 100644
--- a/src/qt/coincontroldialog.h
+++ b/src/qt/coincontroldialog.h
@@ -16,6 +16,7 @@
#include <QString>
#include <QTreeWidgetItem>
+class PlatformStyle;
class WalletModel;
class CCoinControl;
@@ -32,7 +33,7 @@ class CoinControlDialog : public QDialog
Q_OBJECT
public:
- explicit CoinControlDialog(QWidget *parent = 0);
+ explicit CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent = 0);
~CoinControlDialog();
void setModel(WalletModel *model);
@@ -57,6 +58,8 @@ private:
QAction *lockAction;
QAction *unlockAction;
+ const PlatformStyle *platformStyle;
+
QString strPad(QString, int, QString);
void sortView(int, Qt::SortOrder);
void updateView();
diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/debugwindow.ui
index 7ae8237476..4117da57f5 100644
--- a/src/qt/forms/rpcconsole.ui
+++ b/src/qt/forms/debugwindow.ui
@@ -87,6 +87,32 @@
</widget>
</item>
<item row="3" column="0">
+ <widget class="QLabel" name="labelClientUserAgent">
+ <property name="text">
+ <string>User Agent</string>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="clientUserAgent">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Using OpenSSL version</string>
@@ -96,7 +122,7 @@
</property>
</widget>
</item>
- <item row="3" column="1">
+ <item row="4" column="1">
<widget class="QLabel" name="openSSLVersion">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -112,7 +138,7 @@
</property>
</widget>
</item>
- <item row="4" column="0">
+ <item row="5" column="0">
<widget class="QLabel" name="label_berkeleyDBVersion">
<property name="text">
<string>Using BerkeleyDB version</string>
@@ -122,7 +148,7 @@
</property>
</widget>
</item>
- <item row="4" column="1">
+ <item row="5" column="1">
<widget class="QLabel" name="berkeleyDBVersion">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -138,14 +164,14 @@
</property>
</widget>
</item>
- <item row="5" column="0">
+ <item row="6" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Build date</string>
</property>
</widget>
</item>
- <item row="5" column="1">
+ <item row="6" column="1">
<widget class="QLabel" name="buildDate">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -161,14 +187,14 @@
</property>
</widget>
</item>
- <item row="6" column="0">
+ <item row="7" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Startup time</string>
</property>
</widget>
</item>
- <item row="6" column="1">
+ <item row="7" column="1">
<widget class="QLabel" name="startupTime">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -184,7 +210,7 @@
</property>
</widget>
</item>
- <item row="7" column="0">
+ <item row="8" column="0">
<widget class="QLabel" name="label_11">
<property name="font">
<font>
@@ -197,14 +223,14 @@
</property>
</widget>
</item>
- <item row="8" column="0">
+ <item row="9" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
- <item row="8" column="1">
+ <item row="9" column="1">
<widget class="QLabel" name="networkName">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -220,14 +246,14 @@
</property>
</widget>
</item>
- <item row="9" column="0">
+ <item row="10" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Number of connections</string>
</property>
</widget>
</item>
- <item row="9" column="1">
+ <item row="10" column="1">
<widget class="QLabel" name="numberOfConnections">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -243,7 +269,7 @@
</property>
</widget>
</item>
- <item row="10" column="0">
+ <item row="11" column="0">
<widget class="QLabel" name="label_10">
<property name="font">
<font>
@@ -256,14 +282,14 @@
</property>
</widget>
</item>
- <item row="11" column="0">
+ <item row="12" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Current number of blocks</string>
</property>
</widget>
</item>
- <item row="11" column="1">
+ <item row="12" column="1">
<widget class="QLabel" name="numberOfBlocks">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -279,14 +305,14 @@
</property>
</widget>
</item>
- <item row="12" column="0">
+ <item row="13" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Last block time</string>
</property>
</widget>
</item>
- <item row="12" column="1">
+ <item row="13" column="1">
<widget class="QLabel" name="lastBlockTime">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -302,7 +328,7 @@
</property>
</widget>
</item>
- <item row="13" column="0">
+ <item row="14" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -315,7 +341,7 @@
</property>
</spacer>
</item>
- <item row="14" column="0">
+ <item row="15" column="0">
<widget class="QLabel" name="labelDebugLogfile">
<property name="font">
<font>
@@ -328,7 +354,7 @@
</property>
</widget>
</item>
- <item row="15" column="0">
+ <item row="16" column="0">
<widget class="QPushButton" name="openDebugLogfileButton">
<property name="toolTip">
<string>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</string>
@@ -341,7 +367,7 @@
</property>
</widget>
</item>
- <item row="16" column="0">
+ <item row="17" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -687,17 +713,85 @@
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" rowspan="2">
- <widget class="QTableView" name="peerWidget">
- <property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAsNeeded</enum>
- </property>
- <property name="sortingEnabled">
- <bool>true</bool>
+ <layout class="QVBoxLayout" name="verticalLayout_101">
+ <property name="spacing">
+ <number>0</number>
</property>
- <attribute name="horizontalHeaderHighlightSections">
- <bool>false</bool>
- </attribute>
- </widget>
+ <item>
+ <widget class="QTableView" name="peerWidget">
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAsNeeded</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <attribute name="horizontalHeaderHighlightSections">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="banHeading">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>12</pointsize>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>Banned peers</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::NoTextInteraction</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTableView" name="banlistWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAsNeeded</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <attribute name="horizontalHeaderHighlightSections">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
</item>
<item row="0" column="1">
<widget class="QLabel" name="peerHeading">
diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui
index 55c4f5ac58..22c67b8040 100644
--- a/src/qt/forms/optionsdialog.ui
+++ b/src/qt/forms/optionsdialog.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>560</width>
- <height>400</height>
+ <height>440</height>
</rect>
</property>
<property name="windowTitle">
@@ -298,6 +298,193 @@
</layout>
</item>
<item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2_Network">
+ <item>
+ <widget class="QLabel" name="proxyActiveNets">
+ <property name="text">
+ <string>Used for reaching peers via:</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="proxyReachIPv4">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="proxyReachIPv4Label">
+ <property name="text">
+ <string>IPv4</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="proxyReachIPv6">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="proxyReachIPv6Label">
+ <property name="text">
+ <string>IPv6</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="proxyReachTor">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="proxyReachTorLabel">
+ <property name="text">
+ <string>Tor</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2_Network">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="connectSocksTor">
+ <property name="toolTip">
+ <string>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</string>
+ </property>
+ <property name="text">
+ <string>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3_Network">
+ <item>
+ <widget class="QLabel" name="proxyIpTorLabel">
+ <property name="text">
+ <string>Proxy &amp;IP:</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="buddy">
+ <cstring>proxyIpTor</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QValidatedLineEdit" name="proxyIpTor">
+ <property name="minimumSize">
+ <size>
+ <width>140</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>140</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="proxyPortTorLabel">
+ <property name="text">
+ <string>&amp;Port:</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="buddy">
+ <cstring>proxyPortTor</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="proxyPortTor">
+ <property name="minimumSize">
+ <size>
+ <width>55</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>55</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Port of the proxy (e.g. 9050)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4_Network">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
<spacer name="verticalSpacer_Network">
<property name="orientation">
<enum>Qt::Vertical</enum>
diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h
index a0a2993ea3..7d3e48ff32 100644
--- a/src/qt/guiconstants.h
+++ b/src/qt/guiconstants.h
@@ -42,7 +42,7 @@ static const int MAX_URI_LENGTH = 255;
#define EXPORT_IMAGE_SIZE 256
/* Number of frames in spinner animation */
-#define SPINNER_FRAMES 35
+#define SPINNER_FRAMES 36
#define QAPP_ORG_NAME "Bitcoin"
#define QAPP_ORG_DOMAIN "bitcoin.org"
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 581d2321bc..8917f77f22 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -11,7 +11,7 @@
#include "primitives/transaction.h"
#include "init.h"
-#include "main.h"
+#include "main.h" // For minRelayTxFee
#include "protocol.h"
#include "script/script.h"
#include "script/standard.h"
@@ -404,7 +404,7 @@ void SubstituteFonts(const QString& language)
{
#if defined(Q_OS_MAC)
// Background:
-// OSX's default font changed in 10.9 and QT is unable to find it with its
+// OSX's default font changed in 10.9 and Qt is unable to find it with its
// usual fallback methods when building against the 10.7 sdk or lower.
// The 10.8 SDK added a function to let it find the correct fallback font.
// If this fallback is not properly loaded, some characters may fail to
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
index 117969758c..4ab87e0f32 100644
--- a/src/qt/intro.cpp
+++ b/src/qt/intro.cpp
@@ -6,7 +6,6 @@
#include "ui_intro.h"
#include "guiutil.h"
-#include "scicon.h"
#include "util.h"
@@ -168,7 +167,7 @@ void Intro::pickDataDirectory()
/* If current default data directory does not exist, let the user choose one */
Intro intro;
intro.setDataDirectory(dataDir);
- intro.setWindowIcon(SingleColorIcon(":icons/bitcoin"));
+ intro.setWindowIcon(QIcon(":icons/bitcoin"));
while(true)
{
diff --git a/src/qt/locale/bitcoin_ach.ts b/src/qt/locale/bitcoin_ach.ts
index 835ddb8eaa..ddb9fb85ce 100644
--- a/src/qt/locale/bitcoin_ach.ts
+++ b/src/qt/locale/bitcoin_ach.ts
@@ -1,4 +1,4 @@
-<TS language="ach" version="2.1">
+<TS language="ach" version="2.0">
<context>
<name>AddressBookPage</name>
</context>
diff --git a/src/qt/locale/bitcoin_af_ZA.ts b/src/qt/locale/bitcoin_af_ZA.ts
index 5ef7d3fd37..3767a4c830 100644
--- a/src/qt/locale/bitcoin_af_ZA.ts
+++ b/src/qt/locale/bitcoin_af_ZA.ts
@@ -1,4 +1,4 @@
-<TS language="af_ZA" version="2.1">
+<TS language="af_ZA" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts
index 235b22cd1f..e56083fa2c 100644
--- a/src/qt/locale/bitcoin_ar.ts
+++ b/src/qt/locale/bitcoin_ar.ts
@@ -1,4 +1,4 @@
-<TS language="ar" version="2.1">
+<TS language="ar" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_be_BY.ts b/src/qt/locale/bitcoin_be_BY.ts
index b727b75566..5f7f6f89bf 100644
--- a/src/qt/locale/bitcoin_be_BY.ts
+++ b/src/qt/locale/bitcoin_be_BY.ts
@@ -1,4 +1,4 @@
-<TS language="be_BY" version="2.1">
+<TS language="be_BY" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts
index c86fdd42dd..e2821dbdef 100644
--- a/src/qt/locale/bitcoin_bg.ts
+++ b/src/qt/locale/bitcoin_bg.ts
@@ -1,4 +1,4 @@
-<TS language="bg" version="2.1">
+<TS language="bg" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -1955,6 +1955,14 @@
<translation>Дебит</translation>
</message>
<message>
+ <source>Total debit</source>
+ <translation>Общ дълг</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Общ дълг</translation>
+ </message>
+ <message>
<source>Transaction fee</source>
<translation>Такса</translation>
</message>
@@ -1979,6 +1987,10 @@
<translation>Търговец</translation>
</message>
<message>
+ <source>Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source>
+ <translation>Генерираните монети трябва да отлежат %1 блока преди да могат да бъдат похарчени. Когато генерираш блока, той се разпространява в мрежата, за да се добави в блок-веригата. Ако не успее да се добави във веригата, неговия статус ще се стане "неприет" и няма да може да се похарчи. Това е възможно да се случи случайно, ако друг възел генерира блок няколко секунди след твоя.</translation>
+ </message>
+ <message>
<source>Debug information</source>
<translation>Информация за грешките</translation>
</message>
@@ -2029,6 +2041,10 @@
<translation>Тип</translation>
</message>
<message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Неплатим (%1 потвърждения, ще бъде платим след %2)</translation>
+ </message>
+ <message>
<source>Open until %1</source>
<translation>Подлежи на промяна до %1</translation>
</message>
diff --git a/src/qt/locale/bitcoin_bs.ts b/src/qt/locale/bitcoin_bs.ts
index fc5e6d270e..86526022fe 100644
--- a/src/qt/locale/bitcoin_bs.ts
+++ b/src/qt/locale/bitcoin_bs.ts
@@ -1,4 +1,4 @@
-<TS language="bs" version="2.1">
+<TS language="bs" version="2.0">
<context>
<name>AddressBookPage</name>
</context>
diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts
index f7d97eb061..ceb71469cb 100644
--- a/src/qt/locale/bitcoin_ca.ts
+++ b/src/qt/locale/bitcoin_ca.ts
@@ -1,4 +1,4 @@
-<TS language="ca" version="2.1">
+<TS language="ca" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -168,6 +168,10 @@
<translation>Esteu segur que voleu encriptar el vostre moneder?</translation>
</message>
<message>
+ <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>Ara es tancarà el Bitcoin Core per finalitzar el procés d'encriptació. Tingueu present que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguin ser robades per programari maliciós que infecti l'ordinador.</translation>
+ </message>
+ <message>
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
<translation>IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder.</translation>
</message>
@@ -184,6 +188,10 @@
<translation>Introduïu la contrasenya nova al moneder.&lt;br/&gt;Utilitzeu una contrasenya de &lt;b&gt;deu o més caràcters aleatoris&lt;/b&gt;, o &lt;b&gt;vuit o més paraules&lt;/b&gt;.</translation>
</message>
<message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Introduïu la contrasenya antiga i la contrasenya nova al moneder.</translation>
+ </message>
+ <message>
<source>Wallet encryption failed</source>
<translation>L'encriptació del moneder ha fallat</translation>
</message>
@@ -391,6 +399,10 @@
<translation>&amp;Quant al Bitcoin Core</translation>
</message>
<message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modifica les opcions de configuració del Bitcoin Core</translation>
+ </message>
+ <message>
<source>Show the list of used sending addresses and labels</source>
<translation>Mostra la llista d'adreces d'enviament i etiquetes utilitzades</translation>
</message>
@@ -419,6 +431,10 @@
<translation>No hi ha cap font de bloc disponible...</translation>
</message>
<message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>S'han processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation>
+ </message>
+ <message numerus="yes">
<source>%n hour(s)</source>
<translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation>
</message>
@@ -471,6 +487,36 @@
<translation>S'està posant al dia ...</translation>
</message>
<message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Import: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tipus: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Etiqueta: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adreça: %1
+</translation>
+ </message>
+ <message>
<source>Sent transaction</source>
<translation>Transacció enviada</translation>
</message>
@@ -669,6 +715,18 @@
<translation>cap</translation>
</message>
<message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana».</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Aquesta etiqueta es torna vermella si el destinatari rep un import inferior de %1.</translation>
+ </message>
+ <message>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation>Pot variar +/- %1 satoshi(s) per entrada.</translation>
</message>
@@ -919,6 +977,14 @@
<translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
</message>
<message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimitza en comptes de sortir de l'aplicació quan la finestra es tanca. Quan s'habilita aquesta opció l'aplicació es tancara només quan se selecciona Surt del menú. </translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>La interfície d'usuari pot definir-se des d'aquí. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
<translation>URL de terceres parts (p. ex. explorador de blocs) que apareix en la pestanya de transaccions com elements del menú contextual. %s en l'URL es reemplaçat pel resum de la transacció. Diferents URL estan separades per una barra vertical |.</translation>
</message>
@@ -943,6 +1009,14 @@
<translation>&amp;Xarxa</translation>
</message>
<message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Inicia el Bitcoin Core en inciar el sistema</translation>
+ </message>
+ <message>
<source>(0 = auto, &lt;0 = leave that many cores free)</source>
<translation>(0 = auto, &lt;0 = deixa tants nuclis lliures)</translation>
</message>
@@ -1055,6 +1129,10 @@
<translation>Cal reiniciar el client per activar els canvis.</translation>
</message>
<message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>S'aturarà el client. Voleu procedir?</translation>
+ </message>
+ <message>
<source>This change would require a client restart.</source>
<translation>Amb aquest canvi cal un reinici del client.</translation>
</message>
@@ -1189,10 +1267,18 @@
<translation>No es pot llegir el fitxer de la sol·licitud de pagament. Això pot ser causat per un fitxer de sol·licitud de pagament no vàlid.</translation>
</message>
<message>
+ <source>Payment request expired.</source>
+ <translation>La sol·licitud de pagament ha vençut.</translation>
+ </message>
+ <message>
<source>Unverified payment requests to custom payment scripts are unsupported.</source>
<translation>No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats.</translation>
</message>
<message>
+ <source>Invalid payment request.</source>
+ <translation>Sol·licitud de pagament no vàlida.</translation>
+ </message>
+ <message>
<source>Refund from %1</source>
<translation>Reemborsament de %1</translation>
</message>
@@ -1232,6 +1318,10 @@
<translation>Agent d'usuari</translation>
</message>
<message>
+ <source>Node/Service</source>
+ <translation>Node/Servei</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Temps de ping</translation>
</message>
@@ -1353,6 +1443,10 @@
<translation>Nombre de blocs actuals</translation>
</message>
<message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Obre el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans.</translation>
+ </message>
+ <message>
<source>Received</source>
<translation>Rebut</translation>
</message>
@@ -1421,6 +1515,10 @@
<translation>Temps de ping</translation>
</message>
<message>
+ <source>Time Offset</source>
+ <translation>Diferència horària</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Últim temps de bloc</translation>
</message>
@@ -1465,6 +1563,10 @@
<translation>Neteja la consola</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>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
<translation>Utilitza les fletxes d'amunt i avall per navegar per l'historial, i &lt;b&gt;Ctrl-L&lt;\b&gt; per netejar la pantalla.</translation>
</message>
@@ -1761,6 +1863,10 @@
<translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation>
</message>
<message>
+ <source>Hide</source>
+ <translation>Amaga</translation>
+ </message>
+ <message>
<source>total at least</source>
<translation>total com a mínim</translation>
</message>
@@ -1901,10 +2007,30 @@
<translation>S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'haguessin gastat monedes de la còpia però sense marcar-les-hi com a gastades.</translation>
</message>
<message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Una comissió superior a %1 es considera una comissió absurdament alta.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>La sol·licitud de pagament ha vençut.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation>
+ </message>
+ <message>
<source>Pay only the minimum fee of %1</source>
<translation>Paga només la comissió mínima de %1</translation>
</message>
<message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada.</translation>
+ </message>
+ <message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Avís: adreça Bitcoin no vàlida</translation>
</message>
@@ -1976,10 +2102,26 @@
<translation>Elimina aquesta entrada</translation>
</message>
<message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>La comissió es deduirà de l'import que s'enviarà. El destinatari rebrà menys bitcoins que les que introduïu al camp d'import. Si se seleccionen múltiples destinataris, la comissió es dividirà per igual.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>S&amp;ubstreu la comissió de l'import</translation>
+ </message>
+ <message>
<source>Message:</source>
<translation>Missatge:</translation>
</message>
<message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Aquesta és una sol·licitud de pagament no autenticada.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Aquesta és una sol·licitud de pagament autenticada.</translation>
+ </message>
+ <message>
<source>Enter a label for this address to add it to the list of used addresses</source>
<translation>Introduïu una etiqueta per a aquesta adreça per afegir-la a la llista d'adreces utilitzades</translation>
</message>
@@ -2018,6 +2160,10 @@
<translation>&amp;Signa el missatge</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>Podeu signar missatges/acords amb les vostres adreces per provar que rebeu les bitcoins que s'hi envien. Aneu amb compte no signar res que sigui vague o aleatori, perquè en alguns atacs de suplantació es pot provar que hi signeu la vostra identitat. Només signeu aquelles declaracions completament detallades en què hi esteu d'acord. </translation>
+ </message>
+ <message>
<source>The Bitcoin address to sign the message with</source>
<translation>L'adreça Bitcoin amb què signar el missatge</translation>
</message>
@@ -2070,6 +2216,10 @@
<translation>&amp;Verifica el missatge</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>Introduïu l'adreça del receptor, el missatge (assegureu-vos de copiar els salts de línia, espais, tabuladors, etc. exactament) i signatura de sota per verificar el missatge. Tingueu cura de no llegir més en la signatura del que està al missatge signat, per evitar ser enganyat per un atac d'home-en-el-mig. Tingueu en compte que això només demostra que la part que signa rep amb l'adreça, i no es pot provar l'enviament de qualsevol transacció!</translation>
+ </message>
+ <message>
<source>The Bitcoin address the message was signed with</source>
<translation>L'adreça Bitcoin amb què va ser signat el missatge</translation>
</message>
@@ -2421,6 +2571,10 @@
<translation>Si està implicada o no una adreça només de lectura en la transacció.</translation>
</message>
<message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Intenció/propòsit de la transacció definida per l'usuari.</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
<translation>Import extret o afegit del balanç.</translation>
</message>
@@ -2671,16 +2825,16 @@
<translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Entra en el mode de proves de regressió, que utilitza una cadena especial en què els blocs poden resoldre's al moment.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>En aquest mode -genproclimit controla quants blocs es generen immediatament.</translation>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%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, &gt;%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, &lt;0 = leave that many cores free, default: %d)</source>
@@ -2695,6 +2849,14 @@
<translation>No es pot enllaçar %s a aquest ordinador. El Bitcoin Core probablement ja estigui executant-s'hi.</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Avís: el -paytxfee és molt elevat! Aquesta és la comissió de transacció que pagareu si envieu una transacció.</translation>
</message>
@@ -2811,6 +2973,14 @@
<translation>Només connecta als nodes de la xarxa &lt;net&gt; (ipv4, ipv6 o onion)</translation>
</message>
<message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>La poda no es pot configurar amb un valor negatiu.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>El mode de poda és incompatible amb -txindex.</translation>
+ </message>
+ <message>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation>Defineix la mida de la memòria cau de la base de dades en megabytes (%d a %d, per defecte: %d)</translation>
</message>
@@ -2823,10 +2993,6 @@
<translation>Especifica un fitxer de moneder (dins del directori de dades)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Això es així per a eines de proves de regressió per al desenvolupament d'aplicacions.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation>
</message>
@@ -2847,6 +3013,10 @@
<translation>Opcions de moneder:</translation>
</message>
<message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Avís: aquesta versió és obsoleta; cal actualitzar-la!</translation>
+ </message>
+ <message>
<source>You need to rebuild the database using -reindex to change -txindex</source>
<translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation>
</message>
@@ -2875,6 +3045,10 @@
<translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation>
</message>
<message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Descobreix l'adreça IP pròpia (per defecte: 1 quan s'escolta i no -externalip o -proxy)</translation>
+ </message>
+ <message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation>
</message>
@@ -2891,10 +3065,6 @@
<translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la transmissió (per defecte: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la creació de la transacció (per defecte: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencin a confirmar-se en una mitja de n blocs (per defecte: %u)</translation>
</message>
@@ -2907,10 +3077,18 @@
<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>
<message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Genera a l'atzar credencials per a cada connexió proxy. Això habilita l'aïllament del flux de Tor (per defecte: %u)</translation>
+ </message>
+ <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d)</translation>
</message>
@@ -2919,6 +3097,10 @@
<translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation>
</message>
<message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>L'import de la transacció és massa petit per enviar-la després que se'n dedueixi la comissió</translation>
+ </message>
+ <message>
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
<translation>Aquest producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit &lt;https://www.openssl.org/&gt; i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation>
</message>
@@ -2958,10 +3140,26 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation>
</message>
<message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Cal que torneu a construir la base de dades fent servir -reindex per tornar al mode no podat. Això tornarà a baixar la cadena de blocs sencera</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(per defecte: %u)</translation>
+ </message>
+ <message>
<source>Accept public REST requests (default: %u)</source>
<translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation>
</message>
<message>
+ <source>Activating best chain...</source>
+ <translation>S'està activant la millor cadena...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>No es pot executar amb un moneder en mode poda.</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>No es pot resoldre l'adreça -whitebind: «%s»</translation>
</message>
@@ -3050,12 +3248,12 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Descarta a l'atzar 1 de cada &lt;n&gt; missatges de la xarxa</translation>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation>
</message>
<message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Introdueix incertesa en 1 de cada &lt;n&gt; missatges de la xarxa</translation>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Rep i mostra avisos de la xarxa P2P (per defecte: %u)</translation>
</message>
<message>
<source>Send trace/debug info to console instead of debug.log file</source>
@@ -3094,6 +3292,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Inicia minimitzat</translation>
</message>
<message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation>
+ </message>
+ <message>
<source>This is experimental software.</source>
<translation>Això és programari experimental.</translation>
</message>
@@ -3114,6 +3316,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>La transacció és massa gran</translation>
</message>
<message>
+ <source>UI Options:</source>
+ <translation>Opcions d'interfície:</translation>
+ </message>
+ <message>
<source>Unable to bind to %s on this computer (bind returned error %s)</source>
<translation>No s'ha pogut vincular a %s en aquest ordinador (la vinculació ha retornat l'error %s)</translation>
</message>
@@ -3194,18 +3400,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>(1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Buida l'activitat de la base de dades de la memòria disponible al registre del disc cada &lt;n&gt; megabytes (per defecte: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Enregistreu la prioritat de la transacció i la comissió per kB en minar blocs (per defecte: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation>
</message>
@@ -3234,18 +3432,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Inhabilita el mode segur, sobreescriu un esdeveniment de mode segur real (per defecte: %u) </translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>Error en carregar wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Força el mode segur (per defecte: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Genera monedes (per defecte: %u)</translation>
</message>
@@ -3262,10 +3452,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Adreça -proxy invalida: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Limita la mida de la cau de signatura a &lt;n&gt; entrades (per defecte: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Escolta les connexions JSON-RPC en &lt;port&gt; (per defecte: %u o testnet: %u)</translation>
</message>
@@ -3278,6 +3464,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Manté com a màxim &lt;n&gt; connexions a iguals (per defecte: %u)</translation>
</message>
<message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Fes que el moneder faci difusió de les transaccions</translation>
+ </message>
+ <message>
<source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
<translation>Memòria intermèdia màxima de recepció per connexió, &lt;n&gt;*1000 bytes (per defecte: %u)</translation>
</message>
@@ -3286,10 +3476,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Memòria intermèdia màxima d'enviament per connexió, &lt;n&gt;*1000 bytes (per defecte: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Només accepta els punts de control integrats que coincideixen amb la cadena de blocs (per defecte: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Posa davant de la sortida de depuració una marca horària (per defecte: %u)</translation>
</message>
@@ -3302,10 +3488,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Retransmet multisig no P2SH (per defecte: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Executa un fil per buidar el moneder periòdicament (per defecte: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>Fitxer de certificat del servidor (per defecte: %s)</translation>
</message>
@@ -3326,10 +3508,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Defineix el senyalador DB_PRIVATE en l'entorn db del moneder (per defecte: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Especifica el fitxer de configuració (per defecte: %s)</translation>
</message>
@@ -3346,10 +3524,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Atura l'execució després d'importar blocs del disc (per defecte: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts
index c68cfb686a..b77845cfb2 100644
--- a/src/qt/locale/bitcoin_ca@valencia.ts
+++ b/src/qt/locale/bitcoin_ca@valencia.ts
@@ -1,7 +1,11 @@
-<TS language="ca@valencia" version="2.1">
+<TS language="ca@valencia" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
+ <source>Right-click to edit address or label</source>
+ <translation>Feu clic dret per a editar l'adreça o l'etiqueta</translation>
+ </message>
+ <message>
<source>Create a new address</source>
<translation>Crea una nova adreça</translation>
</message>
@@ -83,7 +87,7 @@
</message>
<message>
<source>Comma separated file (*.csv)</source>
- <translation>Fitxer separat per comes (*.csv)</translation>
+ <translation>Fitxer de separació amb comes (*.csv)</translation>
</message>
<message>
<source>Exporting Failed</source>
@@ -164,6 +168,10 @@
<translation>Esteu segur que voleu encriptar el vostre moneder?</translation>
</message>
<message>
+ <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>Ara es tancarà el Bitcoin Core per finalitzar el procés d'encriptació. Tingueu present que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguen ser robades per programari maliciós que infecti l'ordinador.</translation>
+ </message>
+ <message>
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
<translation>IMPORTANT: Tota copia de seguretat que hàgeu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder.</translation>
</message>
@@ -180,6 +188,10 @@
<translation>Introduïu la contrasenya nova al moneder.&lt;br/&gt;Utilitzeu una contrasenya de &lt;b&gt;deu o més caràcters aleatoris&lt;/b&gt;, o &lt;b&gt;vuit o més paraules&lt;/b&gt;.</translation>
</message>
<message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Introduïu la contrasenya antiga i la contrasenya nova al moneder.</translation>
+ </message>
+ <message>
<source>Wallet encryption failed</source>
<translation>L'encriptació del moneder ha fallat</translation>
</message>
@@ -387,6 +399,10 @@
<translation>&amp;Quant al Bitcoin Core</translation>
</message>
<message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modifica les opcions de configuració del Bitcoin Core</translation>
+ </message>
+ <message>
<source>Show the list of used sending addresses and labels</source>
<translation>Mostra la llista d'adreces d'enviament i etiquetes utilitzades</translation>
</message>
@@ -406,14 +422,34 @@
<source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
<translation>Mostra el missatge d'ajuda del Bitcoin Core per obtindre una llista amb les possibles opcions de línia d'ordes de Bitcoin</translation>
</message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n connexió activa a la xarxa Bitcoin</numerusform><numerusform>%n connexions actives a la xarxa Bitcoin</numerusform></translation>
+ </message>
<message>
<source>No block source available...</source>
<translation>No hi ha cap font de bloc disponible...</translation>
</message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dia</numerusform><numerusform>%n dies</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n setmana</numerusform><numerusform>%n setmanes</numerusform></translation>
+ </message>
<message>
<source>%1 and %2</source>
<translation>%1 i %2</translation>
</message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n any</numerusform><numerusform>%n anys</numerusform></translation>
+ </message>
<message>
<source>%1 behind</source>
<translation>%1 darrere</translation>
@@ -436,7 +472,7 @@
</message>
<message>
<source>Information</source>
- <translation>&amp;Informació</translation>
+ <translation>Informació</translation>
</message>
<message>
<source>Up to date</source>
@@ -447,6 +483,36 @@
<translation>S'està posant al dia ...</translation>
</message>
<message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Import: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tipus: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Etiqueta: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adreça: %1
+</translation>
+ </message>
+ <message>
<source>Sent transaction</source>
<translation>Transacció enviada</translation>
</message>
@@ -473,6 +539,10 @@
<context>
<name>CoinControlDialog</name>
<message>
+ <source>Coin Selection</source>
+ <translation>Selecció de moneda</translation>
+ </message>
+ <message>
<source>Quantity:</source>
<translation>Quantitat:</translation>
</message>
@@ -490,7 +560,7 @@
</message>
<message>
<source>Fee:</source>
- <translation>Comissió:</translation>
+ <translation>Comissió</translation>
</message>
<message>
<source>Dust:</source>
@@ -498,7 +568,7 @@
</message>
<message>
<source>After Fee:</source>
- <translation>Quota posterior:</translation>
+ <translation>Comissió posterior:</translation>
</message>
<message>
<source>Change:</source>
@@ -518,7 +588,15 @@
</message>
<message>
<source>Amount</source>
- <translation>Quantitat</translation>
+ <translation>Import</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Rebut amb l'etiqueta</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Rebut amb l'adreça</translation>
</message>
<message>
<source>Date</source>
@@ -538,11 +616,11 @@
</message>
<message>
<source>Copy address</source>
- <translation>Copia l'adreça</translation>
+ <translation>Copiar adreça </translation>
</message>
<message>
<source>Copy label</source>
- <translation>Copia l'etiqueta</translation>
+ <translation>Copiar etiqueta</translation>
</message>
<message>
<source>Copy amount</source>
@@ -566,7 +644,7 @@
</message>
<message>
<source>Copy fee</source>
- <translation>Copia la comissi</translation>
+ <translation>Copia la comissió</translation>
</message>
<message>
<source>Copy after fee</source>
@@ -633,6 +711,18 @@
<translation>cap</translation>
</message>
<message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Esta etiqueta es torna en roig si la transacció és superior a 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Esta etiqueta es torna en roig si la propietat és inferior que la «mitjana».</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Esta etiqueta es torna roja si el destinatari rep un import inferior de %1.</translation>
+ </message>
+ <message>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation>Pot variar +/- %1 satoshi(s) per entrada.</translation>
</message>
@@ -646,7 +736,7 @@
</message>
<message>
<source>This means a fee of at least %1 per kB is required.</source>
- <translation>Això comporta una comissi d'almenys %1 per kB.</translation>
+ <translation>Això comporta una comissió d'almenys %1 per kB.</translation>
</message>
<message>
<source>Can vary +/- 1 byte per input.</source>
@@ -673,7 +763,7 @@
<name>EditAddressDialog</name>
<message>
<source>Edit Address</source>
- <translation>Editar Adreça</translation>
+ <translation>Edita l'adreça</translation>
</message>
<message>
<source>&amp;Label</source>
@@ -816,7 +906,15 @@
<source>Error</source>
<translation>Error</translation>
</message>
- </context>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB d'espai lliure disponible</numerusform><numerusform>%n GB d'espai lliure disponible</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(de %n GB necessari)</numerusform><numerusform>(de %n GB necessaris)</numerusform></translation>
+ </message>
+</context>
<context>
<name>OpenURIDialog</name>
<message>
@@ -875,6 +973,14 @@
<translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
</message>
<message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimitza en comptes d'eixir de l'aplicació quan la finestra es tanca. Quan s'habilita esta opció l'aplicació es tancara només quan se selecciona Ix del menú. </translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>La interfície d'usuari pot definir-se des d'ací. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
<translation>URL de terceres parts (p. ex. explorador de blocs) que apareix en la pestanya de transaccions com elements del menú contextual. %s en l'URL es reemplaçat pel resum de la transacció. Diferents URL estan separades per una barra vertical |.</translation>
</message>
@@ -899,6 +1005,14 @@
<translation>&amp;Xarxa</translation>
</message>
<message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Inicia el Bitcoin Core en inciar el sistema</translation>
+ </message>
+ <message>
<source>(0 = auto, &lt;0 = leave that many cores free)</source>
<translation>(0 = auto, &lt;0 = deixa tants nuclis lliures)</translation>
</message>
@@ -931,6 +1045,14 @@
<translation>Port obert amb &amp;UPnP</translation>
</message>
<message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Connecta a través d'un proxy SOCKS5 (proxy per defecte):</translation>
+ </message>
+ <message>
<source>Proxy &amp;IP:</source>
<translation>&amp;IP del proxy:</translation>
</message>
@@ -1003,6 +1125,10 @@
<translation>Cal reiniciar el client per activar els canvis.</translation>
</message>
<message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Es pararà el client. Voleu procedir?</translation>
+ </message>
+ <message>
<source>This change would require a client restart.</source>
<translation>Amb este canvi cal un reinici del client.</translation>
</message>
@@ -1050,6 +1176,10 @@
<translation>Balanç minat que encara no ha madurat</translation>
</message>
<message>
+ <source>Balances</source>
+ <translation>Balances</translation>
+ </message>
+ <message>
<source>Total:</source>
<translation>Total:</translation>
</message>
@@ -1062,6 +1192,14 @@
<translation>El vostre balanç actual en adreces de només lectura</translation>
</message>
<message>
+ <source>Spendable:</source>
+ <translation>Que es pot gastar:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Transaccions recents</translation>
+ </message>
+ <message>
<source>Unconfirmed transactions to watch-only addresses</source>
<translation>Transaccions sense confirmar a adreces de només lectura</translation>
</message>
@@ -1125,14 +1263,30 @@
<translation>No es pot llegir el fitxer de la sol·licitud de pagament. Això pot ser causat per un fitxer de sol·licitud de pagament no vàlid.</translation>
</message>
<message>
+ <source>Payment request expired.</source>
+ <translation>La sol·licitud de pagament ha vençut.</translation>
+ </message>
+ <message>
<source>Unverified payment requests to custom payment scripts are unsupported.</source>
<translation>No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats.</translation>
</message>
<message>
+ <source>Invalid payment request.</source>
+ <translation>Sol·licitud de pagament no vàlida.</translation>
+ </message>
+ <message>
<source>Refund from %1</source>
<translation>Reemborsament de %1</translation>
</message>
<message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>La sol·licitud de pagament %1 és massa gran (%2 bytes, permés %3 bytes).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Protecció de DoS per a la sol·licitud de pagament</translation>
+ </message>
+ <message>
<source>Error communicating with %1: %2</source>
<translation>Error en comunicar amb %1: %2</translation>
</message>
@@ -1160,6 +1314,10 @@
<translation>Agent d'usuari</translation>
</message>
<message>
+ <source>Node/Service</source>
+ <translation>Node/Servei</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Temps de ping</translation>
</message>
@@ -1168,7 +1326,7 @@
<name>QObject</name>
<message>
<source>Amount</source>
- <translation>Quantitat</translation>
+ <translation>Import</translation>
</message>
<message>
<source>Enter a Bitcoin address (e.g. %1)</source>
@@ -1281,6 +1439,10 @@
<translation>Nombre de blocs actuals</translation>
</message>
<message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Obri el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans.</translation>
+ </message>
+ <message>
<source>Received</source>
<translation>Rebut</translation>
</message>
@@ -1349,6 +1511,10 @@
<translation>Temps de ping</translation>
</message>
<message>
+ <source>Time Offset</source>
+ <translation>Diferència horària</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Últim temps de bloc</translation>
</message>
@@ -1393,6 +1559,10 @@
<translation>Neteja la consola</translation>
</message>
<message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Vos donem la benviguda a la consola RPC del Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
<translation>Utilitza les fletxes d'amunt i avall per navegar per l'historial, i &lt;b&gt;Ctrl-L&lt;\b&gt; per netejar la pantalla.</translation>
</message>
@@ -1560,7 +1730,7 @@
</message>
<message>
<source>Amount</source>
- <translation>Quantitat</translation>
+ <translation>Import</translation>
</message>
<message>
<source>Label</source>
@@ -1595,7 +1765,7 @@
</message>
<message>
<source>Amount</source>
- <translation>Quantitat</translation>
+ <translation>Import</translation>
</message>
<message>
<source>(no label)</source>
@@ -1654,7 +1824,7 @@
</message>
<message>
<source>After Fee:</source>
- <translation>Quota posterior:</translation>
+ <translation>Comissió posterior:</translation>
</message>
<message>
<source>Change:</source>
@@ -1669,6 +1839,74 @@
<translation>Personalitza l'adreça de canvi</translation>
</message>
<message>
+ <source>Transaction Fee:</source>
+ <translation>Comissió de transacció</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Tria...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>redueix els paràmetres de comissió</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilobyte</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Amaga</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>total com a mínim</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>No hi ha cap problema en pagar només la comissió mínima sempre que hi haja menys volum de transacció que espai en els blocs. Però tingueu present que això pot acabar en una transacció que mai es confirme una vegada hi haja més demanda de transaccions de bitcoins que la xarxa puga processar.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(llegiu l'indicador de funció)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Recomanada:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Personalitzada:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(No s'ha inicialitzat encara la comissió intel·ligent. Normalment pren uns pocs blocs...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Temps de confirmació:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>ràpid</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Envia com a transacció de comissió zero si és possible</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(la confirmació pot trigar més temps)</translation>
+ </message>
+ <message>
<source>Send to multiple recipients at once</source>
<translation>Envia a múltiples destinataris al mateix temps</translation>
</message>
@@ -1678,7 +1916,7 @@
</message>
<message>
<source>Clear all fields of the form.</source>
- <translation>Esborra tots els camps del formuari.</translation>
+ <translation>Netejar tots els camps del formulari.</translation>
</message>
<message>
<source>Dust:</source>
@@ -1718,7 +1956,7 @@
</message>
<message>
<source>Copy fee</source>
- <translation>Copia la comissi</translation>
+ <translation>Copia la comissió</translation>
</message>
<message>
<source>Copy after fee</source>
@@ -1754,7 +1992,7 @@
</message>
<message>
<source>The total exceeds your balance when the %1 transaction fee is included.</source>
- <translation>El total excedeix el teu balanç quan s'afig la comisió a la transacció %1.</translation>
+ <translation>El total excedeix el teu balanç quan s'afig la comissió a la transacció %1.</translation>
</message>
<message>
<source>Transaction creation failed!</source>
@@ -1765,6 +2003,30 @@
<translation>S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'hagueren gastat monedes de la còpia però sense marcar-les-hi com a gastades.</translation>
</message>
<message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Una comissió superior a %1 es considera una comissió absurdament alta.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>La sol·licitud de pagament ha vençut.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Paga només la comissió mínima de %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada.</translation>
+ </message>
+ <message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Avís: adreça Bitcoin no vàlida</translation>
</message>
@@ -1836,10 +2098,26 @@
<translation>Elimina esta entrada</translation>
</message>
<message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>La comissió es deduirà de l'import que s'enviarà. El destinatari rebrà menys bitcoins que les que introduïu al camp d'import. Si se seleccionen múltiples destinataris, la comissió es dividirà per igual.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>S&amp;ubstreu la comissió de l'import</translation>
+ </message>
+ <message>
<source>Message:</source>
<translation>Missatge:</translation>
</message>
<message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Esta és una sol·licitud de pagament no autenticada.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Esta és una sol·licitud de pagament autenticada.</translation>
+ </message>
+ <message>
<source>Enter a label for this address to add it to the list of used addresses</source>
<translation>Introduïu una etiqueta per a esta adreça per afegir-la a la llista d'adreces utilitzades</translation>
</message>
@@ -1878,20 +2156,24 @@
<translation>&amp;Signa el missatge</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>Podeu signar missatges/acords amb les vostres adreces per provar que rebeu les bitcoins que s'hi envien. Aneu amb compte no signar res que siga vague o aleatori, perquè en alguns atacs de suplantació es pot provar que hi signeu la vostra identitat. Només signeu aquelles declaracions completament detallades en què hi esteu d'acord. </translation>
+ </message>
+ <message>
<source>The Bitcoin address to sign the message with</source>
<translation>L'adreça Bitcoin amb què signar el missatge</translation>
</message>
<message>
<source>Choose previously used address</source>
- <translation>Trieu una adreça feta servir anteriorment</translation>
+ <translation>Tria les adreces fetes servir amb anterioritat</translation>
</message>
<message>
<source>Alt+A</source>
- <translation>Alta+A</translation>
+ <translation>Alt+A</translation>
</message>
<message>
<source>Paste address from clipboard</source>
- <translation>Apegar adreça del porta-retalls</translation>
+ <translation>Apega l'adreça del porta-retalls</translation>
</message>
<message>
<source>Alt+P</source>
@@ -1930,6 +2212,10 @@
<translation>&amp;Verifica el missatge</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>Introduïu l'adreça del receptor, el missatge (assegureu-vos de copiar els salts de línia, espais, tabuladors, etc. exactament) i signatura de sota per verificar el missatge. Tingueu cura de no llegir més en la signatura del que està al missatge signat, per evitar ser enganyat per un atac d'home-en-el-mig. Tingueu en compte que això només demostra que la part que signa rep amb l'adreça, i no es pot provar l'enviament de qualsevol transacció!</translation>
+ </message>
+ <message>
<source>The Bitcoin address the message was signed with</source>
<translation>L'adreça Bitcoin amb què va ser signat el missatge</translation>
</message>
@@ -2002,7 +2288,7 @@
<name>SplashScreen</name>
<message>
<source>Bitcoin Core</source>
- <translation>Nucli de Bitcoin</translation>
+ <translation>Bitcoin Core</translation>
</message>
<message>
<source>The Bitcoin Core developers</source>
@@ -2046,6 +2332,10 @@
<source>Status</source>
<translation>Estat</translation>
</message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, difusió a través de %n node</numerusform><numerusform>, difusió a través de %n nodes</numerusform></translation>
+ </message>
<message>
<source>Date</source>
<translation>Data</translation>
@@ -2082,6 +2372,10 @@
<source>Credit</source>
<translation>Crèdit</translation>
</message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>madura en %n bloc més</numerusform><numerusform>madura en %n blocs més</numerusform></translation>
+ </message>
<message>
<source>not accepted</source>
<translation>no acceptat</translation>
@@ -2140,7 +2434,7 @@
</message>
<message>
<source>Amount</source>
- <translation>Quantitat</translation>
+ <translation>Import</translation>
</message>
<message>
<source>true</source>
@@ -2154,6 +2448,10 @@
<source>, has not been successfully broadcast yet</source>
<translation>, encara no ha estat emés correctement</translation>
</message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Obri per %n bloc més</numerusform><numerusform>Obri per %n blocs més</numerusform></translation>
+ </message>
<message>
<source>unknown</source>
<translation>desconegut</translation>
@@ -2184,6 +2482,10 @@
<source>Immature (%1 confirmations, will be available after %2)</source>
<translation>Immadur (%1 confirmacions, serà disponible després de %2)</translation>
</message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Obri per %n bloc més</numerusform><numerusform>Obri per %n blocs més</numerusform></translation>
+ </message>
<message>
<source>Open until %1</source>
<translation>Obert fins %1</translation>
@@ -2261,6 +2563,14 @@
<translation>Tipus de transacció.</translation>
</message>
<message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Si està implicada o no una adreça només de lectura en la transacció.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Intenció/propòsit de la transacció definida per l'usuari.</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
<translation>Import extret o afegit del balanç.</translation>
</message>
@@ -2329,7 +2639,7 @@
</message>
<message>
<source>Copy label</source>
- <translation>Copia l'etiqueta</translation>
+ <translation>Copiar etiqueta</translation>
</message>
<message>
<source>Copy amount</source>
@@ -2352,6 +2662,10 @@
<translation>Exporta l'historial de transacció</translation>
</message>
<message>
+ <source>Watch-only</source>
+ <translation>Només de lectura</translation>
+ </message>
+ <message>
<source>Exporting Failed</source>
<translation>L'exportació ha fallat</translation>
</message>
@@ -2503,16 +2817,20 @@
<translation>Elimina totes les transaccions del moneder i només recupera aquelles de la cadena de blocs a través de -rescan a l'inici</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Entra en el mode de proves de regressió, que utilitza una cadena especial en què els blocs poden resoldre's al moment.</translation>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Executa una orde quan una transacció del moneder canvie (%s en cmd es canvia per TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>En este mode -genproclimit controla quants blocs es generen immediatament.</translation>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%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, &gt;%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, &lt;0 = leave that many cores free, default: %d)</source>
@@ -2527,6 +2845,14 @@
<translation>No es pot enllaçar %s a este ordinador. El Bitcoin Core probablement ja estiga executant-s'hi.</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Avís: el -paytxfee és molt elevat! Esta és la comissió de transacció que pagareu si envieu una transacció.</translation>
</message>
@@ -2547,6 +2873,10 @@
<translation>Avís: el fitxer wallet.dat és corrupte, dades rescatades! L'arxiu wallet.dat original ha estat guardat com wallet.{estampa_temporal}.bak al directori %s; si el teu balanç o transaccions son incorrectes hauries de restaurar-lo de un backup.</translation>
</message>
<message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Afig a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades.</translation>
+ </message>
+ <message>
<source>(default: 1)</source>
<translation>(per defecte: 1)</translation>
</message>
@@ -2603,6 +2933,10 @@
<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>
@@ -2631,6 +2965,18 @@
<translation>No hi ha suficient descriptors de fitxers disponibles.</translation>
</message>
<message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Només connecta als nodes de la xarxa &lt;net&gt; (ipv4, ipv6 o onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>La poda no es pot configurar amb un valor negatiu.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>El mode de poda és incompatible amb -txindex.</translation>
+ </message>
+ <message>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation>Defineix la mida de la memòria cau de la base de dades en megabytes (%d a %d, per defecte: %d)</translation>
</message>
@@ -2643,8 +2989,8 @@
<translation>Especifica un fitxer de moneder (dins del directori de dades)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Això s'així per a eines de proves de regressió per al desenvolupament d'aplicacions.</translation>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation>
</message>
<message>
<source>Verifying blocks...</source>
@@ -2663,6 +3009,10 @@
<translation>Opcions de moneder:</translation>
</message>
<message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Avís: esta versió és obsoleta; cal actualitzar-la!</translation>
+ </message>
+ <message>
<source>You need to rebuild the database using -reindex to change -txindex</source>
<translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation>
</message>
@@ -2691,6 +3041,10 @@
<translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation>
</message>
<message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Descobreix l'adreça IP pròpia (per defecte: 1 quan s'escolta i no -externalip o -proxy)</translation>
+ </message>
+ <message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation>
</message>
@@ -2707,22 +3061,73 @@
<translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la transmissió (per defecte: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la creació de la transacció (per defecte: %s)</translation>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencen a confirmar-se en una mitja de n blocs (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Import no vàlid per a -maxtxfee=&lt;amount&gt;: '%s' (cal que siga com a mínim la comissió de minrelay de %s per evitar que les comissions s'encallin)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Mida màxima de les dades en les transaccions de l'operador en què confiem i en les meues (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Poda configurada per sota el mínim de %d MB. Feu servir un nombre superior.</translation>
</message>
<message>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation>Consulta a adreces d'iguals a través de DNS, si es troba baix en adreces (per defecte: 1 a menys que -connect)</translation>
</message>
<message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Genera a l'atzar credencials per a cada connexió proxy. Això habilita l'aïllament del flux de Tor (per defecte: %u)</translation>
+ </message>
+ <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d)</translation>
</message>
<message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>L'import de la transacció és massa petit per enviar-la després que se'n deduïsca la comissió</translation>
+ </message>
+ <message>
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
<translation>Este producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit &lt;https://www.openssl.org/&gt; 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>
@@ -2731,6 +3136,26 @@
<translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation>
</message>
<message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Cal que torneu a construir la base de dades fent servir -reindex per tornar al mode no podat. Això tornarà a baixar la cadena de blocs sencera</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>S'està activant la millor cadena...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>No es pot executar amb un moneder en mode poda.</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>No es pot resoldre l'adreça -whitebind: «%s»</translation>
</message>
@@ -2755,6 +3180,10 @@
<translation>Error en carregar wallet.dat: el moneder requereix una versió més nova del Bitcoin core</translation>
</message>
<message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Error en llegir la base de dades, tancant.</translation>
+ </message>
+ <message>
<source>Error: Unsupported argument -tor found, use -onion.</source>
<translation>Error: s'ha trobat un argument -tor no acceptat. Feu servir -onion.</translation>
</message>
@@ -2771,6 +3200,10 @@
<translation>Ha fallat la inicialització de la comprovació de validesa. El Bitcoin Core s'està parant.</translation>
</message>
<message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Import no vàlid per a -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
<source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
<translation>Import no vàlid per a -minrelaytxfee=&lt;amount&gt;: «%s»</translation>
</message>
@@ -2787,6 +3220,10 @@
<translation>S'ha especificat una màscara de xarxa no vàlida a -whitelist: «%s»</translation>
</message>
<message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Manté com a màxim &lt;n&gt; transaccions no connectables en memòria (per defecte: %u)</translation>
+ </message>
+ <message>
<source>Need to specify a port with -whitebind: '%s'</source>
<translation>Cal especificar un port amb -whitebind: «%s»</translation>
</message>
@@ -2803,24 +3240,32 @@
<translation>Opcions del servidor RPC:</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Descarta a l'atzar 1 de cada &lt;n&gt; missatges de la xarxa</translation>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation>
</message>
<message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Introdueix incertesa en 1 de cada &lt;n&gt; missatges de la xarxa</translation>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Rep i mostra avisos de la xarxa P2P (per defecte: %u)</translation>
</message>
<message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Envia informació de traça/depuració a la consola en comptes del fitxer debug.log</translation>
</message>
<message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Envia les transaccions com a transaccions de comissió zero sempre que siga possible (per defecte: %u) </translation>
+ </message>
+ <message>
<source>Set SSL root certificates for payment request (default: -system-)</source>
<translation>Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-)</translation>
</message>
<message>
<source>Set language, for example "de_DE" (default: system locale)</source>
- <translation>Defineix un idioma, per exemple "de_DE" (per defecte: preferències locals de sistema)</translation>
+ <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>
@@ -2843,6 +3288,10 @@
<translation>Inicia minimitzat</translation>
</message>
<message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation>
+ </message>
+ <message>
<source>This is experimental software.</source>
<translation>Això és programari experimental.</translation>
</message>
@@ -2855,10 +3304,18 @@
<translation>Els imports de les transaccions han de ser positius</translation>
</message>
<message>
+ <source>Transaction too large for fee policy</source>
+ <translation>Transacció massa gran per a la política de comissions</translation>
+ </message>
+ <message>
<source>Transaction too large</source>
<translation>La transacció és massa gran</translation>
</message>
<message>
+ <source>UI Options:</source>
+ <translation>Opcions d'interfície:</translation>
+ </message>
+ <message>
<source>Unable to bind to %s on this computer (bind returned error %s)</source>
<translation>No s'ha pogut vincular a %s en este ordinador (la vinculació ha retornat l'error %s)</translation>
</message>
@@ -2935,14 +3392,138 @@
<translation>Error en carregar wallet.dat: Moneder corrupte</translation>
</message>
<message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Nombre de segons necessaris perquè els iguals de comportament qüestionable puguen tornar a connectar-se (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Informació d'eixida de la depuració (per defecte: %u, proporcionar &lt;category&gt; és opcional)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Xifrats acceptables (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation>
+ </message>
+ <message>
<source>Error loading wallet.dat</source>
<translation>Error en carregar wallet.dat</translation>
</message>
<message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Genera monedes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Quants blocs per comprovar a l'inici (per defecte: %u, 0 = tots)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Inclou l'adreça IP a l'eixida de depuració (per defecte: %u)</translation>
+ </message>
+ <message>
<source>Invalid -proxy address: '%s'</source>
<translation>Adreça -proxy invalida: '%s'</translation>
</message>
<message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escolta les connexions JSON-RPC en &lt;port&gt; (per defecte: %u o testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escolta les connexions en &lt;port&gt; (per defecte: %u o testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Manté com a màxim &lt;n&gt; connexions a iguals (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Fes que el moneder faça difusió de les transaccions</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Memòria intermèdia màxima de recepció per connexió, &lt;n&gt;*1000 bytes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Memòria intermèdia màxima d'enviament per connexió, &lt;n&gt;*1000 bytes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Posa davant de l'eixida de depuració una marca horària (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Retransmet i mina les transaccions de l'operador (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Retransmet multisig no P2SH (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Fitxer de certificat del servidor (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Clau privada del servidor (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Defineix la mida clau disponible a &lt;n&gt; (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Defineix la mida de bloc mínima en bytes (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Especifica el fitxer de configuració (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Especifica el temps d'espera de la connexió en milisegons (mínim: 1, per defecte: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Especifica el fitxer pid (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation>
+ </message>
+ <message>
<source>Unknown network specified in -onlynet: '%s'</source>
<translation>Xarxa desconeguda especificada a -onlynet: '%s'</translation>
</message>
diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts
index cd6aa96d34..898b7f33b3 100644
--- a/src/qt/locale/bitcoin_ca_ES.ts
+++ b/src/qt/locale/bitcoin_ca_ES.ts
@@ -1,4 +1,4 @@
-<TS language="ca_ES" version="2.1">
+<TS language="ca_ES" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -168,6 +168,10 @@
<translation>Esteu segur que voleu encriptar el vostre moneder?</translation>
</message>
<message>
+ <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>Ara es tancarà el Bitcoin Core per finalitzar el procés d'encriptació. Tingueu present que encriptar el vostre moneder no garanteix que les vostres bitcoins no puguin ser robades per programari maliciós que infecti l'ordinador.</translation>
+ </message>
+ <message>
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
<translation>IMPORTANT: Tota copia de seguretat que hàgiu realitzat hauria de ser reemplaçada pel, recentment generat, fitxer encriptat del moneder.</translation>
</message>
@@ -184,6 +188,10 @@
<translation>Introduïu la contrasenya nova al moneder.&lt;br/&gt;Utilitzeu una contrasenya de &lt;b&gt;deu o més caràcters aleatoris&lt;/b&gt;, o &lt;b&gt;vuit o més paraules&lt;/b&gt;.</translation>
</message>
<message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Introduïu la contrasenya antiga i la contrasenya nova al moneder.</translation>
+ </message>
+ <message>
<source>Wallet encryption failed</source>
<translation>L'encriptació del moneder ha fallat</translation>
</message>
@@ -391,6 +399,10 @@
<translation>&amp;Quant al Bitcoin Core</translation>
</message>
<message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modifica les opcions de configuració del Bitcoin Core</translation>
+ </message>
+ <message>
<source>Show the list of used sending addresses and labels</source>
<translation>Mostra la llista d'adreces d'enviament i etiquetes utilitzades</translation>
</message>
@@ -419,6 +431,10 @@
<translation>No hi ha cap font de bloc disponible...</translation>
</message>
<message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>S'han processat %n bloc de l'historial de transacció.</numerusform><numerusform>S'han processat %n blocs de l'historial de transacció.</numerusform></translation>
+ </message>
+ <message numerus="yes">
<source>%n hour(s)</source>
<translation><numerusform>%n hora</numerusform><numerusform>%n hores</numerusform></translation>
</message>
@@ -471,6 +487,36 @@
<translation>S'està posant al dia ...</translation>
</message>
<message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Import: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tipus: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Etiqueta: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adreça: %1
+</translation>
+ </message>
+ <message>
<source>Sent transaction</source>
<translation>Transacció enviada</translation>
</message>
@@ -669,6 +715,18 @@
<translation>cap</translation>
</message>
<message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Aquesta etiqueta es torna en vermell si la transacció és superior a 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Aquesta etiqueta es torna en vermell si la propietat és inferior que la «mitjana».</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Aquesta etiqueta es torna vermella si el destinatari rep un import inferior de %1.</translation>
+ </message>
+ <message>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation>Pot variar +/- %1 satoshi(s) per entrada.</translation>
</message>
@@ -919,6 +977,14 @@
<translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
</message>
<message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimitza en comptes de sortir de l'aplicació quan la finestra es tanca. Quan s'habilita aquesta opció l'aplicació es tancara només quan se selecciona Surt del menú. </translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>La interfície d'usuari pot definir-se des d'aquí. El paràmetre tindrà efecte després de reiniciar el Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
<translation>URL de terceres parts (p. ex. explorador de blocs) que apareix en la pestanya de transaccions com elements del menú contextual. %s en l'URL es reemplaçat pel resum de la transacció. Diferents URL estan separades per una barra vertical |.</translation>
</message>
@@ -943,6 +1009,14 @@
<translation>&amp;Xarxa</translation>
</message>
<message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Inicia el Bitcoin Core automàticament després d'iniciar una sessió en el sistema.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Inicia el Bitcoin Core en inciar el sistema</translation>
+ </message>
+ <message>
<source>(0 = auto, &lt;0 = leave that many cores free)</source>
<translation>(0 = auto, &lt;0 = deixa tants nuclis lliures)</translation>
</message>
@@ -1055,6 +1129,10 @@
<translation>Cal reiniciar el client per activar els canvis.</translation>
</message>
<message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>S'aturarà el client. Voleu procedir?</translation>
+ </message>
+ <message>
<source>This change would require a client restart.</source>
<translation>Amb aquest canvi cal un reinici del client.</translation>
</message>
@@ -1189,10 +1267,18 @@
<translation>No es pot llegir el fitxer de la sol·licitud de pagament. Això pot ser causat per un fitxer de sol·licitud de pagament no vàlid.</translation>
</message>
<message>
+ <source>Payment request expired.</source>
+ <translation>La sol·licitud de pagament ha vençut.</translation>
+ </message>
+ <message>
<source>Unverified payment requests to custom payment scripts are unsupported.</source>
<translation>No s'accepten sol·licituds de pagament no verificades a scripts de pagament personalitzats.</translation>
</message>
<message>
+ <source>Invalid payment request.</source>
+ <translation>Sol·licitud de pagament no vàlida.</translation>
+ </message>
+ <message>
<source>Refund from %1</source>
<translation>Reemborsament de %1</translation>
</message>
@@ -1232,6 +1318,10 @@
<translation>Agent d'usuari</translation>
</message>
<message>
+ <source>Node/Service</source>
+ <translation>Node/Servei</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Temps de ping</translation>
</message>
@@ -1353,6 +1443,10 @@
<translation>Nombre de blocs actuals</translation>
</message>
<message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Obre el fitxer de registre de depuració del Bitcoin Core del directori de dades actual. Pot portar uns quants segons per a fitxers de registre grans.</translation>
+ </message>
+ <message>
<source>Received</source>
<translation>Rebut</translation>
</message>
@@ -1421,6 +1515,10 @@
<translation>Temps de ping</translation>
</message>
<message>
+ <source>Time Offset</source>
+ <translation>Diferència horària</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Últim temps de bloc</translation>
</message>
@@ -1465,6 +1563,10 @@
<translation>Neteja la consola</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>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
<translation>Utilitza les fletxes d'amunt i avall per navegar per l'historial, i &lt;b&gt;Ctrl-L&lt;\b&gt; per netejar la pantalla.</translation>
</message>
@@ -1761,6 +1863,10 @@
<translation>Si la comissió personalitzada es defineix a 1000 satoshis i la transacció és de només 250 bytes, llavors «per kilobyte» només es paguen 250 satoshis en una comissió, mentre que amb la de «total com a mínim» es pagarien 1000 satoshis. Per a transaccions superiors al kilobyte, en tots dos casos es paga per kilobyte.</translation>
</message>
<message>
+ <source>Hide</source>
+ <translation>Amaga</translation>
+ </message>
+ <message>
<source>total at least</source>
<translation>total com a mínim</translation>
</message>
@@ -1901,10 +2007,30 @@
<translation>S'ha rebutjat la transacció! Això pot passar si alguna de les monedes del vostre moneder ja s'han gastat; per exemple, si heu fet servir una còpia de seguretat del fitxer wallet.dat i s'haguessin gastat monedes de la còpia però sense marcar-les-hi com a gastades.</translation>
</message>
<message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Una comissió superior a %1 es considera una comissió absurdament alta.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>La sol·licitud de pagament ha vençut.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Estimat per començar la confirmació en %n bloc.</numerusform><numerusform>Estimat per començar la confirmació en %n blocs.</numerusform></translation>
+ </message>
+ <message>
<source>Pay only the minimum fee of %1</source>
<translation>Paga només la comissió mínima de %1</translation>
</message>
<message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>L'adreça de destinatari no és vàlida. Torneu-la a comprovar.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>S'ha trobat una adreça duplicada: cal utilitzar les adreces només un cop cada vegada.</translation>
+ </message>
+ <message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Avís: adreça Bitcoin no vàlida</translation>
</message>
@@ -1976,10 +2102,26 @@
<translation>Elimina aquesta entrada</translation>
</message>
<message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>La comissió es deduirà de l'import que s'enviarà. El destinatari rebrà menys bitcoins que les que introduïu al camp d'import. Si se seleccionen múltiples destinataris, la comissió es dividirà per igual.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>S&amp;ubstreu la comissió de l'import</translation>
+ </message>
+ <message>
<source>Message:</source>
<translation>Missatge:</translation>
</message>
<message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Aquesta és una sol·licitud de pagament no autenticada.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Aquesta és una sol·licitud de pagament autenticada.</translation>
+ </message>
+ <message>
<source>Enter a label for this address to add it to the list of used addresses</source>
<translation>Introduïu una etiqueta per a aquesta adreça per afegir-la a la llista d'adreces utilitzades</translation>
</message>
@@ -2018,6 +2160,10 @@
<translation>&amp;Signa el missatge</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>Podeu signar missatges/acords amb les vostres adreces per provar que rebeu les bitcoins que s'hi envien. Aneu amb compte no signar res que sigui vague o aleatori, perquè en alguns atacs de suplantació es pot provar que hi signeu la vostra identitat. Només signeu aquelles declaracions completament detallades en què hi esteu d'acord. </translation>
+ </message>
+ <message>
<source>The Bitcoin address to sign the message with</source>
<translation>L'adreça Bitcoin amb què signar el missatge</translation>
</message>
@@ -2070,6 +2216,10 @@
<translation>&amp;Verifica el missatge</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>Introduïu l'adreça del receptor, el missatge (assegureu-vos de copiar els salts de línia, espais, tabuladors, etc. exactament) i signatura de sota per verificar el missatge. Tingueu cura de no llegir més en la signatura del que està al missatge signat, per evitar ser enganyat per un atac d'home-en-el-mig. Tingueu en compte que això només demostra que la part que signa rep amb l'adreça, i no es pot provar l'enviament de qualsevol transacció!</translation>
+ </message>
+ <message>
<source>The Bitcoin address the message was signed with</source>
<translation>L'adreça Bitcoin amb què va ser signat el missatge</translation>
</message>
@@ -2421,6 +2571,10 @@
<translation>Si està implicada o no una adreça només de lectura en la transacció.</translation>
</message>
<message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Intenció/propòsit de la transacció definida per l'usuari.</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
<translation>Import extret o afegit del balanç.</translation>
</message>
@@ -2671,16 +2825,16 @@
<translation>Distribuït sota llicència de programari MIT. Vegeu el fitxer acompanyant COPYING o &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Entra en el mode de proves de regressió, que utilitza una cadena especial en què els blocs poden resoldre's al moment.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Executa una ordre quan una transacció del moneder canviï (%s en cmd es canvia per TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>En aquest mode -genproclimit controla quants blocs es generen immediatament.</translation>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Comissions totals màximes que s'utilitzaran en una única transacció de moneder; si s'estableix un valor massa baix es poden interrompre transaccions grans (per defecte: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%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, &gt;%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, &lt;0 = leave that many cores free, default: %d)</source>
@@ -2695,6 +2849,14 @@
<translation>No es pot enllaçar %s a aquest ordinador. El Bitcoin Core probablement ja estigui executant-s'hi.</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVÍS: s'ha generat un nombre anòmalament alt de blocs, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVÍS: comproveu la vostra connexió a la xarxa, %d blocs rebuts en les darreres %d hores (se n'esperaven %d)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Avís: el -paytxfee és molt elevat! Aquesta és la comissió de transacció que pagareu si envieu una transacció.</translation>
</message>
@@ -2811,6 +2973,14 @@
<translation>Només connecta als nodes de la xarxa &lt;net&gt; (ipv4, ipv6 o onion)</translation>
</message>
<message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>La poda no es pot configurar amb un valor negatiu.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>El mode de poda és incompatible amb -txindex.</translation>
+ </message>
+ <message>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation>Defineix la mida de la memòria cau de la base de dades en megabytes (%d a %d, per defecte: %d)</translation>
</message>
@@ -2823,10 +2993,6 @@
<translation>Especifica un fitxer de moneder (dins del directori de dades)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Això es així per a eines de proves de regressió per al desenvolupament d'aplicacions.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Utilitza UPnP per a mapejar el port d'escolta (per defecte: %u)</translation>
</message>
@@ -2847,6 +3013,10 @@
<translation>Opcions de moneder:</translation>
</message>
<message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Avís: aquesta versió és obsoleta; cal actualitzar-la!</translation>
+ </message>
+ <message>
<source>You need to rebuild the database using -reindex to change -txindex</source>
<translation>Cal que reconstruïu la base de dades fent servir -reindex per canviar -txindex</translation>
</message>
@@ -2875,6 +3045,10 @@
<translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation>
</message>
<message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Descobreix l'adreça IP pròpia (per defecte: 1 quan s'escolta i no -externalip o -proxy)</translation>
+ </message>
+ <message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation>
</message>
@@ -2891,10 +3065,6 @@
<translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la transmissió (per defecte: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Comissions (en BTC/Kb) inferiors a això es consideren de comissió zero per a la creació de la transacció (per defecte: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Si no s'especifica una paytxfee (comissió de transacció de pagament), inclogueu suficient comissió per tal que les transaccions comencin a confirmar-se en una mitja de n blocs (per defecte: %u)</translation>
</message>
@@ -2907,10 +3077,18 @@
<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>
<message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Genera a l'atzar credencials per a cada connexió proxy. Això habilita l'aïllament del flux de Tor (per defecte: %u)</translation>
+ </message>
+ <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Defineix la mida màxima de transaccions d'alta prioritat / baixa comissió en bytes (per defecte: %d)</translation>
</message>
@@ -2919,6 +3097,10 @@
<translation>Defineix el nombre de fils per a la generació de moneda si està habilitat (-1 = tots els nuclis, per defecte: %d)</translation>
</message>
<message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>L'import de la transacció és massa petit per enviar-la després que se'n dedueixi la comissió</translation>
+ </message>
+ <message>
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
<translation>Aquest producte inclou programari desenvolupat pel projecte OpenSSL per a ús a l'OpenSSL Toolkit &lt;https://www.openssl.org/&gt; i programari criptogràfic escrit per Eric Young i programari UPnP escrit per Thomas Bernard.</translation>
</message>
@@ -2958,10 +3140,26 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Els iguals en la llista blanca no poden ser bandejats per DoS i es transmetran sempre llurs transaccions, fins i tot si ja són a la mempool. Això és útil, p. ex., per a una passarel·la</translation>
</message>
<message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Cal que torneu a construir la base de dades fent servir -reindex per tornar al mode no podat. Això tornarà a baixar la cadena de blocs sencera</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(per defecte: %u)</translation>
+ </message>
+ <message>
<source>Accept public REST requests (default: %u)</source>
<translation>Accepta sol·licituds REST públiques (per defecte: %u)</translation>
</message>
<message>
+ <source>Activating best chain...</source>
+ <translation>S'està activant la millor cadena...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>No es pot executar amb un moneder en mode poda.</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>No es pot resoldre l'adreça -whitebind: «%s»</translation>
</message>
@@ -3050,12 +3248,12 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Suport RPC per a connexions HTTP persistents (per defecte: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Descarta a l'atzar 1 de cada &lt;n&gt; missatges de la xarxa</translation>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Reconstrueix l'índex de la cadena de blocs dels fitxers blk000??.dat actuals a l'inici.</translation>
</message>
<message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Introdueix incertesa en 1 de cada &lt;n&gt; missatges de la xarxa</translation>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Rep i mostra avisos de la xarxa P2P (per defecte: %u)</translation>
</message>
<message>
<source>Send trace/debug info to console instead of debug.log file</source>
@@ -3094,6 +3292,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Inicia minimitzat</translation>
</message>
<message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>L'import de la transacció és massa petit per pagar-ne una comissió</translation>
+ </message>
+ <message>
<source>This is experimental software.</source>
<translation>Això és programari experimental.</translation>
</message>
@@ -3114,6 +3316,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>La transacció és massa gran</translation>
</message>
<message>
+ <source>UI Options:</source>
+ <translation>Opcions d'interfície:</translation>
+ </message>
+ <message>
<source>Unable to bind to %s on this computer (bind returned error %s)</source>
<translation>No s'ha pogut vincular a %s en aquest ordinador (la vinculació ha retornat l'error %s)</translation>
</message>
@@ -3194,18 +3400,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>(1 = manté les metadades de les tx, p. ex., propietari del compte i informació de sol·licitud del pagament, 2 = prescindeix de les metadades de les tx)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Buida l'activitat de la base de dades de la memòria disponible al registre del disc cada &lt;n&gt; megabytes (per defecte: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Com d'exhaustiva és la verificació de blocs del -checkblocks (0-4, per defecte: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Enregistreu la prioritat de la transacció i la comissió per kB en minar blocs (per defecte: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Manté un índex complet de transaccions, utilitzat per la crida rpc getrawtransaction (per defecte: %u)</translation>
</message>
@@ -3234,18 +3432,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Demana sempre les adreces dels iguals a través de consultes DNS (per defecte: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Inhabilita el mode segur, sobreescriu un esdeveniment de mode segur real (per defecte: %u) </translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>Error en carregar wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Força el mode segur (per defecte: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Genera monedes (per defecte: %u)</translation>
</message>
@@ -3262,10 +3452,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Adreça -proxy invalida: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Limita la mida de la cau de signatura a &lt;n&gt; entrades (per defecte: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Escolta les connexions JSON-RPC en &lt;port&gt; (per defecte: %u o testnet: %u)</translation>
</message>
@@ -3278,6 +3464,10 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Manté com a màxim &lt;n&gt; connexions a iguals (per defecte: %u)</translation>
</message>
<message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Fes que el moneder faci difusió de les transaccions</translation>
+ </message>
+ <message>
<source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
<translation>Memòria intermèdia màxima de recepció per connexió, &lt;n&gt;*1000 bytes (per defecte: %u)</translation>
</message>
@@ -3286,10 +3476,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Memòria intermèdia màxima d'enviament per connexió, &lt;n&gt;*1000 bytes (per defecte: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Només accepta els punts de control integrats que coincideixen amb la cadena de blocs (per defecte: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Posa davant de la sortida de depuració una marca horària (per defecte: %u)</translation>
</message>
@@ -3302,10 +3488,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Retransmet multisig no P2SH (per defecte: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Executa un fil per buidar el moneder periòdicament (per defecte: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>Fitxer de certificat del servidor (per defecte: %s)</translation>
</message>
@@ -3326,10 +3508,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Defineix el nombre de fils a crides de servei RPC (per defecte: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Defineix el senyalador DB_PRIVATE en l'entorn db del moneder (per defecte: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Especifica el fitxer de configuració (per defecte: %s)</translation>
</message>
@@ -3346,10 +3524,6 @@ per exemple: alertnotify=echo %%s | mail -s "Avís de Bitcoin" admin@foo.com</tr
<translation>Gasta el canvi no confirmat en enviar les transaccions (per defecte: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Atura l'execució després d'importar blocs del disc (per defecte: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Llindar per a desconnectar els iguals de comportament qüestionable (per defecte: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_cmn.ts b/src/qt/locale/bitcoin_cmn.ts
index 3286f12698..37c937b864 100644
--- a/src/qt/locale/bitcoin_cmn.ts
+++ b/src/qt/locale/bitcoin_cmn.ts
@@ -1,6 +1,10 @@
-<TS language="cmn" version="2.1">
+<TS language="cmn" version="2.0">
<context>
<name>AddressBookPage</name>
+ <message>
+ <source>Create a new address</source>
+ <translation>创建新地址</translation>
+ </message>
</context>
<context>
<name>AddressTableModel</name>
diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts
index 47464b7a53..6e7ffec27f 100644
--- a/src/qt/locale/bitcoin_cs.ts
+++ b/src/qt/locale/bitcoin_cs.ts
@@ -1,4 +1,4 @@
-<TS language="cs" version="2.1">
+<TS language="cs" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -168,6 +168,10 @@
<translation>Jsi si jistý, že chceš peněženku zašifrovat?</translation>
</message>
<message>
+ <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>Bitcoin Core se teď ukončí, aby dokončil zašifrování. Pamatuj však, že pouhé zašifrování peněženky nemůže zabránit krádeži tvých bitcoinů malwarem, kterým se může počítač nakazit.</translation>
+ </message>
+ <message>
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
<translation>DŮLEŽITÉ: Všechny předchozí zálohy peněženky by měly být nahrazeny nově vygenerovanou, zašifrovanou peněženkou. Z bezpečnostních důvodů budou předchozí zálohy nešifrované peněženky nepoužitelné, jakmile začneš používat novou zašifrovanou peněženku.</translation>
</message>
@@ -184,6 +188,10 @@
<translation>Zadej nové heslo k peněžence.&lt;br/&gt;Použij &lt;b&gt;alespoň deset náhodných znaků&lt;/b&gt; nebo &lt;b&gt;alespoň osm slov&lt;/b&gt;.</translation>
</message>
<message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Zadej staré a nové heslo k peněžence.</translation>
+ </message>
+ <message>
<source>Wallet encryption failed</source>
<translation>Zašifrování peněženky selhalo</translation>
</message>
@@ -391,6 +399,10 @@
<translation>O &amp;Bitcoin Core</translation>
</message>
<message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Uprav nastavení Bitcoin Core</translation>
+ </message>
+ <message>
<source>Show the list of used sending addresses and labels</source>
<translation>Ukaž seznam použitých odesílacích adres a jejich označení</translation>
</message>
@@ -419,6 +431,10 @@
<translation>Není dostupný žádný zdroj bloků...</translation>
</message>
<message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Zpracován %n blok transakční historie.</numerusform><numerusform>Zpracovány %n bloky transakční historie.</numerusform><numerusform>Zpracováno %n bloků transakční historie.</numerusform></translation>
+ </message>
+ <message numerus="yes">
<source>%n hour(s)</source>
<translation><numerusform>%n hodinu</numerusform><numerusform>%n hodiny</numerusform><numerusform>%n hodin</numerusform></translation>
</message>
@@ -471,6 +487,36 @@
<translation>Stahuji...</translation>
</message>
<message>
+ <source>Date: %1
+</source>
+ <translation>Datum: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Částka: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Typ: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Označení: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adresa: %1
+</translation>
+ </message>
+ <message>
<source>Sent transaction</source>
<translation>Odeslané transakce</translation>
</message>
@@ -669,6 +715,18 @@
<translation>žádná</translation>
</message>
<message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Popisek zčervená, pokud je velikost transakce větší než 1000 bajtů.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Popisek zčervená, pokud je priorita menší než „střední“.</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Popisek zčervená, pokud má některý příjemce obdržet částku menší než %1.</translation>
+ </message>
+ <message>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation>Může se lišit o +/– %1 satoshi na každý vstup.</translation>
</message>
@@ -919,6 +977,14 @@
<translation>IP adresa proxy (např. IPv4: 127.0.0.1/IPv6: ::1)</translation>
</message>
<message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Zavřením se aplikace minimalizuje. Pokud je tato volba zaškrtnuta, tak se aplikace ukončí pouze zvolením Konec v menu.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Tady lze nastavit jazyk uživatelského rozhraní. Nastavení se projeví až po restartování Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
<translation>URL třetích stran (např. block exploreru), které se zobrazí v kontextovém menu v záložce Transakce. %s v URL se nahradí hashem transakce. Více URL odděl svislítkem |.</translation>
</message>
@@ -943,6 +1009,14 @@
<translation>&amp;Síť</translation>
</message>
<message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Automaticky spustí Bitcoin Core po přihlášení do systému.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>S&amp;pustit Bitcoin Core po přihlášení do systému</translation>
+ </message>
+ <message>
<source>(0 = auto, &lt;0 = leave that many cores free)</source>
<translation>(0 = automaticky, &lt;0 = nechat daný počet jader volný, výchozí: 0)</translation>
</message>
@@ -1055,6 +1129,10 @@
<translation>K aktivaci změn je potřeba restartovat klienta.</translation>
</message>
<message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Klient se vypne, chceš pokračovat?</translation>
+ </message>
+ <message>
<source>This change would require a client restart.</source>
<translation>Tahle změna bude chtít restartovat klienta.</translation>
</message>
@@ -1189,10 +1267,18 @@
<translation>Soubor platebního požadavku nejde přečíst nebo zpracovat! Příčinou může být špatný soubor platebního požadavku.</translation>
</message>
<message>
+ <source>Payment request expired.</source>
+ <translation>Platební požadavek vypršel.</translation>
+ </message>
+ <message>
<source>Unverified payment requests to custom payment scripts are unsupported.</source>
<translation>Neověřené platební požadavky k uživatelským platebním skriptům nejsou podporované.</translation>
</message>
<message>
+ <source>Invalid payment request.</source>
+ <translation>Neplatný platební požadavek.</translation>
+ </message>
+ <message>
<source>Refund from %1</source>
<translation>Vrácení peněz od %1</translation>
</message>
@@ -1232,6 +1318,10 @@
<translation>Typ klienta</translation>
</message>
<message>
+ <source>Node/Service</source>
+ <translation>Uzel/Služba</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Odezva</translation>
</message>
@@ -1353,6 +1443,10 @@
<translation>Aktuální počet bloků</translation>
</message>
<message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Otevři soubor s ladicími záznamy Bitcoin Core z aktuálního datového adresáře. U velkých logů to může pár vteřin zabrat.</translation>
+ </message>
+ <message>
<source>Received</source>
<translation>Přijato</translation>
</message>
@@ -1421,6 +1515,10 @@
<translation>Odezva</translation>
</message>
<message>
+ <source>Time Offset</source>
+ <translation>Časový posun</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Čas posledního bloku</translation>
</message>
@@ -1465,6 +1563,10 @@
<translation>Vyčistit konzoli</translation>
</message>
<message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Vítej v RPC konzoli Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
<translation>V historii se pohybuješ šipkami nahoru a dolů a pomocí &lt;b&gt;Ctrl-L&lt;/b&gt; čistíš obrazovku.</translation>
</message>
@@ -1761,6 +1863,10 @@
<translation>Pokud je vlastní poplatek nastavený na 1000 satoshi a transakce má pouze 250 bajtů, tak „za kilobajt“ zaplatí poplatek jen 250 satoshi, zatímco „přinejmenším“ zaplatí 1000 satoshi. Pro transakce větší než kilobajt obě možnosti platí za kilobajt.</translation>
</message>
<message>
+ <source>Hide</source>
+ <translation>Skryj</translation>
+ </message>
+ <message>
<source>total at least</source>
<translation>přinejmenším</translation>
</message>
@@ -1901,10 +2007,30 @@
<translation>Transakce byla odmítnuta! Tohle může nastat, pokud nějaké mince z tvé peněženky už jednou byly utraceny, například pokud používáš kopii souboru wallet.dat a mince byly utraceny v druhé kopii, ale nebyly označeny jako utracené v této.</translation>
</message>
<message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Poplatek vyšší než %1 je považován za absurdně vysoký.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Platební požadavek vypršel.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Potvrzování by podle odhadu mělo začít během %n bloku.</numerusform><numerusform>Potvrzování by podle odhadu mělo začít během %n bloků.</numerusform><numerusform>Potvrzování by podle odhadu mělo začít během %n bloků.</numerusform></translation>
+ </message>
+ <message>
<source>Pay only the minimum fee of %1</source>
<translation>Zaplatit pouze minimální poplatek %1</translation>
</message>
<message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Adresa příjemce je neplatná – překontroluj ji prosím.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Zaznamenána duplicitní adresa: každá adresa by ale měla být použita vždy jen jednou.</translation>
+ </message>
+ <message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Upozornění: Neplatná Bitcoinová adresa</translation>
</message>
@@ -1976,10 +2102,26 @@
<translation>Smaž tento záznam</translation>
</message>
<message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Poplatek se odečte od posílané částky. Příjemce tak dostane méně bitcoinů, než zadáš do pole Částka. Pokud vybereš více příjemců, tak se poplatek rovnoměrně rozloží.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>&amp;Odečíst poplatek od částky</translation>
+ </message>
+ <message>
<source>Message:</source>
<translation>Zpráva:</translation>
</message>
<message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Tohle je neověřený platební požadavek.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Tohle je ověřený platební požadavek.</translation>
+ </message>
+ <message>
<source>Enter a label for this address to add it to the list of used addresses</source>
<translation>Zadej označení této adresy; obojí se ti pak uloží do adresáře</translation>
</message>
@@ -2018,6 +2160,10 @@
<translation>&amp;Podepiš zprávu</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>Podepsáním zprávy/smlouvy svými adresami můžeš prokázat, že jsi na ně schopen přijmout bitcoiny. Buď opatrný a nepodepisuj nic vágního nebo náhodného; například při phishingových útocích můžeš být lákán, abys něco takového podepsal. Podepisuj pouze naprosto úplná a detailní prohlášení, se kterými souhlasíš.</translation>
+ </message>
+ <message>
<source>The Bitcoin address to sign the message with</source>
<translation>Bitcoinová adresa, kterou se zpráva podepíše</translation>
</message>
@@ -2070,6 +2216,10 @@
<translation>&amp;Ověř zprávu</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>K ověření podpisu zprávy zadej adresu příjemce, zprávu (ověř si, že správně kopíruješ zalomení řádků, mezery, tabulátory apod.) a podpis. Dávej pozor na to, abys nezkopíroval do podpisu víc, než co je v samotné podepsané zprávě, abys nebyl napálen man-in-the-middle útokem. Poznamenejme však, že takto lze pouze prokázat, že podepisující je schopný na dané adrese přijmout platbu, ale není možnéprokázat, že odeslal jakoukoli transakci!</translation>
+ </message>
+ <message>
<source>The Bitcoin address the message was signed with</source>
<translation>Bitcoinová adresa, kterou je zpráva podepsána</translation>
</message>
@@ -2421,6 +2571,10 @@
<translation>Zda tato transakce zahrnuje i některou sledovanou adresu.</translation>
</message>
<message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Uživatelsky určený účel transakce.</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
<translation>Částka odečtená z nebo přičtená k účtu.</translation>
</message>
@@ -2640,7 +2794,7 @@
</message>
<message>
<source>Specify your own public address</source>
- <translation>Specifikuj svou veřejnou adresu</translation>
+ <translation>Udej svou veřejnou adresu</translation>
</message>
<message>
<source>Accept command line and JSON-RPC commands</source>
@@ -2671,16 +2825,16 @@
<translation>Šířen pod softwarovou licencí MIT, viz přiložený soubor COPYING nebo &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Přepnout do módu testování regresí, který používá speciální řetězec, ve kterém mohou být bloky okamžitě vyřešeny.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Spustit příkaz, když se objeví transakce týkající se peněženky (%s se v příkazu nahradí za TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>V tomto módu -genproclimit určuje, kolik bloků je vygenerováno okamžitě.</translation>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Horní hranice pro celkový poplatek za jednu transakci z peněženky; příliš nízká hodnota může zmařit velké transakce (výchozí: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%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, &gt;%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, &lt;0 = leave that many cores free, default: %d)</source>
@@ -2695,6 +2849,14 @@
<translation>Nedaří se mi připojit na %s na tomhle počítači. Bitcoin Core už pravděpodobně jednou běží.</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>UPOZORNĚNÍ: vygenerováno nezvykle mnoho bloků – přijato %d bloků jen za posledních %d hodin (očekáváno %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>UPOZORNĚNÍ: zkontroluj své spojení do sítě – bylo přijato %d bloků za posledních %d hodin (očekáváno %d)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Upozornění: -paytxfee je nastaveno velmi vysoko! Toto je transakční poplatek, který zaplatíš za každou poslanou transakci.</translation>
</message>
@@ -2732,7 +2894,7 @@
</message>
<message>
<source>Block creation options:</source>
- <translation>Možnosti vytvoření bloku:</translation>
+ <translation>Možnosti vytváření bloku:</translation>
</message>
<message>
<source>Connect only to the specified node(s)</source>
@@ -2811,6 +2973,14 @@
<translation>Připojovat se pouze k uzlům v &lt;net&gt; síti (ipv4, ipv6 nebo onion)</translation>
</message>
<message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Prořezávání nemůže být zkonfigurováno s negativní hodnotou.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Prořezávací režim není kompatibilní s -txindex.</translation>
+ </message>
+ <message>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation>Nastavit velikost databázové vyrovnávací paměti v megabajtech (%d až %d, výchozí: %d)</translation>
</message>
@@ -2823,16 +2993,12 @@
<translation>Udej název souboru s peněženkou (v rámci datového adresáře)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Tohle je určeno pro nástroje na regresní testování a vyvíjení aplikací.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Použít UPnP k namapování naslouchacího portu (výchozí: %u)</translation>
</message>
<message>
<source>Verifying blocks...</source>
- <translation>Ověřuji bloky... </translation>
+ <translation>Ověřuji bloky...</translation>
</message>
<message>
<source>Verifying wallet...</source>
@@ -2847,6 +3013,10 @@
<translation>Možnosti peněženky:</translation>
</message>
<message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Upozornění: tahle verze je zastaralá, měl bys ji aktualizovat!</translation>
+ </message>
+ <message>
<source>You need to rebuild the database using -reindex to change -txindex</source>
<translation>Je třeba přestavět databázi použitím -reindex, aby bylo možné změnit -txindex</translation>
</message>
@@ -2879,6 +3049,10 @@
<translation>Vytvářet nové soubory s výchozími systémovými právy namísto umask 077 (uplatní se, pouze pokud je vypnutá funkce peněženky)</translation>
</message>
<message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Zjistit vlastní IP adresu (výchozí: 1, pokud naslouchá a není zadáno -externalip nebo -proxy)</translation>
+ </message>
+ <message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Chyba: Nelze naslouchat příchozí spojení (listen vrátil chybu %s)</translation>
</message>
@@ -2892,25 +3066,33 @@
</message>
<message>
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
- <translation>Poplatky (v BTC/Kb) menší než tato hodnota jsou považovány za nulové pro účely přeposílání transakcí (výchozí: %s)</translation>
+ <translation>Poplatky (v BTC/kB) menší než tato hodnota jsou považovány za nulové pro účely přeposílání transakcí (výchozí: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Poplatky (v BTC/Kb) menší než tato hodnota jsou považovány za nulové pro účely vytváření transakcí (výchozí: %s)</translation>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Pokud paytxfee není nastaveno, platit dostatečný poplatek na to, aby začaly být transakce potvrzovány v průměru během n bloků (výchozí: %u)</translation>
</message>
<message>
- <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
- <translation>Pokud paytxfee není nastaveno, platit dostatečný poplatek na to, aby byly transakce potvrzeny v průměru během n bloků (výchozí: %u)</translation>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Neplatná částka pro -maxtxfee=&lt;amount&gt;: '%s' (musí být alespoň jako poplatek minrelay %s, aby transakce nezůstávaly trčet)</translation>
</message>
<message>
<source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
<translation>Maximální velikost dat v transakcích nesoucích data, se kterou jsme ochotni je ještě přeposílat a těžit (výchozí: %u)</translation>
</message>
<message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Prořezávání je nastaveno pod minimum %d MB. Použij prosím nějaké vyšší číslo.</translation>
+ </message>
+ <message>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation>Při nedostatku adres získat další protějšky z DNS (výchozí: 1, pokud není použito -connect)</translation>
</message>
<message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Použít náhodné údaje pro každé proxy spojení. To umožní izolovat nesouvisející datové toky v Toru (výchozí: %u)</translation>
+ </message>
+ <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Nastavit maximální velikost prioritních/nízkopoplatkových transakcí v bajtech (výchozí: %d)</translation>
</message>
@@ -2919,10 +3101,42 @@
<translation>Nastavení počtu vláken pro těžení, je-li zapnuté (-1 = všechna jádra, výchozí: %d)</translation>
</message>
<message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Částka v transakci po odečtení poplatku je příliš malá na odeslání</translation>
+ </message>
+ <message>
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
<translation>Tento produkt zahrnuje programy vyvinuté OpenSSL Projektem pro použití v OpenSSL Toolkitu &lt;https://www.openssl.org/&gt; 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>
@@ -2931,6 +3145,26 @@
<translation>Na protějšky na bílé listině se nevztahuje DoS klatba a jejich transakce jsou vždy přeposílány, i když už třeba jsou v mempoolu, což je užitečné např. pro bránu</translation>
</message>
<message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>K návratu k neprořezávacímu režimu je potřeba přestavět databázi použitím -reindex. Také se znovu stáhne celý řetězec bloků</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Přijímat veřejné REST požadavky (výchozí: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Aktivuji nejlepší řetězec...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>V prořezávacím režimu se s pěněženkou nemůžu spustit.</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>Nemohu přeložit -whitebind adresu: '%s'</translation>
</message>
@@ -2975,6 +3209,10 @@
<translation>Selhala úvodní zevrubná prověrka. Bitcoin Core se ukončuje.</translation>
</message>
<message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Neplatná částka pro -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
<source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
<translation>Neplatná částka pro -minrelaytxfee=&lt;částka&gt;: '%s'</translation>
</message>
@@ -3011,12 +3249,16 @@
<translation>Možnosti RPC serveru:</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Náhodně zahazovat jednu z každých &lt;n&gt; síťových zpráv</translation>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Podpora RPC pro perzistentní HTTP spojení (výchozí: %d)</translation>
</message>
<message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Náhodně pozměňovat jednu z každých &lt;n&gt; síťových zpráv</translation>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Při startu znovu vytvořit index řetězce bloků z aktuálních blk000??.dat souborů</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Přijímat a zobrazovat poplachy z P2P sítě (výchozí: %u)</translation>
</message>
<message>
<source>Send trace/debug info to console instead of debug.log file</source>
@@ -3032,7 +3274,7 @@
</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>
+ <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>
@@ -3055,6 +3297,10 @@
<translation>Nastartovat minimalizovaně</translation>
</message>
<message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Částka v transakci je příliš malá na pokrytí poplatku</translation>
+ </message>
+ <message>
<source>This is experimental software.</source>
<translation>Tohle je experimentální program.</translation>
</message>
@@ -3075,6 +3321,10 @@
<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>
@@ -3155,18 +3405,10 @@
<translation>(1 = ukládat transakční metadata, např. majitele účtu a informace o platebním požadavku, 2 = mazat transakční metadata)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Promítnout databázovou aktivitu z paměťového prostoru do záznamu na disku každých &lt;n&gt; megabajtů (výchozí: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Jak moc důkladná má být verifikace bloků -checkblocks (0-4, výchozí: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Zaznamenávat během těžení bloků prioritu transakce a poplatek za kB (výchozí: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Spravovat úplný index transakcí, který je využíván rpc voláním getrawtransaction (výchozí: %u)</translation>
</message>
@@ -3195,18 +3437,10 @@
<translation>Vždy získávat adresy dalších protějšků přes DNS (výchozí: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Vypnout bezpečný režim (safemode), překrýt skutečnou událost bezpečného režimu (výchozí: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>Chyba při načítání wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Vynutit bezpečný mód (výchozí: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Těžit (výchozí: %u)</translation>
</message>
@@ -3223,10 +3457,6 @@
<translation>Neplatná -proxy adresa: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Omezit velikost vyrovnávací paměti pro podpisy na &lt;n&gt; položek (výchozí: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Čekat na JSON-RPC spojení na &lt;portu&gt; (výchozí: %u nebo testnet: %u)</translation>
</message>
@@ -3239,6 +3469,10 @@
<translation>Povolit nejvýše &lt;n&gt; protějšků (výchozí: %u)</translation>
</message>
<message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Transakce z peněženky rozesílat</translation>
+ </message>
+ <message>
<source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
<translation>Maximální velikost přijímacího bufferu pro každé spojení, &lt;n&gt;*1000 bajtů (výchozí: %u)</translation>
</message>
@@ -3247,10 +3481,6 @@
<translation>Maximální velikost odesílacího bufferu pro každé spojení, &lt;n&gt;*1000 bajtů (výchozí: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Uznávat pouze řetězec bloků, který odpovídá vnitřním kontrolním bodům (výchozí: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Připojit před ladicí výstup časové razítko (výchozí: %u)</translation>
</message>
@@ -3263,10 +3493,6 @@
<translation>Přeposílat ne-P2SH multisig (výchozí: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Spustit vlákno pročišťující periodicky peněženku (výchozí: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>Soubor se serverovým certifikátem (výchozí: %s)</translation>
</message>
@@ -3287,10 +3513,6 @@
<translation>Nastavení počtu vláken pro servisní RPC volání (výchozí: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Nastavit příznak DB_PRIVATE v databázovém prostředí peněženky (výchozí: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Konfigurační soubor (výchozí: %s)</translation>
</message>
@@ -3303,10 +3525,6 @@
<translation>Utrácet i ještě nepotvrzené drobné při posílání transakcí (výchozí: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Ukončit se po importu bloků z disku (výchozí: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Práh pro odpojování zlobivých protějšků (výchozí: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_cy.ts b/src/qt/locale/bitcoin_cy.ts
index 9867375fb2..1b8eb3dc41 100644
--- a/src/qt/locale/bitcoin_cy.ts
+++ b/src/qt/locale/bitcoin_cy.ts
@@ -1,4 +1,4 @@
-<TS language="cy" version="2.1">
+<TS language="cy" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts
index 1467791047..60b8925e8c 100644
--- a/src/qt/locale/bitcoin_da.ts
+++ b/src/qt/locale/bitcoin_da.ts
@@ -1,4 +1,4 @@
-<TS language="da" version="2.1">
+<TS language="da" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -2813,10 +2813,6 @@
<translation>Tildel til den givne adresse og lyt altid på den. Brug [vært]:port-notation for IPv6</translation>
</message>
<message>
- <source>Continuously rate-limit free transactions to &lt;n&gt;*1000 bytes per minute (default: %u)</source>
- <translation>Begræns hyppigheden af gratis transaktioner løbende til &lt;n&gt;*1000 byte pr. minut (standard: %u)</translation>
- </message>
- <message>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Slet alle transaktioner i tegnebogen og genskab kun disse dele af blokkæden gennem -rescan under opstart</translation>
</message>
@@ -2825,18 +2821,10 @@
<translation>Distribueret under MIT-softwarelicensen; se den vedlagte fil COPYING eller &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Start regressionstesttilstand, som bruger en speciel kæde, hvor blokke kan løses med det samme.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Udfør kommando, når en transaktion i tegnebogen ændres (%s i kommandoen erstattes med TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>I denne tilstand styrer -genproclimit hvor mange blokke, der genereres med det samme.</translation>
- </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>
@@ -2857,6 +2845,14 @@
<translation>Ikke i stand til at tildele til %s på denne computer. Bitcoin Core kører sansynligvis allerede.</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ADVARSEL: unormalt mange blokke er genereret; %d blokke er modtaget i løbet af de seneste %d timer (%d forventet)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ADVARSEL: tjek din netværksforbindelse; %d blokke er modtaget i løbet af de seneste %d timer (%d forventet)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Advarsel: -paytxfee er sat meget højt! Dette er det gebyr du vil betale, hvis du sender en transaktion.</translation>
</message>
@@ -2993,10 +2989,6 @@
<translation>Angiv tegnebogsfil (inden for datamappe)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>This is intended for regression testing tools and app development.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Brug UPnP til at konfigurere den lyttende port (standard: %u)</translation>
</message>
@@ -3073,10 +3065,6 @@
<translation>Gebyrer (i BTC/Kb) mindre end dette opfattes som nulgebyr for videresendelse (standard: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Gebyrer (i BTC/Kb) mindre end dette opfattes som nulgebyr for oprettelse af transaktion (standard: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Hvis paytxfee ikke er sat, inkluderes nok gebyr til at transaktioner begynder at blive bekræftet ingen for gennemsnitligt n blokke (standard: %u)</translation>
</message>
@@ -3101,10 +3089,6 @@
<translation>Brug tilfældige akkreditiver for hver proxy-forbindelse. Dette tillader strømisolation med Tor (standard: %u)</translation>
</message>
<message>
- <source>Require high priority for relaying free or low-fee transactions (default: %u)</source>
- <translation>Kræv høj prioritet for at videresende transaktioner uden eller med lavt gebyr (standard: %u)</translation>
- </message>
- <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Sæt maksimumstørrelse for højprioritet/lavgebyr-transaktioner i byte (standard: %d)</translation>
</message>
@@ -3173,10 +3157,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Aktiverer bedste kæde …</translation>
</message>
<message>
- <source>Allow self signed root certificates (default: 0)</source>
- <translation>Tillad selvsignerede rodcertifikater (standard: 0)</translation>
- </message>
- <message>
<source>Can't run with a wallet in prune mode.</source>
<translation>Kan ikke køre med en tegnebog i beskåret tilstand.</translation>
</message>
@@ -3269,18 +3249,14 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>RPC-understøttelse for HTTP-persistente forbindelser (standard: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Drop tilfældigt 1 ud af hver &lt;n&gt; netværksbeskeder</translation>
- </message>
- <message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Slør tilfældigt 1 ud af hver &lt;n&gt; netværksbeskeder</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>
<message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Modtag og vis P2P-netværksadvarsler (standard: %u)</translation>
+ </message>
+ <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Send sporings-/fejlsøgningsinformation til konsollen i stedet for debug.log filen</translation>
</message>
@@ -3425,18 +3401,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>(1 = behold metadata for transaktion, fx kontoindehaver og information om betalingsanmodning, 2 = drop metadata for transaktion)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Flyt databaseaktivitet fra hukommelsespulje til disklog hver &lt;n&gt; megabyte (standard: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Hvor gennemarbejdet blokverificeringen for -checkblocks er (0-4; standard: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Prioritet for transaktionslog og gebyr pr. kB under udvinding af blokke (standard: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Vedligehold et komplet transaktionsindeks, der bruges af rpc-kaldet getrawtransaction (standard: %u)</translation>
</message>
@@ -3465,18 +3433,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Forespørg altid adresser på andre knuder via DNS-opslag (default: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Slå sikker tilstand fra, tilsidesæt hændelser fra sikker tilstand (standard: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>Fejl ved indlæsning af wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Gennemtving sikker tilstand (standard: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Generér bitcoins (standard: %u)</translation>
</message>
@@ -3493,10 +3453,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Ugyldig -proxy adresse: "%s"</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Begræns størrelsen på signaturcache til &lt;n&gt; indgange (standard: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Lyt efter JSON-RPC-forbindelser på &lt;port&gt; (standard: %u eller testnet: %u)</translation>
</message>
@@ -3521,10 +3477,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Maksimum for afsendelsesbuffer pr. forbindelse, &lt;n&gt;*1000 byte (standard: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Acceptér kun indbyggede kontrolposter, der matcher blokkæden (standard: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Føj tidsstempel foran fejlsøgningsoutput (standard: %u)</translation>
</message>
@@ -3537,10 +3489,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Videresend ikke-P2SH multisig (standard: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Kør en tråd for periodisk at rydde tegnebog (standard: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>Servercertifikat-fil (standard: %s)
</translation>
@@ -3563,10 +3511,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Angiv antallet af tråde til at håndtere RPC-kald (standard: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Sætter DB_PRIVATE-flaget i tegnebogens db-miljø (standard: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Angiv konfigurationsfil (standard: %s)</translation>
</message>
@@ -3583,10 +3527,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Brug ubekræftede byttepenge under afsendelse af transaktioner (standard: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Stop kørsel efter import af blokke fra disk (standard: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Grænse for afbrydelse af forbindelse til knuder, der opfører sig upassende (standard: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts
index ab0367dbab..a50a6e60cb 100644
--- a/src/qt/locale/bitcoin_de.ts
+++ b/src/qt/locale/bitcoin_de.ts
@@ -1,4 +1,4 @@
-<TS language="de" version="2.1">
+<TS language="de" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -2817,10 +2817,6 @@
<translation>An die angegebene Adresse binden und immer abhören. Für IPv6 "[Host]:Port"-Notation verwenden</translation>
</message>
<message>
- <source>Continuously rate-limit free transactions to &lt;n&gt;*1000 bytes per minute (default: %u)</source>
- <translation>Durchgehend die Anzahl freier Transaktionen auf &lt;n&gt; * 1000 Byte pro Minute begrenzen (Standard: %u)</translation>
- </message>
- <message>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Alle Wallet-Transaktionen löschen und nur diese Teilbereiche der Blockkette durch -rescan beim Starten wiederherstellen</translation>
</message>
@@ -2829,18 +2825,10 @@
<translation>Veröffentlicht unter der MIT-Softwarelizenz, siehe beiligende Datei COPYING oder &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Regressionstest-Modus aktivieren, der eine spezielle Blockkette nutzt, in der Blöcke sofort gelöst werden können.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Befehl ausführen wenn sich eine Wallet-Transaktion verändert (%s im Befehl wird durch die Transaktions-ID ersetzt)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>In diesem Modus legt -genproclimit fest, wie viele Blöcke sofort erzeugt werden.</translation>
- </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>
@@ -2861,6 +2849,14 @@
<translation>Kann auf diesem Computer nicht an %s binden, da Bitcoin Core wahrscheinlich bereits gestartet wurde.</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>Warnung: Es wurde eine ungewöhnlich hohe Anzahl Blöcke erzeugt, %d Blöcke wurden in den letzten %d Stunden empfangen (%d wurden erwartet).</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>Warnung: Überprüpfen Sie ihre Netzwerkverbindung, %d Blöcke wurden in den letzten %d Stunden empfangen (%d wurden erwartet).</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Warnung: -paytxfee ist auf einen sehr hohen Wert festgelegt! Dies ist die Gebühr die beim Senden einer Transaktion fällig wird.</translation>
</message>
@@ -2997,10 +2993,6 @@
<translation>Wallet-Datei angeben (innerhalb des Datenverzeichnisses)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Dies ist für Regressionstest-Tools und Anwendungsentwicklung gedacht.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: %u)</translation>
</message>
@@ -3077,10 +3069,6 @@
<translation>Niedrigere Gebühren (in BTC/Kb) als diese werden bei der Weiterleitung als gebührenfrei angesehen (Standard: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Niedrigere Gebühren (in BTC/Kb) als diese werden bei der Transaktionserstellung als gebührenfrei angesehen (Standard: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Wenn -paytxfee nicht festgelegt wurde Gebühren einschließen, so dass mit der Bestätigung von Transaktionen im Schnitt innerhalb von n Blöcken begonnen wird (Standard: %u)</translation>
</message>
@@ -3105,10 +3093,6 @@
<translation>Zufällige Anmeldedaten für jede Proxyverbindung verwenden. Dies aktiviert Tor-Datenflussisolation (Standard: %u)</translation>
</message>
<message>
- <source>Require high priority for relaying free or low-fee transactions (default: %u)</source>
- <translation>Hohe Priorität zum Weiterleiten von freien bzw. Transaktionen mit niedrigen Gebühren voraussetzen (Standard: %u)</translation>
- </message>
- <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Maximale Größe in Byte von "high-priority/low-fee"-Transaktionen festlegen (Standard: %d)</translation>
</message>
@@ -3177,10 +3161,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Aktiviere beste Blockkette...</translation>
</message>
<message>
- <source>Allow self signed root certificates (default: 0)</source>
- <translation>Selbstunterschriebene Stammzertifikate erlauben (Standard: 0)</translation>
- </message>
- <message>
<source>Can't run with a wallet in prune mode.</source>
<translation>Eine Wallet kann im Kürzungsmodus nicht verwendet werden.</translation>
</message>
@@ -3273,18 +3253,14 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Unterstützung für persistente HTTP-Verbindungen bei RPC (Standard: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Zufällig eine von &lt;n&gt; Netzwerknachrichten verwerfen</translation>
- </message>
- <message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Zufällig eine von &lt;n&gt; Netzwerknachrichten verwürfeln</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>
<message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>P2P-Netzwerk-Alarme empfangen und anzeigen (Standard: %u)</translation>
+ </message>
+ <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Rückverfolgungs- und Debuginformationen an die Konsole senden, anstatt sie in debug.log zu schreiben</translation>
</message>
@@ -3429,18 +3405,10 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>(1 = TX-Metadaten wie z.B. Accountbesitzer und Zahlungsanforderungsinformationen behalten, 2 = TX-Metadaten verwerfen)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Datenbankaktivitäten vom Arbeitsspeicher-Pool alle &lt;n&gt; Megabyte auf den Datenträger schreiben (Standard: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Legt fest, wie gründlich die Blockverifikation von -checkblocks ist (0-4, Standard: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Transaktionspriorität und Gebühr pro kB beim Erzeugen von Blöcken protokollieren (Standard: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Einen vollständigen Transaktionsindex führen, der vom RPC-Befehl "getrawtransaction" genutzt wird (Standard: %u)</translation>
</message>
@@ -3469,18 +3437,10 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Adressen von Gegenstellen immer über DNS-Namensauflösung abfragen (Standard: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Sicherheitsmodus deaktivieren, übergeht ein echtes Sicherheitsmodusereignis (Standard: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>Fehler beim Laden von wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Sicherheitsmodus erzwingen (Standard: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Bitcoins erzeugen (Standard: %u)</translation>
</message>
@@ -3497,10 +3457,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Ungültige Adresse in -proxy: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Größe des Signaturcaches auf &lt;n&gt; Einträge begrenzen (Standard: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>&lt;port&gt; nach JSON-RPC-Verbindungen abhören (Standard: %u oder Testnetz: %u)</translation>
</message>
@@ -3521,10 +3477,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Maximale Größe des Sendepuffers pro Verbindung, &lt;n&gt; * 1000 Byte (Standard: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Blockkette nur als gültig ansehen, wenn sie mit den integrierten Prüfpunkten übereinstimmt (Standard: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Debugausgaben einen Zeitstempel voranstellen (Standard: %u)</translation>
</message>
@@ -3537,10 +3489,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Nicht-"P2SH-Multisig" weiterleiten (Standard: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Einen Thread starten, der periodisch die Wallet sicher auf den Datenträger schreibt (Standard: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>Serverzertifikat (Standard: %s)</translation>
</message>
@@ -3561,10 +3509,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Maximale Anzahl an Threads zur Verarbeitung von RPC-Anfragen festlegen (Standard: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>"DB_PRIVATE"-Flag in der Wallet-Datenbankumgebung setzen (Standard: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Konfigurationsdatei festlegen (Standard: %s)</translation>
</message>
@@ -3581,10 +3525,6 @@ Beispiel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Unbestätigtes Wechselgeld darf beim Senden von Transaktionen ausgegeben werden (Standard: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Beenden, nachdem Blöcke vom Datenträger importiert wurden (Standard: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Schwellenwert, um Verbindungen zu sich nicht konform verhaltenden Gegenstellen zu beenden (Standard: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts
index a4c95857ba..8a0958a7bd 100644
--- a/src/qt/locale/bitcoin_el_GR.ts
+++ b/src/qt/locale/bitcoin_el_GR.ts
@@ -1,4 +1,4 @@
-<TS language="el_GR" version="2.1">
+<TS language="el_GR" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -2494,10 +2494,6 @@
<translation>Αποθηκευση σε συγκεκριμένη διεύθυνση. Χρησιμοποιήστε τα πλήκτρα [Host] : συμβολισμός θύρα για IPv6</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Εισαγωγή δοκιμαστικής λειτουργίας παλινδρόμησης, που χρησιμοποιεί μια ειδική αλυσίδα στην οποία τα μπλοκ επιλύονται στιγμιαία.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Εκτέλεσε την εντολή όταν το καλύτερο μπλοκ αλλάξει(%s στην εντολή αντικαθίσταται από το hash του μπλοκ)</translation>
</message>
@@ -2594,10 +2590,6 @@
<translation>Επιλέξτε αρχείο πορτοφολιού (μέσα απο κατάλογο δεδομένων)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Αυτό προορίζεται για εργαλεία δοκιμών παλινδρόμησης και την ανάπτυξη εφαρμογών.</translation>
- </message>
- <message>
<source>Verifying blocks...</source>
<translation>Επαλήθευση των μπλοκ... </translation>
</message>
@@ -2802,10 +2794,6 @@
<translation>Σφάλμα φόρτωσης αρχείου wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Επιβολή ασφαλής λειτουργίας (προεπιλογή: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Δημιουργία νομισμάτων (προκαθορισμος: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index 90a13feaca..3ebb4d0bf6 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -104,7 +104,7 @@
<translation>&amp;Edit</translation>
</message>
<message>
- <location line="+194"/>
+ <location line="+193"/>
<source>Export Address List</source>
<translation type="unfinished"></translation>
</message>
@@ -284,29 +284,42 @@
</message>
</context>
<context>
+ <name>BanTableModel</name>
+ <message>
+ <location filename="../bantablemodel.cpp" line="+88"/>
+ <source>IP/Netmask</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Banned Until</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>BitcoinGUI</name>
<message>
- <location filename="../bitcoingui.cpp" line="+326"/>
+ <location filename="../bitcoingui.cpp" line="+324"/>
<source>Sign &amp;message...</source>
<translation>Sign &amp;message...</translation>
</message>
<message>
- <location line="+342"/>
+ <location line="+353"/>
<source>Synchronizing with network...</source>
<translation>Synchronizing with network...</translation>
</message>
<message>
- <location line="-418"/>
+ <location line="-429"/>
<source>&amp;Overview</source>
<translation>&amp;Overview</translation>
</message>
<message>
- <location line="-134"/>
+ <location line="-130"/>
<source>Node</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+135"/>
+ <location line="+131"/>
<source>Show general overview of wallet</source>
<translation>Show general overview of wallet</translation>
</message>
@@ -376,12 +389,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+175"/>
+ <location line="+180"/>
<source>Bitcoin Core client</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+157"/>
+ <location line="+163"/>
<source>Importing blocks from disk...</source>
<translation>Importing blocks from disk...</translation>
</message>
@@ -391,7 +404,7 @@
<translation>Reindexing blocks on disk...</translation>
</message>
<message>
- <location line="-416"/>
+ <location line="-427"/>
<source>Send coins to a Bitcoin address</source>
<translation>Send coins to a Bitcoin address</translation>
</message>
@@ -421,17 +434,17 @@
<translation>&amp;Verify message...</translation>
</message>
<message>
- <location line="+439"/>
+ <location line="+450"/>
<source>Bitcoin</source>
<translation>Bitcoin</translation>
</message>
<message>
- <location line="-653"/>
+ <location line="-660"/>
<source>Wallet</source>
<translation>Wallet</translation>
</message>
<message>
- <location line="+143"/>
+ <location line="+139"/>
<source>&amp;Send</source>
<translation>&amp;Send</translation>
</message>
@@ -471,7 +484,7 @@
<translation>Verify messages to ensure they were signed with specified Bitcoin addresses</translation>
</message>
<message>
- <location line="+49"/>
+ <location line="+53"/>
<source>&amp;File</source>
<translation>&amp;File</translation>
</message>
@@ -496,7 +509,7 @@
<translation type="unfinished">Bitcoin Core</translation>
</message>
<message>
- <location line="+164"/>
+ <location line="+160"/>
<source>Request payments (generates QR codes and bitcoin: URIs)</source>
<translation type="unfinished"></translation>
</message>
@@ -536,7 +549,7 @@
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location line="+309"/>
+ <location line="+320"/>
<source>%n active connection(s) to Bitcoin network</source>
<translation>
<numerusform>%n active connection to Bitcoin network</numerusform>
@@ -688,7 +701,7 @@
<context>
<name>ClientModel</name>
<message>
- <location filename="../clientmodel.cpp" line="+141"/>
+ <location filename="../clientmodel.cpp" line="+143"/>
<source>Network Alert</source>
<translation>Network Alert</translation>
</message>
@@ -791,7 +804,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../coincontroldialog.cpp" line="+46"/>
+ <location filename="../coincontroldialog.cpp" line="+47"/>
<source>Copy address</source>
<translation type="unfinished">Copy address</translation>
</message>
@@ -912,7 +925,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+161"/>
+ <location line="+160"/>
<source>This label turns red if the transaction size is greater than 1000 bytes.</source>
<translation type="unfinished"></translation>
</message>
@@ -958,8 +971,8 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+59"/>
- <location line="+61"/>
+ <location line="+58"/>
+ <location line="+60"/>
<source>(no label)</source>
<translation type="unfinished">(no label)</translation>
</message>
@@ -1045,7 +1058,7 @@
<context>
<name>FreespaceChecker</name>
<message>
- <location filename="../intro.cpp" line="+69"/>
+ <location filename="../intro.cpp" line="+68"/>
<source>A new data directory will be created.</source>
<translation>A new data directory will be created.</translation>
</message>
@@ -1240,6 +1253,7 @@
</message>
<message>
<location line="+44"/>
+ <location line="+187"/>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation type="unfinished"></translation>
</message>
@@ -1280,7 +1294,7 @@
<translation>&amp;Reset Options</translation>
</message>
<message>
- <location line="-317"/>
+ <location line="-504"/>
<source>&amp;Network</source>
<translation>&amp;Network</translation>
</message>
@@ -1346,21 +1360,61 @@
</message>
<message>
<location line="+9"/>
+ <location line="+187"/>
<source>Proxy &amp;IP:</source>
<translation>Proxy &amp;IP:</translation>
</message>
<message>
- <location line="+32"/>
+ <location line="-155"/>
+ <location line="+187"/>
<source>&amp;Port:</source>
<translation>&amp;Port:</translation>
</message>
<message>
- <location line="+25"/>
+ <location line="-162"/>
+ <location line="+187"/>
<source>Port of the proxy (e.g. 9050)</source>
<translation>Port of the proxy (e.g. 9050)</translation>
</message>
<message>
- <location line="+36"/>
+ <location line="-163"/>
+ <source>Used for reaching peers via:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <location line="+23"/>
+ <location line="+23"/>
+ <source>Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-36"/>
+ <source>IPv4</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>IPv6</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
+ <source>Tor</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+102"/>
<source>&amp;Window</source>
<translation>&amp;Window</translation>
</message>
@@ -1400,12 +1454,12 @@
<translation>Choose the default subdivision unit to show in the interface and when sending coins.</translation>
</message>
<message>
- <location line="-253"/>
+ <location line="-440"/>
<source>Whether to show coin control features or not.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+415"/>
+ <location line="+602"/>
<source>&amp;OK</source>
<translation>&amp;OK</translation>
</message>
@@ -1415,7 +1469,7 @@
<translation>&amp;Cancel</translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="+75"/>
+ <location filename="../optionsdialog.cpp" line="+83"/>
<source>default</source>
<translation>default</translation>
</message>
@@ -1425,28 +1479,28 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+76"/>
+ <location line="+83"/>
<source>Confirm options reset</source>
<translation>Confirm options reset</translation>
</message>
<message>
<location line="+1"/>
- <location line="+29"/>
+ <location line="+30"/>
<source>Client restart required to activate changes.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-29"/>
+ <location line="-30"/>
<source>Client will be shut down. Do you want to proceed?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+33"/>
+ <location line="+34"/>
<source>This change would require a client restart.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+25"/>
+ <location line="+24"/>
<source>The supplied proxy address is invalid.</source>
<translation>The supplied proxy address is invalid.</translation>
</message>
@@ -1548,7 +1602,7 @@
<context>
<name>PaymentServer</name>
<message>
- <location filename="../paymentserver.cpp" line="+434"/>
+ <location filename="../paymentserver.cpp" line="+432"/>
<location line="+14"/>
<location line="+7"/>
<source>URI handling</source>
@@ -1560,16 +1614,17 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+88"/>
+ <location line="+83"/>
<location line="+9"/>
<location line="+31"/>
<location line="+10"/>
<location line="+17"/>
+ <location line="+88"/>
<source>Payment request rejected</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-67"/>
+ <location line="-155"/>
<source>Payment request network doesn&apos;t match client network.</source>
<translation type="unfinished"></translation>
</message>
@@ -1584,17 +1639,17 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-263"/>
- <location line="+221"/>
+ <location line="-258"/>
+ <location line="+216"/>
<location line="+42"/>
- <location line="+114"/>
+ <location line="+113"/>
<location line="+14"/>
<location line="+18"/>
<source>Payment request error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-408"/>
+ <location line="-402"/>
<source>Cannot start bitcoin: click-to-pay handler</source>
<translation type="unfinished"></translation>
</message>
@@ -1619,7 +1674,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+75"/>
+ <location line="+70"/>
<source>Payment request expired.</source>
<translation type="unfinished"></translation>
</message>
@@ -1640,17 +1695,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+43"/>
+ <location line="+44"/>
<source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
- <source>Payment request DoS protection</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+5"/>
+ <location line="+9"/>
<source>Error communicating with %1: %2</source>
<translation type="unfinished"></translation>
</message>
@@ -1678,7 +1728,7 @@
<context>
<name>PeerTableModel</name>
<message>
- <location filename="../peertablemodel.cpp" line="+118"/>
+ <location filename="../peertablemodel.cpp" line="+117"/>
<source>User Agent</source>
<translation type="unfinished"></translation>
</message>
@@ -1706,7 +1756,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+748"/>
+ <location line="+761"/>
<source>%1 d</source>
<translation type="unfinished"></translation>
</message>
@@ -1768,7 +1818,7 @@
<context>
<name>RPCConsole</name>
<message>
- <location filename="../forms/rpcconsole.ui" line="+46"/>
+ <location filename="../forms/debugwindow.ui" line="+46"/>
<source>Client name</source>
<translation>Client name</translation>
</message>
@@ -1777,13 +1827,16 @@
<location line="+23"/>
<location line="+26"/>
<location line="+26"/>
+ <location line="+26"/>
<location line="+23"/>
<location line="+23"/>
<location line="+36"/>
<location line="+23"/>
<location line="+36"/>
<location line="+23"/>
- <location line="+465"/>
+ <location line="+533"/>
+ <location line="+23"/>
+ <location line="+23"/>
<location line="+23"/>
<location line="+23"/>
<location line="+23"/>
@@ -1796,12 +1849,13 @@
<location line="+23"/>
<location line="+23"/>
<location line="+23"/>
+ <location line="+26"/>
<location line="+23"/>
<source>N/A</source>
<translation>N/A</translation>
</message>
<message>
- <location line="-990"/>
+ <location line="-1156"/>
<source>Client version</source>
<translation>Client version</translation>
</message>
@@ -1821,7 +1875,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+53"/>
+ <location line="+79"/>
<source>Using OpenSSL version</source>
<translation>Using OpenSSL version</translation>
</message>
@@ -1881,14 +1935,24 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+39"/>
- <location filename="../rpcconsole.cpp" line="+238"/>
- <location line="+326"/>
+ <location line="+50"/>
+ <source>Banned peers</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+57"/>
+ <location filename="../rpcconsole.cpp" line="+281"/>
+ <location line="+560"/>
<source>Select a peer to view detailed information.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+25"/>
+ <source>Whitelisted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
<source>Direction</source>
<translation type="unfinished"></translation>
</message>
@@ -1898,27 +1962,33 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+23"/>
- <source>User Agent</source>
+ <location line="+69"/>
+ <source>Starting Block</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+23"/>
- <source>Services</source>
+ <source>Synced Headers</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+23"/>
- <source>Starting Height</source>
+ <source>Synced Blocks</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+23"/>
- <source>Sync Height</source>
+ <location line="-913"/>
+ <location line="+821"/>
+ <source>User Agent</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+23"/>
+ <source>Services</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+92"/>
<source>Ban Score</source>
<translation type="unfinished"></translation>
</message>
@@ -1954,11 +2024,21 @@
</message>
<message>
<location line="+23"/>
+ <source>The duration of a currently outstanding ping.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Ping Wait</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+23"/>
<source>Time Offset</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-764"/>
+ <location line="-904"/>
<source>Last block time</source>
<translation>Last block time</translation>
</message>
@@ -1988,7 +2068,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../rpcconsole.cpp" line="-164"/>
+ <location filename="../rpcconsole.cpp" line="-333"/>
<source>In:</source>
<translation type="unfinished"></translation>
</message>
@@ -1998,7 +2078,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/rpcconsole.ui" line="-357"/>
+ <location filename="../forms/debugwindow.ui" line="-357"/>
<source>Build date</source>
<translation>Build date</translation>
</message>
@@ -2013,7 +2093,45 @@
<translation>Clear console</translation>
</message>
<message>
- <location filename="../rpcconsole.cpp" line="-36"/>
+ <location filename="../rpcconsole.cpp" line="-150"/>
+ <source>&amp;Disconnect Node</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <location line="+1"/>
+ <location line="+1"/>
+ <location line="+1"/>
+ <source>Ban Node for</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-3"/>
+ <source>1 &amp;hour</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>1 &amp;day</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>1 &amp;week</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>1 &amp;year</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+46"/>
+ <source>&amp;Unban Node</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+64"/>
<source>Welcome to the Bitcoin Core RPC console.</source>
<translation type="unfinished"></translation>
</message>
@@ -2048,7 +2166,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+95"/>
+ <location line="+88"/>
+ <source>(node id: %1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
<source>via %1</source>
<translation type="unfinished"></translation>
</message>
@@ -2059,7 +2182,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+8"/>
+ <location line="+9"/>
<source>Inbound</source>
<translation type="unfinished"></translation>
</message>
@@ -2069,14 +2192,19 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+13"/>
- <source>Unknown</source>
+ <location line="+2"/>
+ <source>Yes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
- <location line="+1"/>
- <source>Fetching...</source>
+ <location line="+0"/>
+ <source>No</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <location line="+6"/>
+ <source>Unknown</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2171,7 +2299,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../receivecoinsdialog.cpp" line="+45"/>
+ <location filename="../receivecoinsdialog.cpp" line="+46"/>
<source>Copy label</source>
<translation type="unfinished">Copy label</translation>
</message>
@@ -2296,7 +2424,7 @@
<name>SendCoinsDialog</name>
<message>
<location filename="../forms/sendcoinsdialog.ui" line="+14"/>
- <location filename="../sendcoinsdialog.cpp" line="+543"/>
+ <location filename="../sendcoinsdialog.cpp" line="+545"/>
<source>Send Coins</source>
<translation>Send Coins</translation>
</message>
@@ -2541,12 +2669,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+244"/>
- <source>Total Amount %1 (= %2)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+2"/>
+ <location line="+246"/>
<source>or</source>
<translation type="unfinished"></translation>
</message>
@@ -2599,7 +2722,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-114"/>
+ <location line="-309"/>
+ <source>Total Amount %1&lt;span style=&apos;font-size:10pt;font-weight:normal;&apos;&gt;&lt;br /&gt;(=%2)&lt;/span&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+195"/>
<source>The recipient address is not valid. Please recheck.</source>
<translation type="unfinished"></translation>
</message>
@@ -2614,7 +2742,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+20"/>
+ <location line="+19"/>
<source>(no label)</source>
<translation type="unfinished">(no label)</translation>
</message>
@@ -2624,7 +2752,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-692"/>
+ <location line="-691"/>
<source>Copy dust</source>
<translation type="unfinished"></translation>
</message>
@@ -2872,7 +3000,7 @@
<translation>Reset all verify message fields</translation>
</message>
<message>
- <location filename="../signverifymessagedialog.cpp" line="+40"/>
+ <location filename="../signverifymessagedialog.cpp" line="+41"/>
<source>Click &quot;Sign Message&quot; to generate signature</source>
<translation>Click &quot;Sign Message&quot; to generate signature</translation>
</message>
@@ -2956,7 +3084,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../networkstyle.cpp" line="+20"/>
+ <location filename="../networkstyle.cpp" line="+19"/>
<source>[testnet]</source>
<translation>[testnet]</translation>
</message>
@@ -2972,7 +3100,7 @@
<context>
<name>TransactionDesc</name>
<message>
- <location filename="../transactiondesc.cpp" line="+34"/>
+ <location filename="../transactiondesc.cpp" line="+32"/>
<source>Open until %1</source>
<translation>Open until %1</translation>
</message>
@@ -3196,7 +3324,7 @@
<context>
<name>TransactionTableModel</name>
<message>
- <location filename="../transactiontablemodel.cpp" line="+230"/>
+ <location filename="../transactiontablemodel.cpp" line="+233"/>
<source>Date</source>
<translation>Date</translation>
</message>
@@ -3332,7 +3460,7 @@
<context>
<name>TransactionView</name>
<message>
- <location filename="../transactionview.cpp" line="+68"/>
+ <location filename="../transactionview.cpp" line="+69"/>
<location line="+16"/>
<source>All</source>
<translation>All</translation>
@@ -3519,7 +3647,7 @@
<context>
<name>WalletFrame</name>
<message>
- <location filename="../walletframe.cpp" line="+26"/>
+ <location filename="../walletframe.cpp" line="+27"/>
<source>No wallet has been loaded.</source>
<translation type="unfinished"></translation>
</message>
@@ -3535,7 +3663,7 @@
<context>
<name>WalletView</name>
<message>
- <location filename="../walletview.cpp" line="+45"/>
+ <location filename="../walletview.cpp" line="+46"/>
<source>&amp;Export</source>
<translation>&amp;Export</translation>
</message>
@@ -3545,7 +3673,7 @@
<translation>Export the data in the current tab to a file</translation>
</message>
<message>
- <location line="+189"/>
+ <location line="+194"/>
<source>Backup Wallet</source>
<translation>Backup Wallet</translation>
</message>
@@ -3578,57 +3706,112 @@
<context>
<name>bitcoin-core</name>
<message>
- <location filename="../bitcoinstrings.cpp" line="+268"/>
+ <location filename="../bitcoinstrings.cpp" line="+249"/>
<source>Options:</source>
<translation>Options:</translation>
</message>
<message>
- <location line="+35"/>
+ <location line="+30"/>
<source>Specify data directory</source>
<translation>Specify data directory</translation>
</message>
<message>
- <location line="-94"/>
+ <location line="-87"/>
<source>Connect to a node to retrieve peer addresses, and disconnect</source>
<translation>Connect to a node to retrieve peer addresses, and disconnect</translation>
</message>
<message>
- <location line="+97"/>
+ <location line="+90"/>
<source>Specify your own public address</source>
<translation>Specify your own public address</translation>
</message>
<message>
- <location line="-117"/>
+ <location line="-107"/>
<source>Accept command line and JSON-RPC commands</source>
<translation>Accept command line and JSON-RPC commands</translation>
</message>
<message>
- <location line="+95"/>
+ <location line="-117"/>
+ <source>Fees (in %s/kB) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>If &lt;category&gt; is not supplied or if &lt;category&gt; = 1, output all debugging information.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Please check that your computer&apos;s date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Prune configured below the minimum of %d MiB. Please use a higher number.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+109"/>
+ <source>Error: A fatal internal error occurred, see debug.log for details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Fee (in %s/kB) to add to transactions you send (default: %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+37"/>
+ <source>Pruning blockstore...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
<source>Run in the background as a daemon and accept commands</source>
<translation>Run in the background as a daemon and accept commands</translation>
</message>
<message>
- <location line="+42"/>
+ <location line="+32"/>
+ <source>Unable to start HTTP server. See debug log for details.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
<source>Use the test network</source>
<translation>Use the test network</translation>
</message>
<message>
- <location line="-136"/>
+ <location line="-123"/>
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
<translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation>
</message>
<message>
- <location line="-168"/>
+ <location line="-157"/>
<source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
<translation>Bind to given address and always listen on it. Use [host]:port notation for IPv6</translation>
</message>
<message>
- <location line="+13"/>
- <source>Continuously rate-limit free transactions to &lt;n&gt;*1000 bytes per minute (default: %u)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+6"/>
+ <location line="+16"/>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation type="unfinished"></translation>
</message>
@@ -3638,52 +3821,52 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<location line="+11"/>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</translation>
</message>
<message>
- <location line="+20"/>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
+ <location line="+57"/>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+14"/>
- <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <location line="+6"/>
+ <source>The block database contains a block which appears to be from the future. This may be due to your computer&apos;s date and time being set incorrectly. Only rebuild the block database if you are sure that your computer&apos;s date and time are correct</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+15"/>
- <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, &gt;%u = target size in MiB to use for block files)</source>
+ <location line="+7"/>
+ <source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
+ <translation>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+10"/>
- <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <location line="+3"/>
+ <source>Use UPnP to map the listening port (default: 1 when listening and no -proxy)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+8"/>
- <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>
+ <location line="+5"/>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location line="+20"/>
- <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <location line="+3"/>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+9"/>
+ <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="+6"/>
+ <location line="+3"/>
<source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
<translation>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</translation>
</message>
@@ -3718,7 +3901,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+10"/>
+ <location line="+8"/>
<source>Attempt to recover private keys from a corrupt wallet.dat</source>
<translation>Attempt to recover private keys from a corrupt wallet.dat</translation>
</message>
@@ -3728,7 +3911,7 @@
<translation>Block creation options:</translation>
</message>
<message>
- <location line="+8"/>
+ <location line="+7"/>
<source>Connect only to the specified node(s)</source>
<translation>Connect only to the specified node(s)</translation>
</message>
@@ -3743,12 +3926,12 @@
<translation>Corrupted block database detected</translation>
</message>
<message>
- <location line="+2"/>
+ <location line="+1"/>
<source>Debugging/Testing options:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
+ <location line="+1"/>
<source>Do not load the wallet and disable wallet RPC calls</source>
<translation type="unfinished"></translation>
</message>
@@ -3759,6 +3942,26 @@
</message>
<message>
<location line="+2"/>
+ <source>Enable publish hash block in &lt;address&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Enable publish hash transaction in &lt;address&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Enable publish raw block in &lt;address&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Enable publish raw transaction in &lt;address&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Error initializing block database</source>
<translation>Error initializing block database</translation>
</message>
@@ -3778,12 +3981,7 @@
<translation>Error opening block database</translation>
</message>
<message>
- <location line="+3"/>
- <source>Error: A fatal internal error occured, see debug.log for details</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
+ <location line="+4"/>
<source>Error: Disk space is low!</source>
<translation>Error: Disk space is low!</translation>
</message>
@@ -3793,12 +3991,7 @@
<translation>Failed to listen on any port. Use -listen=0 if you want this.</translation>
</message>
<message>
- <location line="+5"/>
- <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
+ <location line="+4"/>
<source>Importing...</source>
<translation type="unfinished"></translation>
</message>
@@ -3813,12 +4006,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+21"/>
+ <location line="+20"/>
<source>Not enough file descriptors available.</source>
<translation>Not enough file descriptors available.</translation>
</message>
<message>
- <location line="+2"/>
+ <location line="+1"/>
<source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
<translation type="unfinished"></translation>
</message>
@@ -3833,7 +4026,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+18"/>
+ <location line="+14"/>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation type="unfinished"></translation>
</message>
@@ -3843,22 +4036,17 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+12"/>
+ <location line="+11"/>
<source>Specify wallet file (within data directory)</source>
<translation>Specify wallet file (within data directory)</translation>
</message>
<message>
- <location line="+8"/>
- <source>This is intended for regression testing tools and app development.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+11"/>
+ <location line="+17"/>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+3"/>
<source>Verifying blocks...</source>
<translation>Verifying blocks...</translation>
</message>
@@ -3888,22 +4076,17 @@
<translation>You need to rebuild the database using -reindex to change -txindex</translation>
</message>
<message>
- <location line="-99"/>
+ <location line="-89"/>
<source>Imports blocks from external blk000??.dat file</source>
<translation>Imports blocks from external blk000??.dat file</translation>
</message>
<message>
- <location line="-223"/>
+ <location line="-206"/>
<source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
- <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+6"/>
+ <location line="+7"/>
<source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
<translation type="unfinished"></translation>
</message>
@@ -3918,7 +4101,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+3"/>
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
<translation type="unfinished"></translation>
</message>
@@ -3928,7 +4111,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+9"/>
+ <location line="+6"/>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation type="unfinished"></translation>
</message>
@@ -3943,37 +4126,22 @@
<translation>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</translation>
</message>
<message>
- <location line="+9"/>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+8"/>
+ <location line="+17"/>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
+ <location line="+3"/>
<source>Invalid amount for -maxtxfee=&lt;amount&gt;: &apos;%s&apos; (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+8"/>
+ <location line="+6"/>
<source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+10"/>
- <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+2"/>
+ <location line="+18"/>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation type="unfinished"></translation>
</message>
@@ -3983,12 +4151,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+9"/>
- <source>Require high priority for relaying free or low-fee transactions (default: %u)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+2"/>
+ <location line="+11"/>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation type="unfinished"></translation>
</message>
@@ -3998,7 +4161,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+8"/>
<source>The transaction amount is too small to send after the fee has been deducted</source>
<translation type="unfinished"></translation>
</message>
@@ -4008,32 +4171,12 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
- <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file:
-%s
-It is recommended you use the following random password:
-rpcuser=bitcoinrpc
-rpcpassword=%s
-(you do not need to remember this password)
-The username and password MUST NOT be the same.
-If the file does not exist, create it with owner-readable-only file permissions.
-It is also recommended to set alertnotify so you are notified of problems;
-for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.com
-</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+19"/>
+ <location line="+18"/>
<source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+6"/>
- <source>Warning: Please check that your computer&apos;s date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+19"/>
+ <location line="+22"/>
<source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
<translation type="unfinished"></translation>
</message>
@@ -4053,22 +4196,12 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
+ <location line="+1"/>
<source>Activating best chain...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
- <source>Allow self signed root certificates (default: 0)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+4"/>
- <source>Can&apos;t run with a wallet in prune mode.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+4"/>
+ <location line="+9"/>
<source>Cannot resolve -whitebind address: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
@@ -4088,12 +4221,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
- <source>Could not parse -rpcbind value %s as network address</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+11"/>
+ <location line="+15"/>
<source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
<translation type="unfinished"></translation>
</message>
@@ -4108,11 +4236,6 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
- <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<location line="+9"/>
<source>Information</source>
<translation>Information</translation>
@@ -4153,7 +4276,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+11"/>
+ <location line="+10"/>
<source>Need to specify a port with -whitebind: &apos;%s&apos;</source>
<translation type="unfinished"></translation>
</message>
@@ -4164,36 +4287,26 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
</message>
<message>
<location line="+9"/>
- <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
<source>RPC server options:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>RPC support for HTTP persistent connections (default: %d)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
+ <source>Receive and display P2P network alerts (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <source>Reducing -maxconnections from %d to %d, because of system limitations.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+6"/>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Send trace/debug info to console instead of debug.log file</translation>
</message>
@@ -4203,7 +4316,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+1"/>
<source>Set SSL root certificates for payment request (default: -system-)</source>
<translation type="unfinished"></translation>
</message>
@@ -4213,7 +4326,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished">Set language, for example &quot;de_DE&quot; (default: system locale)</translation>
</message>
<message>
- <location line="+5"/>
+ <location line="+4"/>
<source>Show all debugging options (usage: --help -help-debug)</source>
<translation type="unfinished"></translation>
</message>
@@ -4238,7 +4351,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished">Start minimized</translation>
</message>
<message>
- <location line="+2"/>
+ <location line="+1"/>
<source>The transaction amount is too small to pay the fee</source>
<translation type="unfinished"></translation>
</message>
@@ -4248,7 +4361,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
+ <location line="+2"/>
<source>Transaction amount too small</source>
<translation>Transaction amount too small</translation>
</message>
@@ -4278,12 +4391,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+5"/>
- <source>Use UPnP to map the listening port (default: 1 when listening)</source>
- <translation>Use UPnP to map the listening port (default: 1 when listening)</translation>
- </message>
- <message>
- <location line="+2"/>
+ <location line="+6"/>
<source>Username for JSON-RPC connections</source>
<translation>Username for JSON-RPC connections</translation>
</message>
@@ -4314,6 +4422,11 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
</message>
<message>
<location line="+1"/>
+ <source>ZeroMQ notification options:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>on startup</source>
<translation type="unfinished"></translation>
</message>
@@ -4323,72 +4436,57 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>wallet.dat corrupt, salvage failed</translation>
</message>
<message>
- <location line="-71"/>
+ <location line="-64"/>
<source>Password for JSON-RPC connections</source>
<translation>Password for JSON-RPC connections</translation>
</message>
<message>
- <location line="-205"/>
+ <location line="-195"/>
<source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
<translation>Execute command when the best block changes (%s in cmd is replaced by block hash)</translation>
</message>
<message>
- <location line="+258"/>
+ <location line="+242"/>
<source>Upgrade wallet to latest format</source>
<translation>Upgrade wallet to latest format</translation>
</message>
<message>
- <location line="-41"/>
+ <location line="-36"/>
<source>Rescan the block chain for missing wallet transactions</source>
<translation>Rescan the block chain for missing wallet transactions</translation>
</message>
<message>
- <location line="+42"/>
- <source>Use OpenSSL (https) for JSON-RPC connections</source>
- <translation>Use OpenSSL (https) for JSON-RPC connections</translation>
- </message>
- <message>
- <location line="-12"/>
+ <location line="+25"/>
<source>This help message</source>
<translation>This help message</translation>
</message>
<message>
- <location line="-116"/>
+ <location line="-106"/>
<source>Allow DNS lookups for -addnode, -seednode and -connect</source>
<translation>Allow DNS lookups for -addnode, -seednode and -connect</translation>
</message>
<message>
- <location line="+61"/>
+ <location line="+58"/>
<source>Loading addresses...</source>
<translation>Loading addresses...</translation>
</message>
<message>
- <location line="-33"/>
+ <location line="-30"/>
<source>Error loading wallet.dat: Wallet corrupted</source>
<translation>Error loading wallet.dat: Wallet corrupted</translation>
</message>
<message>
- <location line="-211"/>
+ <location line="-196"/>
<source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+61"/>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
+ <location line="+49"/>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+11"/>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+2"/>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4408,37 +4506,22 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+34"/>
+ <location line="+37"/>
<source>(default: %s)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+7"/>
- <source>Acceptable ciphers (default: %s)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+5"/>
+ <location line="+10"/>
<source>Always query for peer addresses via DNS lookup (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+18"/>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+7"/>
+ <location line="+26"/>
<source>Error loading wallet.dat</source>
<translation>Error loading wallet.dat</translation>
</message>
<message>
<location line="+11"/>
- <source>Force safe mode (default: %u)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
<source>Generate coins (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4448,7 +4531,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+3"/>
<source>Include IP addresses in debug output (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4459,11 +4542,6 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
</message>
<message>
<location line="+8"/>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4493,17 +4571,12 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+4"/>
+ <location line="+7"/>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+9"/>
+ <location line="+8"/>
<source>Relay and mine data carrier transactions (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4513,22 +4586,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+4"/>
- <source>Server certificate file (default: %s)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Server private key (default: %s)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
+ <location line="+8"/>
<source>Set key pool size to &lt;n&gt; (default: %u)</source>
<translation type="unfinished"></translation>
</message>
@@ -4543,11 +4601,6 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<location line="+5"/>
<source>Specify configuration file (default: %s)</source>
<translation type="unfinished"></translation>
@@ -4568,22 +4621,17 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+2"/>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<location line="+5"/>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+8"/>
<source>Unknown network specified in -onlynet: &apos;%s&apos;</source>
<translation>Unknown network specified in -onlynet: &apos;%s&apos;</translation>
</message>
<message>
- <location line="-119"/>
+ <location line="-111"/>
<source>Cannot resolve -bind address: &apos;%s&apos;</source>
<translation>Cannot resolve -bind address: &apos;%s&apos;</translation>
</message>
@@ -4603,22 +4651,22 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Insufficient funds</translation>
</message>
<message>
- <location line="+14"/>
+ <location line="+13"/>
<source>Loading block index...</source>
<translation>Loading block index...</translation>
</message>
<message>
- <location line="-63"/>
+ <location line="-60"/>
<source>Add a node to connect to and attempt to keep the connection open</source>
<translation>Add a node to connect to and attempt to keep the connection open</translation>
</message>
<message>
- <location line="+64"/>
+ <location line="+61"/>
<source>Loading wallet...</source>
<translation>Loading wallet...</translation>
</message>
<message>
- <location line="-57"/>
+ <location line="-56"/>
<source>Cannot downgrade wallet</source>
<translation>Cannot downgrade wallet</translation>
</message>
@@ -4628,17 +4676,17 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Cannot write default address</translation>
</message>
<message>
- <location line="+77"/>
+ <location line="+74"/>
<source>Rescanning...</source>
<translation>Rescanning...</translation>
</message>
<message>
- <location line="-64"/>
+ <location line="-63"/>
<source>Done loading</source>
<translation>Done loading</translation>
</message>
<message>
- <location line="+9"/>
+ <location line="+13"/>
<source>Error</source>
<translation>Error</translation>
</message>
diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts
index 007acbc495..17ce494f91 100644
--- a/src/qt/locale/bitcoin_eo.ts
+++ b/src/qt/locale/bitcoin_eo.ts
@@ -1,7 +1,11 @@
-<TS language="eo" version="2.1">
+<TS language="eo" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
+ <source>Right-click to edit address or label</source>
+ <translation>Dekstre-klaku por redakti adreson aŭ etikedon</translation>
+ </message>
+ <message>
<source>Create a new address</source>
<translation>Krei novan adreson</translation>
</message>
@@ -89,7 +93,11 @@
<source>Exporting Failed</source>
<translation>ekspotado malsukcesinta</translation>
</message>
- </context>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Okazis eraron dum konservo de adreslisto al %1. Bonvolu provi denove.</translation>
+ </message>
+</context>
<context>
<name>AddressTableModel</name>
<message>
@@ -327,6 +335,10 @@
<translation>&amp;Ricevi</translation>
</message>
<message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Vidigi informon pri Bitmona Kerno</translation>
+ </message>
+ <message>
<source>&amp;Show / Hide</source>
<translation>&amp;Montri / Kaŝi</translation>
</message>
@@ -477,6 +489,10 @@
<translation>Krompago:</translation>
</message>
<message>
+ <source>Dust:</source>
+ <translation>Polvo:</translation>
+ </message>
+ <message>
<source>After Fee:</source>
<translation>Post krompago:</translation>
</message>
@@ -501,6 +517,14 @@
<translation>Sumo</translation>
</message>
<message>
+ <source>Received with label</source>
+ <translation>Ricevita kun etikedo</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Ricevita kun adreso</translation>
+ </message>
+ <message>
<source>Date</source>
<translation>Dato</translation>
</message>
@@ -561,6 +585,10 @@
<translation>Kopii prioritaton</translation>
</message>
<message>
+ <source>Copy dust</source>
+ <translation>Kopii polvon</translation>
+ </message>
+ <message>
<source>Copy change</source>
<translation>Kopii restmonon</translation>
</message>
@@ -835,6 +863,10 @@
<translation>&amp;Reto</translation>
</message>
<message>
+ <source>Expert</source>
+ <translation>Fakulo</translation>
+ </message>
+ <message>
<source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
<translation>Aŭtomate malfermi la kursilan pordon por Bitmono. Tio funkcias nur se via kursilo havas la UPnP-funkcion, kaj se tiu ĉi estas ŝaltita.</translation>
</message>
@@ -1089,6 +1121,10 @@
<translation>Aktuala nombro de blokoj</translation>
</message>
<message>
+ <source>Bytes Sent</source>
+ <translation>Bajtoj Senditaj:</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Horo de la lasta bloko</translation>
</message>
@@ -1353,6 +1389,10 @@
<translation>Malplenigi ĉiujn kampojn de la formularo.</translation>
</message>
<message>
+ <source>Dust:</source>
+ <translation>Polvo:</translation>
+ </message>
+ <message>
<source>Clear &amp;All</source>
<translation>&amp;Forigi Ĉion</translation>
</message>
@@ -1437,6 +1477,10 @@
<translation>(neniu etikedo)</translation>
</message>
<message>
+ <source>Copy dust</source>
+ <translation>Kopii polvon</translation>
+ </message>
+ <message>
<source>Are you sure you want to send?</source>
<translation>Ĉu vi certas, ke vi volas sendi?</translation>
</message>
diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts
index 17ec4dca5d..de55496c09 100644
--- a/src/qt/locale/bitcoin_es.ts
+++ b/src/qt/locale/bitcoin_es.ts
@@ -1,9 +1,9 @@
-<TS language="es" version="2.1">
+<TS language="es" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Right-click to edit address or label</source>
- <translation>Haz-clic para editar la dirección o etiqueta</translation>
+ <translation>Haz clic derecho para editar la dirección o etiqueta</translation>
</message>
<message>
<source>Create a new address</source>
@@ -47,11 +47,11 @@
</message>
<message>
<source>Choose the address to send coins to</source>
- <translation>Elije la dirección para enviar monedas a</translation>
+ <translation>Elija la dirección para enviar monedas a</translation>
</message>
<message>
<source>Choose the address to receive coins with</source>
- <translation>Elije la dirección para recibir monedas con</translation>
+ <translation>Elija la dirección para recibir monedas con</translation>
</message>
<message>
<source>C&amp;hoose</source>
@@ -75,7 +75,7 @@
</message>
<message>
<source>Copy &amp;Label</source>
- <translation>Copiar &amp;etiqueta</translation>
+ <translation>Copiar &amp;Etiqueta</translation>
</message>
<message>
<source>&amp;Edit</source>
@@ -395,6 +395,10 @@
<translation>&amp;Acerca de Bitcoin Core</translation>
</message>
<message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modificar las opciones de configuración de Bitcoin</translation>
+ </message>
+ <message>
<source>Show the list of used sending addresses and labels</source>
<translation>Mostrar la lista de direcciones de envío y etiquetas</translation>
</message>
@@ -423,6 +427,10 @@
<translation>Ninguna fuente de bloques disponible ...</translation>
</message>
<message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>%n bloque procesado del historial de transacciones.</numerusform><numerusform>%n bloques procesados del historial de transacciones.</numerusform></translation>
+ </message>
+ <message numerus="yes">
<source>%n hour(s)</source>
<translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation>
</message>
@@ -481,6 +489,18 @@
</translation>
</message>
<message>
+ <source>Amount: %1
+</source>
+ <translation>Amount: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tipo: %1
+</translation>
+ </message>
+ <message>
<source>Label: %1
</source>
<translation>Etiqueta: %1
@@ -699,6 +719,10 @@
<translation>Esta etiqueta se mostrará en rojo si la prioridad es menor a "media"</translation>
</message>
<message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Esta etiqueta se vuelve roja si el cambio es menor que %1</translation>
+ </message>
+ <message>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation>Puede variar en +/- %1 satoshi(s) por entrada.</translation>
</message>
@@ -949,6 +973,14 @@
<translation>Dirección IP del proxy (p. ej. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
</message>
<message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimizar en lugar de salir de la aplicación cuando la ventana está cerrada. Cuando se activa esta opción, la aplicación sólo se cerrará después de seleccionar Salir en el menú.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>El idioma de la interfaz de usuario puede establecerse aquí. Este ajuste se aplicará cuando se reinicie Bitcoin.</translation>
+ </message>
+ <message>
<source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
<translation>Identificadores URL de terceros (por ejemplo, un explorador de bloques) que aparecen en la pestaña de transacciones como elementos del menú contextual. El %s en la URL es reemplazado por el valor hash de la transacción. Se pueden separar URL múltiples por una barra vertical |.</translation>
</message>
@@ -1093,6 +1125,10 @@
<translation>Se necesita reiniciar el cliente para activar los cambios.</translation>
</message>
<message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>El cliente se cerrará. ¿Desea continuar?</translation>
+ </message>
+ <message>
<source>This change would require a client restart.</source>
<translation>Este cambio exige el reinicio del cliente.</translation>
</message>
@@ -1403,6 +1439,10 @@
<translation>Número actual de bloques</translation>
</message>
<message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Abre el archivo de registro de depuración de Bitcoin desde el directorio de datos actual. Esto puede tardar unos segundos para ficheros de registro de gran tamaño.</translation>
+ </message>
+ <message>
<source>Received</source>
<translation>Recibido</translation>
</message>
@@ -1471,6 +1511,10 @@
<translation>Ping</translation>
</message>
<message>
+ <source>Time Offset</source>
+ <translation>Desplazamiento de tiempo</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Hora del último bloque</translation>
</message>
@@ -1962,11 +2006,23 @@
<source>Payment request expired.</source>
<translation>Solicitud de pago caducada.</translation>
</message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Estimado para empezar la confirmación dentro de %n bloque.</numerusform><numerusform>Estimado para empezar la confirmación dentro de %n bloques.</numerusform></translation>
+ </message>
<message>
<source>Pay only the minimum fee of %1</source>
<translation>Paga sólo la cuota mínima de %1</translation>
</message>
<message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>La dirección del destinatario no es válida. Por favor, compruébela de nuevo.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Se ha encontrado una dirección duplicada. Solo se puede enviar a cada dirección una vez por operación de envío.</translation>
+ </message>
+ <message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Alerta: Dirección de Bitcoin inválida</translation>
</message>
@@ -2038,6 +2094,10 @@
<translation>Eliminar esta transacción</translation>
</message>
<message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>La cuota será deducida de la cantidad que sea mandada. El destinatario recibirá menos bitcoins de los que entres en el </translation>
+ </message>
+ <message>
<source>S&amp;ubtract fee from amount</source>
<translation>Restar comisiones a la cantidad</translation>
</message>
@@ -2092,6 +2152,10 @@
<translation>&amp;Firmar mensaje</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>Puede firmar los mensajes con sus direcciones para demostrar que las posee. Tenga cuidado de no firmar cualquier cosa de manera vaga o aleatoria, pues los ataques de phishing pueden tratar de engañarle firmando su identidad a través de ellos. Sólo firme declaraciones totalmente detalladas con las que usted esté de acuerdo.</translation>
+ </message>
+ <message>
<source>The Bitcoin address to sign the message with</source>
<translation>Dirección Bitcoin con la que firmar el mensaje</translation>
</message>
@@ -2144,6 +2208,10 @@
<translation>&amp;Verificar mensaje</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>Introduzca la dirección para la firma, el mensaje (asegurándose de copiar tal cual los saltos de línea, espacios, tabulaciones, etc.) y la firma a continuación para verificar el mensaje. Tenga cuidado de no asumir más información de lo que dice el propio mensaje firmado para evitar fraudes basados en ataques de tipo man-in-the-middle. </translation>
+ </message>
+ <message>
<source>The Bitcoin address the message was signed with</source>
<translation>La dirección Bitcoin con la que se firmó el mensaje</translation>
</message>
@@ -2495,6 +2563,10 @@
<translation>Sea o no una dirección sólo está involucrada en esta transacción.</translation>
</message>
<message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>intento/propósito de la transacción definido por el usuario.</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
<translation>Cantidad retirada o añadida al saldo.</translation>
</message>
@@ -2749,16 +2821,16 @@
<translation>Distribuido bajo la licencia de software MIT, vea la copia del archivo adjunto o &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Ingresar en el modo de prueba de regresión, que utiliza una cadena especial en la que los bloques se pueden resolver instantáneamente.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Ejecutar comando cuando una transacción del monedero cambia (%s en cmd se remplazará por TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>En este modo -genproclimit controla cuántos bloques se generan de inmediato.</translation>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Maximo Comisión totales para usar en una sola transacción billetera; establecer esta demasiado bajo puede abortar transacciones grandes (por defecto: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%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, &gt;%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, &lt;0 = leave that many cores free, default: %d)</source>
@@ -2773,6 +2845,14 @@
<translation>No se ha podido acceder a %s en esta máquina. Probablemente ya se está ejecutando Bitcoin Core.</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ADVERTENCIA: anormalmente alto número de bloques generado, %d bloques recibidos en las últimas horas %d (%d espera)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ADVERTENCIA: comprueba tu conexión de red, %d bloques recibidos en las últimas %d horas (%d esperados)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Aviso: ¡-paytxfee tiene un valor muy alto! Esta es la comisión que pagará si envía una transacción.</translation>
</message>
@@ -2889,6 +2969,14 @@
<translation>Sólo conectar a nodos en redes &lt;net&gt; (ipv4, ipv6 o onion)</translation>
</message>
<message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Pode no se puede configurar con un valor negativo.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>El modo recorte es incompatible con -txindex.</translation>
+ </message>
+ <message>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation>Asignar tamaño de cache en megabytes (entre %d y %d; predeterminado: %d)</translation>
</message>
@@ -2901,10 +2989,6 @@
<translation>Especificar archivo de monedero (dentro del directorio de datos)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Esto afecta a las herramientas de prueba de regresión y al desarrollo informático de la aplicación.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Usar UPnP para asignar el puerto de escucha (predeterminado:: %u)</translation>
</message>
@@ -2961,6 +3045,10 @@
<translation>Crear nuevos archivos con permisos por defecto del sistema, en lugar de umask 077 (sólo efectivo con la funcionalidad de monedero desactivada)</translation>
</message>
<message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Descubra direcciones IP propias (por defecto: 1 cuando se escucha y nadie -externalip o -proxy)</translation>
+ </message>
+ <message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Error: la escucha para conexiones entrantes falló (la escucha regresó el error %s)</translation>
</message>
@@ -2977,10 +3065,6 @@
<translation>Tarifas (en BTC/Kb) más pequeños que esto se consideran cero cuota de reinstalación (por defecto: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Tarifas (en BTC/Kb) más pequeños que esto se consideran cero cuota para la creación de la transacción (por defecto: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Si el pago de comisión no está establecido, incluir la cuota suficiente para que las transacciones comiencen la confirmación en una media de n bloques ( por defecto :%u)</translation>
</message>
@@ -2989,10 +3073,18 @@
<translation>El tamaño máximo de los datos en las operaciones de transporte de datos que transmitimos y el mio (default: %u)</translation>
</message>
<message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Pode configurado por debajo del mínimo de %d MB. Por favor, use un número más alto.</translation>
+ </message>
+ <message>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation>Consulta de direcciones pares mediante búsqueda de DNS, si bajo en direcciones (por defecto: 1 a menos que - conectar)</translation>
</message>
<message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Aleatorizar las credenciales para cada conexión proxy. Esto habilita la Tor stream isolation (por defecto: %u)</translation>
+ </message>
+ <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Establecer tamaño máximo de las transacciones de alta prioridad/baja comisión en bytes (predeterminado: %d)</translation>
</message>
@@ -3001,6 +3093,10 @@
<translation>Ajuste el número de hilos para la generación de moneda si está habilitado (-1 = all cores, default: %d)</translation>
</message>
<message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Monto de transacción muy pequeña luego de la deducción por comisión</translation>
+ </message>
+ <message>
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
<translation>Este producto incluye software desarrollado por el OpenSSL Project para su uso en OpenSSL Toolkit &lt;https://www.openssl.org/&gt;, software de cifrado escrito por Eric Young y software UPnP escrito por Thomas Bernard.</translation>
</message>
@@ -3041,10 +3137,26 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
<translation>A los equipos en lista blanca no se les pueden prohibir los ataques DoS y sus transacciones siempre son retransmitidas, incluso si ya están en el mempool, es útil por ejemplo para un gateway.</translation>
</message>
<message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Necesitas reconstruir la base de datos utilizando -reindex para volver al modo sin recorte. Esto volverá a descargar toda la cadena de bloques</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(por defecto: %u)</translation>
+ </message>
+ <message>
<source>Accept public REST requests (default: %u)</source>
<translation>Aceptar solicitudes públicas en FERIADOS (por defecto: %u)</translation>
</message>
<message>
+ <source>Activating best chain...</source>
+ <translation>Activando la mejor cadena...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>No se puede ejecutar con un monedero en modo recorte.</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>No se puede resolver -whitebind address: '%s'</translation>
</message>
@@ -3133,12 +3245,12 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
<translation>Soporte RPC para conexiones HTTP persistentes (por defecto: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Ignorar 1 de cada &lt;n&gt; mensajes de red al azar</translation>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Reconstruir el índice de la cadena de bloques en el arranque desde los actuales ficheros blk000??.dat</translation>
</message>
<message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Introducir datos fuzz en 1 de cada &lt;n&gt; mensajes de red al azar</translation>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Recibir y mostrar alertas de red P2P (default: %u)</translation>
</message>
<message>
<source>Send trace/debug info to console instead of debug.log file</source>
@@ -3177,6 +3289,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
<translation>Arrancar minimizado</translation>
</message>
<message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Cantidad de la transacción demasiado pequeña para pagar la comisión</translation>
+ </message>
+ <message>
<source>This is experimental software.</source>
<translation>Este software es experimental.</translation>
</message>
@@ -3197,6 +3313,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
<translation>Transacción demasiado grande</translation>
</message>
<message>
+ <source>UI Options:</source>
+ <translation>Opciones de interfaz de usuario</translation>
+ </message>
+ <message>
<source>Unable to bind to %s on this computer (bind returned error %s)</source>
<translation>No es posible conectar con %s en este sistema (bind ha dado el error %s)</translation>
</message>
@@ -3281,18 +3401,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
<translation>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Volcar la actividad de la base de datos de memoria al registro en disco cada &lt;n&gt; megabytes (predeterminado: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Nivel de rigor en la verificación de bloques de -checkblocks (0-4; predeterminado: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Registrar prioridad de las transacciones y cuota por kB cuando se minen bloques (por defecto: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Mantener el índice completo de transacciones, usado por la llamada rpc de getrawtransaction (por defecto: %u)</translation>
</message>
@@ -3321,18 +3433,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
<translation>Siempre consultar direcciones de otros equipos por medio de DNS lookup (por defecto: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Inhabilitar el modo seguro, no considerar un suceso real de modo seguro (predeterminado: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>Error al cargar wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Forzar modo seguro (por defecto: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Generar monedas (por defecto: %u)</translation>
</message>
@@ -3349,10 +3453,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
<translation>Dirección -proxy inválida: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Limitar tamaño de la cache de firmas a &lt;n&gt; entradas (predeterminado: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Escuchar conexiones JSON-RPC en &lt;puerto&gt; (predeterminado: %u o testnet: %u)</translation>
</message>
@@ -3365,6 +3465,10 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
<translation>Mantener como máximo &lt;n&gt; conexiones a pares (predeterminado: %u)</translation>
</message>
<message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Realiza las operaciones de difusión del monedero</translation>
+ </message>
+ <message>
<source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
<translation>Búfer de recepción máximo por conexión, &lt;n&gt;*1000 bytes (por defecto: %u)</translation>
</message>
@@ -3373,10 +3477,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
<translation>Búfer de recepción máximo por conexión, , &lt;n&gt;*1000 bytes (por defecto: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Aceptar solamente cadena de bloques que concuerde con los puntos de control internos (predeterminado: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Anteponer marca temporal a la información de depuración (por defecto: %u)</translation>
</message>
@@ -3389,10 +3489,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
<translation>Relay non-P2SH multisig (default: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Ejecutar un hilo para limpiar de la memoria el monedero periódicamente (predeterminado: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>Archivo de certificado del servidor (por defecto: %s)</translation>
</message>
@@ -3413,10 +3509,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
<translation>Establecer el número de procesos para llamadas del servicio RPC (por defecto: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Establece la opción DB_PRIVATE en el entorno de base de datos del monedero (predeterminado: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Especificar archivo de configuración (por defecto: %s)</translation>
</message>
@@ -3433,10 +3525,6 @@ por ejemplo: alertnotify=echo %% s | correo -s "Alerta Bitcoin" admin@foo.com
<translation>Gastar cambio no confirmado al enviar transacciones (predeterminado: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Detener después de importar los bloques del disco (por defecto: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Umbral para la desconexión de pares con mal comportamiento (predeterminado: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts
index f50aa49110..c35acf2c67 100644
--- a/src/qt/locale/bitcoin_es_CL.ts
+++ b/src/qt/locale/bitcoin_es_CL.ts
@@ -1,4 +1,4 @@
-<TS language="es_CL" version="2.1">
+<TS language="es_CL" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -204,7 +204,7 @@
</message>
<message>
<source>Show information about Qt</source>
- <translation>Mostrar Información sobre QT</translation>
+ <translation>Mostrar Información sobre Qt</translation>
</message>
<message>
<source>&amp;Options...</source>
diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts
index d2cdf87a0e..6071702989 100644
--- a/src/qt/locale/bitcoin_es_DO.ts
+++ b/src/qt/locale/bitcoin_es_DO.ts
@@ -1,4 +1,4 @@
-<TS language="es_DO" version="2.1">
+<TS language="es_DO" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -2271,10 +2271,6 @@
<translation>Opciones del sservidor RPC:</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Descartar aleatoriamente 1 de cada &lt;n&gt; mensajes de red</translation>
- </message>
- <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Enviar información de trazas/depuración a la consola en lugar de al archivo debug.log</translation>
</message>
diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts
index 4238330105..258308598e 100644
--- a/src/qt/locale/bitcoin_es_MX.ts
+++ b/src/qt/locale/bitcoin_es_MX.ts
@@ -1,4 +1,4 @@
-<TS language="es_MX" version="2.1">
+<TS language="es_MX" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_es_UY.ts b/src/qt/locale/bitcoin_es_UY.ts
index 48a6f35f92..bb99466619 100644
--- a/src/qt/locale/bitcoin_es_UY.ts
+++ b/src/qt/locale/bitcoin_es_UY.ts
@@ -1,4 +1,4 @@
-<TS language="es_UY" version="2.1">
+<TS language="es_UY" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts
index 29a45960c9..c746107bc7 100644
--- a/src/qt/locale/bitcoin_et.ts
+++ b/src/qt/locale/bitcoin_et.ts
@@ -1,4 +1,4 @@
-<TS language="et" version="2.1">
+<TS language="et" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_eu_ES.ts b/src/qt/locale/bitcoin_eu_ES.ts
index d68411d382..3de9ad5a2f 100644
--- a/src/qt/locale/bitcoin_eu_ES.ts
+++ b/src/qt/locale/bitcoin_eu_ES.ts
@@ -1,4 +1,4 @@
-<TS language="eu_ES" version="2.1">
+<TS language="eu_ES" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts
index 33f43f0c2d..5eeea04684 100644
--- a/src/qt/locale/bitcoin_fa.ts
+++ b/src/qt/locale/bitcoin_fa.ts
@@ -1,4 +1,4 @@
-<TS language="fa" version="2.1">
+<TS language="fa" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -66,6 +66,10 @@
<translation>این‌ها نشانی‌های بیت‌کوین شما برای ارسال وجود هستند. همیشه قبل از ارسال سکه‌ها، نشانی دریافت‌کننده و مقدار ارسالی را بررسی کنید.</translation>
</message>
<message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>این‌ها نشانی‌های بیت‌کوین شما برای دریافت وجوه هستند. توصیه می‌شود یک نشانی دریافت جدید برای هر تبادل استفاده کنید.</translation>
+ </message>
+ <message>
<source>Copy &amp;Label</source>
<translation>کپی و برچسب‌&amp;گذاری</translation>
</message>
@@ -85,7 +89,11 @@
<source>Exporting Failed</source>
<translation>استخراج انجام نشد</translation>
</message>
- </context>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>خطایی هنگام تلاش برای ذخیرهٔ لیست آدرس ها در %1 رخ داد.</translation>
+ </message>
+</context>
<context>
<name>AddressTableModel</name>
<message>
@@ -156,6 +164,10 @@
<translation>آیا مطمئن هستید که می‌خواهید کیف پول خود را رمزنگاری کنید؟</translation>
</message>
<message>
+ <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>هسته بیت‌کوین هم اکنون بسته می‌شود تا فرایند رمزگذاری را تمام کند. به خاطر داشته باشید که رمزگذاری کردن کیف پول‌تان نمی‌تواند به طور کامل بیت‌کوین‌های شما را در برابر دزدیده شدن توسط بدافزارهایی که رایانه‌ی شما را آلوده می‌کنند، محافظت نماید.</translation>
+ </message>
+ <message>
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
<translation>مهم: هر نسخهٔ پشتیبانی که تا کنون از کیف پول خود تهیه کرده‌اید، باید با کیف پول رمزنگاری شدهٔ جدید جایگزین شود. به دلایل امنیتی، پروندهٔ قدیمی کیف پول بدون رمزنگاری، تا زمانی که از کیف پول رمزنگاری‌شدهٔ جدید استفاده نکنید، غیرقابل استفاده خواهد بود.</translation>
</message>
@@ -168,6 +180,14 @@
<translation>کیف پول رمزنگاری شد</translation>
</message>
<message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>رمز جدید کیف پول خود را وارد کنید.&lt;br/&gt;از رمز عبوری استفاده کنید که&lt;b&gt; حداقل 10 کاراکتر تصادفی &lt;/b&gt; و یا &lt;b&gt; حداقل 8 حرف داشته باشد.&lt;/b&gt;</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>
@@ -211,6 +231,10 @@
<translation>&amp;بررسی اجمالی</translation>
</message>
<message>
+ <source>Node</source>
+ <translation>گره</translation>
+ </message>
+ <message>
<source>Show general overview of wallet</source>
<translation>نمایش بررسی اجمالی کیف پول</translation>
</message>
@@ -255,6 +279,18 @@
<translation>&amp;تغییر گذرواژه...</translation>
</message>
<message>
+ <source>&amp;Sending addresses...</source>
+ <translation>&amp;در حال ارسال آدرس ها...</translation>
+ </message>
+ <message>
+ <source>&amp;Receiving addresses...</source>
+ <translation>&amp;در حال دریافت آدرس ها...</translation>
+ </message>
+ <message>
+ <source>Open &amp;URI...</source>
+ <translation>باز کردن &amp;آدرس</translation>
+ </message>
+ <message>
<source>Importing blocks from disk...</source>
<translation>دریافت بلوک‌ها از دیسک...</translation>
</message>
@@ -303,6 +339,10 @@
<translation>&amp;دریافت</translation>
</message>
<message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>نمایش اطلاعات در مورد بیت‌کوین</translation>
+ </message>
+ <message>
<source>&amp;Show / Hide</source>
<translation>&amp;نمایش/ عدم نمایش</translation>
</message>
@@ -346,6 +386,14 @@
<source>&amp;About Bitcoin Core</source>
<translation>درباره هسته ی بیت کوین</translation>
</message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>نمایش لیست آدرس های ارسال و لیبل ها</translation>
+ </message>
+ <message>
+ <source>Show the list of used receiving addresses and labels</source>
+ <translation>نمایش لیست آدرس های دریافت و لیبل ها</translation>
+ </message>
<message numerus="yes">
<source>%n active connection(s) to Bitcoin network</source>
<translation><numerusform>%n ارتباط فعال با شبکهٔ بیت‌کوین</numerusform></translation>
@@ -457,18 +505,42 @@
<translation>پول خورد:</translation>
</message>
<message>
+ <source>Tree mode</source>
+ <translation>مدل درختی</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>مدل لیست</translation>
+ </message>
+ <message>
<source>Amount</source>
<translation>مبلغ</translation>
</message>
<message>
+ <source>Received with label</source>
+ <translation>دریافت شده با برچسب</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>دریافت شده با نشانی</translation>
+ </message>
+ <message>
<source>Date</source>
<translation>تاریخ</translation>
</message>
<message>
+ <source>Confirmations</source>
+ <translation>تاییدیه ها</translation>
+ </message>
+ <message>
<source>Confirmed</source>
<translation>تأیید شده</translation>
</message>
<message>
+ <source>Priority</source>
+ <translation>اولویت</translation>
+ </message>
+ <message>
<source>Copy address</source>
<translation>کپی نشانی</translation>
</message>
@@ -485,6 +557,46 @@
<translation>کپی شناسهٔ تراکنش</translation>
</message>
<message>
+ <source>highest</source>
+ <translation>بیشترین</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>بیشتر</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>زیاد</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>متوسط متمایل به زیاد</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>متوسط</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>متوسط متمایل به کم</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>کم</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>کمتر</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>کمترین</translation>
+ </message>
+ <message>
+ <source>none</source>
+ <translation>هیچکدام</translation>
+ </message>
+ <message>
<source>yes</source>
<translation>بله</translation>
</message>
@@ -496,7 +608,11 @@
<source>(no label)</source>
<translation>(بدون برچسب)</translation>
</message>
- </context>
+ <message>
+ <source>(change)</source>
+ <translation>(تغییر)</translation>
+ </message>
+</context>
<context>
<name>EditAddressDialog</name>
<message>
@@ -578,6 +694,10 @@
<translation>نسخه</translation>
</message>
<message>
+ <source>About Bitcoin Core</source>
+ <translation>درباره هسته ی بیت کوین</translation>
+ </message>
+ <message>
<source>Command-line options</source>
<translation>گزینه‌های خط‌فرمان</translation>
</message>
@@ -597,6 +717,14 @@
<translation>خوش‌آمدید</translation>
</message>
<message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>به هسته بیت کوین خوش آمدید.</translation>
+ </message>
+ <message>
+ <source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
+ <translation>از آنجایی که این اولین اجرای برنامه است، شما می‌توانید مسیر ذخیرهٔ داده‌ها را انتخاب کنید.</translation>
+ </message>
+ <message>
<source>Use the default data directory</source>
<translation>استفاده از مسیر پیش‌فرض</translation>
</message>
@@ -707,6 +835,10 @@
<translation>پیش‌فرض</translation>
</message>
<message>
+ <source>none</source>
+ <translation>هیچکدام</translation>
+ </message>
+ <message>
<source>Confirm options reset</source>
<translation>تأییدِ بازنشانی گزینه‌ها</translation>
</message>
@@ -750,6 +882,10 @@
<translation>تراز استخراج شده از معدن که هنوز بالغ نشده است</translation>
</message>
<message>
+ <source>Balances</source>
+ <translation>تراز ها</translation>
+ </message>
+ <message>
<source>Total:</source>
<translation>جمع کل:</translation>
</message>
@@ -757,6 +893,14 @@
<source>Your current total balance</source>
<translation>تراز کل فعلی شما</translation>
</message>
+ <message>
+ <source>Spendable:</source>
+ <translation>:قابل خرج کردن</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>تراکنش های اخیر</translation>
+ </message>
</context>
<context>
<name>PaymentServer</name>
@@ -765,9 +909,25 @@
<translation>مدیریت URI</translation>
</message>
<message>
+ <source>Payment request rejected</source>
+ <translation>درخواست پرداخت رد شد.</translation>
+ </message>
+ <message>
+ <source>Payment request error</source>
+ <translation>خطای درخواست پرداخت</translation>
+ </message>
+ <message>
<source>Cannot start bitcoin: click-to-pay handler</source>
<translation>نمی‌توان بیت‌کوین را اجرا کرد: کنترل‌کنندهٔ کلیک-و-پرداخت</translation>
</message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>درخواست پرداخت منقضی شد.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>درخواست پرداخت نامعتبر</translation>
+ </message>
</context>
<context>
<name>PeerTableModel</name>
@@ -779,6 +939,10 @@
<translation>مبلغ</translation>
</message>
<message>
+ <source>None</source>
+ <translation>هیچکدام</translation>
+ </message>
+ <message>
<source>N/A</source>
<translation>ناموجود</translation>
</message>
@@ -837,6 +1001,22 @@
<translation>تعداد فعلی بلوک‌ها</translation>
</message>
<message>
+ <source>Received</source>
+ <translation>دریافتی</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>ارسال شده</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>نسخه</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>سرویس ها</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>زمان آخرین بلوک</translation>
</message>
@@ -865,6 +1045,10 @@
<translation>پاکسازی کنسول</translation>
</message>
<message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>به کنسول RPC هسته بیت کوین خوش آمدید.</translation>
+ </message>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
<translation>دکمه‌های بالا و پایین برای پیمایش تاریخچه و &lt;b&gt;Ctrl-L&lt;/b&gt; برای پاک کردن صفحه.</translation>
</message>
@@ -884,6 +1068,14 @@
<translation>&amp;برچسب:</translation>
</message>
<message>
+ <source>Show</source>
+ <translation>نمایش</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>حذف کردن</translation>
+ </message>
+ <message>
<source>Copy label</source>
<translation>کپی برچسب</translation>
</message>
@@ -981,6 +1173,10 @@
<translation>پول خورد:</translation>
</message>
<message>
+ <source>fast</source>
+ <translation>سریع</translation>
+ </message>
+ <message>
<source>Send to multiple recipients at once</source>
<translation>ارسال به چند دریافت‌کنندهٔ به‌طور همزمان</translation>
</message>
@@ -1029,9 +1225,17 @@
<translation>با احتساب هزینهٔ %1 برای هر تراکنش، مجموع میزان پرداختی از مبلغ تراز شما بیشتر می‌شود.</translation>
</message>
<message>
+ <source>Payment request expired.</source>
+ <translation>درخواست پرداخت منقضی شد.</translation>
+ </message>
+ <message>
<source>(no label)</source>
<translation>(بدون برچسب)</translation>
</message>
+ <message>
+ <source>Are you sure you want to send?</source>
+ <translation>آیا مطمئن هستید که می خواهید ارسال کنید؟</translation>
+ </message>
</context>
<context>
<name>SendCoinsEntry</name>
@@ -1052,6 +1256,18 @@
<translation>&amp;برچسب:</translation>
</message>
<message>
+ <source>Choose previously used address</source>
+ <translation>انتخاب نشانی پیش‌تر استفاده شده</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>این یک پرداخت عادی است</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>نشانی بیت‌کوین برای ارسال پرداخت به آن</translation>
+ </message>
+ <message>
<source>Alt+A</source>
<translation>Alt+A</translation>
</message>
@@ -1064,6 +1280,10 @@
<translation>Alt+P</translation>
</message>
<message>
+ <source>Remove this entry</source>
+ <translation>حذف این مدخل</translation>
+ </message>
+ <message>
<source>Message:</source>
<translation>پیام:</translation>
</message>
@@ -1082,6 +1302,14 @@
<translation>ا&amp;مضای پیام</translation>
</message>
<message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>نشانی بیت‌کوین برای امضاء پیغام با آن</translation>
+ </message>
+ <message>
+ <source>Choose previously used address</source>
+ <translation>انتخاب نشانی پیشتر استفاده شده</translation>
+ </message>
+ <message>
<source>Alt+A</source>
<translation>Alt+A</translation>
</message>
@@ -1126,6 +1354,10 @@
<translation>&amp;شناسایی پیام</translation>
</message>
<message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>نشانی بیت‌کوین که پیغام با آن امضاء شده</translation>
+ </message>
+ <message>
<source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
<translation>برای حصول اطمینان از اینکه پیام با نشانی بیت‌کوین مشخص شده امضا است یا خیر، پیام را شناسایی کنید</translation>
</message>
@@ -1197,13 +1429,21 @@
<translation> هسته Bitcoin </translation>
</message>
<message>
+ <source>The Bitcoin Core developers</source>
+ <translation>توسعه‌دهندگان هسته بیت‌کوین</translation>
+ </message>
+ <message>
<source>[testnet]</source>
<translation>آزمایش شبکه</translation>
</message>
</context>
<context>
<name>TrafficGraphWidget</name>
- </context>
+ <message>
+ <source>KB/s</source>
+ <translation>کیلوبایت</translation>
+ </message>
+</context>
<context>
<name>TransactionDesc</name>
<message>
@@ -1504,6 +1744,10 @@
<translation>استخراج انجام نشد</translation>
</message>
<message>
+ <source>Exporting Successful</source>
+ <translation>استخراج موفق</translation>
+ </message>
+ <message>
<source>Comma separated file (*.csv)</source>
<translation>پروندهٔ نوع CSV جداشونده با کاما (*.csv)</translation>
</message>
@@ -1659,10 +1903,22 @@
<translation>خطا در بازگشایی پایگاه داده ی بلوک</translation>
</message>
<message>
+ <source>Error: A fatal internal error occured, see debug.log for details</source>
+ <translation>خطا: یک خطای داخلی مهلک روی داد، debug.log را برای جزئیات ببینید</translation>
+ </message>
+ <message>
+ <source>Error: Disk space is low!</source>
+ <translation>خطا: فضای دیسک کم است!</translation>
+ </message>
+ <message>
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
<translation>شنیدن هر گونه درگاه انجام پذیر نیست. ازlisten=0 برای اینکار استفاده کیند.</translation>
</message>
<message>
+ <source>Importing...</source>
+ <translation>در حال پیاده‌سازی...</translation>
+ </message>
+ <message>
<source>Verifying blocks...</source>
<translation>در حال بازبینی بلوک ها...</translation>
</message>
@@ -1671,6 +1927,10 @@
<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>
@@ -1699,6 +1959,10 @@
<translation>اجرای برنامه به صورت کوچک‌شده</translation>
</message>
<message>
+ <source>UI Options:</source>
+ <translation>گزینه‌های رابط کاربری:</translation>
+ </message>
+ <message>
<source>Use UPnP to map the listening port (default: 1 when listening)</source>
<translation>از UPnP برای شناسایی درگاه شنیداری استفاده کنید (پیش فرض:1 در زمان شنیدن)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_fa_IR.ts b/src/qt/locale/bitcoin_fa_IR.ts
index da95f10474..1174e24b46 100644
--- a/src/qt/locale/bitcoin_fa_IR.ts
+++ b/src/qt/locale/bitcoin_fa_IR.ts
@@ -1,4 +1,4 @@
-<TS language="fa_IR" version="2.1">
+<TS language="fa_IR" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -14,30 +14,78 @@
<translation>کپی کردن حساب انتخاب شده به حافظه سیستم - کلیپ بورد</translation>
</message>
<message>
+ <source>&amp;Copy</source>
+ <translation>کپی</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>بستن</translation>
+ </message>
+ <message>
<source>&amp;Copy Address</source>
- <translation>و کپی آدرس</translation>
+ <translation>کپی آدرس</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>حذف آدرس های انتخاب شده از لیست</translation>
</message>
<message>
<source>Export the data in the current tab to a file</source>
<translation>صدور داده نوار جاری به یک فایل</translation>
</message>
<message>
+ <source>&amp;Export</source>
+ <translation>صدور</translation>
+ </message>
+ <message>
<source>&amp;Delete</source>
- <translation>و حذف</translation>
+ <translation>حذف</translation>
+ </message>
+ <message>
+ <source>Choose the address to send coins to</source>
+ <translation>انتخاب آدرس جهت ارسال کوین ها به آن آدرس</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>انتخاب آدرس جهت دریافت کوین ها از آن آدرس</translation>
+ </message>
+ <message>
+ <source>C&amp;hoose</source>
+ <translation>انتخاب</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>ارسال آدرس ها</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>دریافت آدرس ها</translation>
</message>
<message>
<source>Copy &amp;Label</source>
- <translation>کپی و برچسب</translation>
+ <translation>کپی برچسب</translation>
</message>
<message>
<source>&amp;Edit</source>
- <translation>و ویرایش</translation>
+ <translation>ویرایش</translation>
+ </message>
+ <message>
+ <source>Export Address List</source>
+ <translation>صدور لیست آدرس</translation>
</message>
<message>
<source>Comma separated file (*.csv)</source>
- <translation>Comma separated file (*.csv) فایل جداگانه دستوری</translation>
+ <translation>فایل سی اس وی (*.csv)</translation>
</message>
- </context>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>صدور با شکست مواجه شد</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>خطایی به هنگام ذخیره لیست آدرس در %1 رخ داده است. لطفا دوباره تلاش کنید.</translation>
+ </message>
+</context>
<context>
<name>AddressTableModel</name>
<message>
@@ -56,6 +104,10 @@
<context>
<name>AskPassphraseDialog</name>
<message>
+ <source>Passphrase Dialog</source>
+ <translation>دیالوگ رمزعبور</translation>
+ </message>
+ <message>
<source>Enter passphrase</source>
<translation>رمز/پَس فرِیز را وارد کنید</translation>
</message>
@@ -96,10 +148,18 @@
<translation>رمزگذاری wallet را تایید کنید</translation>
</message>
<message>
+ <source>Warning: The Caps Lock key is on!</source>
+ <translation>اخطار: کلید Caps Lock فعال است!</translation>
+ </message>
+ <message>
<source>Wallet encrypted</source>
<translation>تایید رمزگذاری</translation>
</message>
<message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>رمز قدیمی و جدید کیف پول را وارد کنید.</translation>
+ </message>
+ <message>
<source>Wallet encryption failed</source>
<translation>رمزگذاری تایید نشد</translation>
</message>
@@ -123,7 +183,11 @@
<source>Wallet decryption failed</source>
<translation>کشف رمز wallet انجام نشد</translation>
</message>
- </context>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>رمز عبور کیف پول با موفقیت تغییر کرد.</translation>
+ </message>
+</context>
<context>
<name>BitcoinGUI</name>
<message>
@@ -160,11 +224,11 @@
</message>
<message>
<source>About &amp;Qt</source>
- <translation>درباره و QT</translation>
+ <translation>درباره و Qt</translation>
</message>
<message>
<source>Show information about Qt</source>
- <translation>نمایش اطلاعات درباره QT</translation>
+ <translation>نمایش اطلاعات درباره Qt</translation>
</message>
<message>
<source>&amp;Options...</source>
@@ -580,10 +644,26 @@
<source>Message:</source>
<translation>پیام:</translation>
</message>
- </context>
+ <message>
+ <source>Pay To:</source>
+ <translation>پرداخت به:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>یادداشت:</translation>
+ </message>
+</context>
<context>
<name>ShutdownWindow</name>
- </context>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>هسته بیت کوین در حال خاموش شدن است...</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>تا پیش از بسته شدن این پنجره کامپیوتر خود را خاموش نکنید.</translation>
+ </message>
+</context>
<context>
<name>SignVerifyMessageDialog</name>
<message>
@@ -813,6 +893,14 @@
<translation>برچسب را ویرایش کنید</translation>
</message>
<message>
+ <source>Exporting Failed</source>
+ <translation>صدور با شکست مواجه شد</translation>
+ </message>
+ <message>
+ <source>Exporting Successful</source>
+ <translation>صدور با موفقیت انجام شد</translation>
+ </message>
+ <message>
<source>Comma separated file (*.csv)</source>
<translation>Comma separated file (*.csv) فایل جداگانه دستوری</translation>
</message>
@@ -865,6 +953,10 @@
<context>
<name>WalletView</name>
<message>
+ <source>&amp;Export</source>
+ <translation>صدور</translation>
+ </message>
+ <message>
<source>Export the data in the current tab to a file</source>
<translation>صدور داده نوار جاری به یک فایل</translation>
</message>
@@ -905,10 +997,22 @@
<translation>از تستِ شبکه استفاده نمایید</translation>
</message>
<message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>مبلغ تراکنش کمتر از آن است که پس از کسر هزینه تراکنش قابل ارسال باشد</translation>
+ </message>
+ <message>
+ <source>RPC server options:</source>
+ <translation>گزینه های سرویس دهنده RPC:</translation>
+ </message>
+ <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>ارسال اطلاعات پیگیری/خطایابی به کنسول به جای ارسال به فایل debug.log</translation>
</message>
<message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>ارسال تراکنش ها به صورت بدون کارمزد در صورت امکان (پیش فرض: %u)</translation>
+ </message>
+ <message>
<source>Username for JSON-RPC connections</source>
<translation>شناسه کاربری برای ارتباطاتِ JSON-RPC</translation>
</message>
@@ -949,6 +1053,22 @@
<translation>خطا در هنگام لود شدن wallet.dat</translation>
</message>
<message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>تنظیم کمینه اندازه بلاک بر حسب بایت (پیش فرض: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>تنظیم تعداد ریسمان ها برای سرویس دهی فراخوانی های RPC (پیش فرض: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>فایل تنظیمات را مشخص کنید (پیش فرض: %s)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>فایل pid را مشخص کنید (پیش فرض: %s)</translation>
+ </message>
+ <message>
<source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
<translation>میزان اشتباه است for -paytxfee=&lt;amount&gt;: '%s'</translation>
</message>
diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts
index db59ea1751..eb90aa4281 100644
--- a/src/qt/locale/bitcoin_fi.ts
+++ b/src/qt/locale/bitcoin_fi.ts
@@ -1,9 +1,9 @@
-<TS language="fi" version="2.1">
+<TS language="fi" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Right-click to edit address or label</source>
- <translation>Klikkaa hiiren oikealla painikkeella muokataksesi osoitetta tai nimikettä</translation>
+ <translation>Valitse hiiren oikealla painikkeella muokataksesi osoitetta tai nimikettä</translation>
</message>
<message>
<source>Create a new address</source>
@@ -27,7 +27,7 @@
</message>
<message>
<source>&amp;Copy Address</source>
- <translation>&amp;Kopioi Osoite</translation>
+ <translation>&amp;Kopioi osoite</translation>
</message>
<message>
<source>Delete the currently selected address from the list</source>
@@ -168,6 +168,10 @@
<translation>Haluatko varmasti salata lompakkosi?</translation>
</message>
<message>
+ <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>Bitcoin Core sammuu nyt viimeistelläkseen kryptaamisen. Muista että lompakon kryptaaminen ei voi täysin suojata bitcoinejasi varkaudelta malwaren saastuttamalla tietokoneella.</translation>
+ </message>
+ <message>
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
<translation>TÄRKEÄÄ: Kaikki vanhat lompakon varmuuskopiot pitäisi korvata uusilla suojatuilla varmuuskopioilla. Turvallisuussyistä edelliset varmuuskopiot muuttuvat turhiksi, kun aloitat suojatun lompakon käytön.</translation>
</message>
@@ -184,6 +188,10 @@
<translation>Anna salauslause lompakkoon. &lt;br/&gt;Ole hyvä ja käytä lausetta jossa on &lt;b&gt;kymmenen tai enemmän satunnaista merkkiä&lt;/b&gt; tai &lt;b&gt;kahdeksan tai useampi sanaa&lt;/b&gt;.</translation>
</message>
<message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Syötä vanha ja uusi salasana lompakolle.</translation>
+ </message>
+ <message>
<source>Wallet encryption failed</source>
<translation>Lompakon salaus epäonnistui</translation>
</message>
@@ -256,7 +264,7 @@
</message>
<message>
<source>Show information about Qt</source>
- <translation>Näytä tietoja QT:ta</translation>
+ <translation>Näytä tietoja Qt:ta</translation>
</message>
<message>
<source>&amp;Options...</source>
@@ -391,6 +399,10 @@
<translation>&amp;Tietoja Bitcoin Core</translation>
</message>
<message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Muokkaa kokoonpanoasetuksia Bitcoin Corelle</translation>
+ </message>
+ <message>
<source>Show the list of used sending addresses and labels</source>
<translation>Näytä lähettämiseen käytettyjen osoitteiden ja nimien lista</translation>
</message>
@@ -419,6 +431,10 @@
<translation>Lohkojen lähdettä ei saatavilla...</translation>
</message>
<message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Prosessoitu %n lohko rahansiirtohistoriasta.</numerusform><numerusform>Prosessoitu %n lohkoa rahansiirtohistoriasta.</numerusform></translation>
+ </message>
+ <message numerus="yes">
<source>%n hour(s)</source>
<translation><numerusform>%n tunti</numerusform><numerusform>%n tuntia</numerusform></translation>
</message>
@@ -471,6 +487,36 @@
<translation>Saavutetaan verkkoa...</translation>
</message>
<message>
+ <source>Date: %1
+</source>
+ <translation>Päivämäärä: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Määrä: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tyyppi: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Nimike: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Osoite: %1
+</translation>
+ </message>
+ <message>
<source>Sent transaction</source>
<translation>Lähetetyt rahansiirrot</translation>
</message>
@@ -669,6 +715,18 @@
<translation>ei mitään</translation>
</message>
<message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Tämä nimi muuttuu punaiseksi mikäli rahansiirron koko on suurempi kuin 1000 tavua.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Tämä nimi muuttuu punaiseksi mikäli prioriteetti on pienempi kuin "medium".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Tämä nimike muuttuu punaiseksi mikäli mikä tahansa saaja vastaanottaa pienemmän määrän kuin %1.</translation>
+ </message>
+ <message>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation>Saattaa vaihdella +/- %1 satoshia per syöte.</translation>
</message>
@@ -943,6 +1001,14 @@
<translation>&amp;Verkko</translation>
</message>
<message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Käynnistä Bitcoin Core automaattisesti järjestelmään kirjautumisen jälkeen.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Käynnistä Bitcoin Core järjestelmään kirjautuessa</translation>
+ </message>
+ <message>
<source>(0 = auto, &lt;0 = leave that many cores free)</source>
<translation>(0 = auto, &lt;0 = jätä näin monta ydintä vapaaksi)</translation>
</message>
@@ -1055,6 +1121,10 @@
<translation>Ohjelman uudelleenkäynnistys aktivoi muutokset.</translation>
</message>
<message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Asiakasohjelma sammutetaan. Haluatko jatkaa?</translation>
+ </message>
+ <message>
<source>This change would require a client restart.</source>
<translation>Tämä muutos vaatii ohjelman uudelleenkäynnistyksen.</translation>
</message>
@@ -1185,14 +1255,30 @@
<translation>Maksupyynnön tiedoston käsittely</translation>
</message>
<message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Maksupyynnön tiedostoa ei voida lukea! Tämä voi aiheutua sopimattomasta maksupyyntötiedostosta.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Maksupyyntö on vanhentunut.</translation>
+ </message>
+ <message>
<source>Unverified payment requests to custom payment scripts are unsupported.</source>
<translation>Varmistamattomia maksupyyntöjä kustomoituun maksupalveluun ei tueta.</translation>
</message>
<message>
+ <source>Invalid payment request.</source>
+ <translation>Epäkelpo maksupyyntö.</translation>
+ </message>
+ <message>
<source>Refund from %1</source>
<translation>Maksupalautus %1:sta</translation>
</message>
<message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Maksupyyntö %1 on liian suuri (%2 tavua, sallittu %3 tavua).</translation>
+ </message>
+ <message>
<source>Payment request DoS protection</source>
<translation>Maksupyynnön DoS-suojaus</translation>
</message>
@@ -1201,6 +1287,10 @@
<translation>Virhe kommunikoidessa %1n kanssa: %2</translation>
</message>
<message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Maksupyyntöä ei voida jäsentää!</translation>
+ </message>
+ <message>
<source>Bad response from server %1</source>
<translation>Huono vastaus palvelimelta %1</translation>
</message>
@@ -1220,6 +1310,10 @@
<translation>Käyttöliittymä</translation>
</message>
<message>
+ <source>Node/Service</source>
+ <translation>Noodi/Palvelu</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Vasteaika</translation>
</message>
@@ -1409,6 +1503,10 @@
<translation>Vasteaika</translation>
</message>
<message>
+ <source>Time Offset</source>
+ <translation>Ajan poikkeama</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Viimeisimmän lohkon aika</translation>
</message>
@@ -1453,6 +1551,10 @@
<translation>Tyhjennä konsoli</translation>
</message>
<message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Tervetuloa Bitcoin Coren RPC-konsoliin.</translation>
+ </message>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
<translation>Ylös- ja alas-nuolet selaavat historiaa ja &lt;b&gt;Ctrl-L&lt;/b&gt; tyhjentää ruudun.</translation>
</message>
@@ -1745,6 +1847,10 @@
<translation>per kilotavu</translation>
</message>
<message>
+ <source>Hide</source>
+ <translation>Piilota</translation>
+ </message>
+ <message>
<source>total at least</source>
<translation>yhteensä ainakin</translation>
</message>
@@ -1877,10 +1983,22 @@
<translation>Rahansiirto hylättiin! Tämä saattaa tapahtua jos lompakossa olevat kolikot on jo kulutettu, kuten jos käytät kopioita wallet.dat tiedostosta ja kolikot oli jos käytetty mutta ei merkattu täällä.</translation>
</message>
<message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Rahansiirtokulua %1 ja sitä suurempia määriä pidetään järjenvastaisen korkeana kuluna.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Maksupyyntö on vanhentunut.</translation>
+ </message>
+ <message>
<source>Pay only the minimum fee of %1</source>
<translation>Maksa vain vähimmäiskulu %1</translation>
</message>
<message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Vastaanottajan osoite ei ole kelvollinen. Tarkistathan uudelleen.</translation>
+ </message>
+ <message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Varoitus: Virheellinen Bitcoin osoite</translation>
</message>
@@ -1952,10 +2070,22 @@
<translation>Poista tämä alkio</translation>
</message>
<message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>V&amp;ähennä maksukulu määrästä</translation>
+ </message>
+ <message>
<source>Message:</source>
<translation>Viesti:</translation>
</message>
<message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Tämä on todentamaton maksupyyntö.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Tämä on todennettu maksupyyntö.</translation>
+ </message>
+ <message>
<source>Enter a label for this address to add it to the list of used addresses</source>
<translation>Aseta nimi tälle osoitteelle lisätäksesi sen käytettyjen osoitteiden listalle.</translation>
</message>
@@ -2393,6 +2523,10 @@
<translation>Rahansiirron laatu.</translation>
</message>
<message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Onko rahansiirrossa mukana ainoastaan katseltava osoite vai ei.</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
<translation>Saldoon lisätty tai siitä vähennetty määrä.</translation>
</message>
@@ -2635,18 +2769,10 @@
<translation>Kytkeydy annettuun osoitteeseen ja pidä linja aina auki. Käytä [host]:portin merkintätapaa IPv6:lle.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Aloita regression testimoodi joka käyttää erikoisketjua jossa lohkoja voidaan ratkaista välittömästi.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Suorita käsky kun lompakossa rahansiirto muuttuu (%s cmd on vaihdettu TxID kanssa)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>Tässä moodissa -genproclimit ohjaa kuinka monta lohkoa luodaan välittömästi.</translation>
- </message>
- <message>
<source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
<translation>Aseta script varmistuksen threadien lukumäärä (%u - %d, 0= auto, &lt;0 = jätä näin monta ydintä vapaaksi, oletus: %d)</translation>
</message>
@@ -2735,6 +2861,10 @@
<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>
@@ -2763,6 +2893,14 @@
<translation>Ei tarpeeksi tiedostomerkintöjä vapaana.</translation>
</message>
<message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Yhdistä vain solmukohtiin &lt;net&gt;-verkossa (ipv4, ipv6 tai onion)</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Karsittu tila ei ole yhteensopiva -txindex:n kanssa.</translation>
+ </message>
+ <message>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation>Aseta tietokannan välimuistin koko megatavuissa (%d - %d, oletus: %d</translation>
</message>
@@ -2775,10 +2913,6 @@
<translation>Aseta lompakkotiedosto (data-hakemiston sisällä)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Tämä on tarkoitettu regression testityökaluille ja ohjelman kehittämiseen.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Käytä UPnP:ta kuuntelevan portin kartoittamiseen (oletus: %u)</translation>
</message>
@@ -2799,6 +2933,10 @@
<translation>Lompakon valinnat:</translation>
</message>
<message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Varoitus: Tämä versio on vanhentunut; päivittämistä vaaditaan!</translation>
+ </message>
+ <message>
<source>You need to rebuild the database using -reindex to change -txindex</source>
<translation>Sinun tulee uudelleenrakentaa tietokanta käyttäen -reindex vaihtaen -txindex</translation>
</message>
@@ -2823,6 +2961,26 @@
<translation>Aseta kolikoiden luomiseen tarkoitettujen säikeiden lukumäärä (-1 = kaikki ytimet, oletus: %d)</translation>
</message>
<message>
+ <source>(default: %u)</source>
+ <translation>(oletus: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Hyväksy julkisia REST-pyyntöjä (oletus: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Aktivoidaan parhainta ketjua...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Lompakkoa ei voida ajaa karsitussa tilassa.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>-whitebind -osoitetta '%s' ei voida jäsentää</translation>
+ </message>
+ <message>
<source>Choose data directory on startup (default: 0)</source>
<translation>Valitse data-hakemisto käynnistyksessä (oletus: 0)</translation>
</message>
@@ -2839,6 +2997,10 @@
<translation>Virhe ladattaessa wallet.dat-tiedostoa: Tarvitset uudemman version Bitcoinista</translation>
</message>
<message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Virheitä tietokantaa luettaessa, ohjelma pysäytetään.</translation>
+ </message>
+ <message>
<source>Information</source>
<translation>Tietoa</translation>
</message>
@@ -2863,12 +3025,12 @@
<translation>RPC-palvelimen valinnat:</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Satunnaisesti pudota 1 joka &lt;n&gt; verkkoviestistä</translation>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>RPC-tuki pysyville HTTP-yhteyksille (oletus: %d)</translation>
</message>
<message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Satunnaisesti sekoita 1 joka &lt;n&gt; verkkoviestistä</translation>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Vastaanota ja näytä P2P-verkon hälytyksiä (oletus: %u)</translation>
</message>
<message>
<source>Send trace/debug info to console instead of debug.log file</source>
@@ -2919,6 +3081,10 @@
<translation>Siirtosumma liian iso</translation>
</message>
<message>
+ <source>UI Options:</source>
+ <translation>Ulkoasun asetukset:</translation>
+ </message>
+ <message>
<source>Use UPnP to map the listening port (default: 1 when listening)</source>
<translation>Käytä UPnP:tä kuunneltavan portin avaamiseen (vakioasetus: 1 kun kuuntelemassa)</translation>
</message>
@@ -2983,6 +3149,10 @@
<translation>Virhe ladattaessa wallet.dat-tiedostoa: Lompakko vioittunut</translation>
</message>
<message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Käytä erillistä SOCKS5-proxyä tavoittaaksesi vertaisia Tor-piilopalveluiden kautta (oletus: %s)</translation>
+ </message>
+ <message>
<source>(default: %s)</source>
<translation>(oletus: %s)</translation>
</message>
@@ -2995,10 +3165,6 @@
<translation>Virhe ladattaessa wallet.dat-tiedostoa</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Pakota yhteensopivuustila (oletus: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Luo kolikoita (oletus: %u)</translation>
</message>
@@ -3015,6 +3181,14 @@
<translation>Virheellinen proxy-osoite '%s'</translation>
</message>
<message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Kuuntele yhteyksiä portissa &lt;port&gt; (oletus: %u tai testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Aseta lompakko kuuluttamaan rahansiirtoja</translation>
+ </message>
+ <message>
<source>Relay non-P2SH multisig (default: %u)</source>
<translation>Välitä ei-P2SH-multisig (oletus: %u)</translation>
</message>
@@ -3047,6 +3221,10 @@
<translation>Määritä pid-tiedosto (oletus: %s)</translation>
</message>
<message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Käytä vahvistamattomia vaihtorahoja lähetettäessä rahansiirtoja (oletus: %u)</translation>
+ </message>
+ <message>
<source>Unknown network specified in -onlynet: '%s'</source>
<translation>Tuntematon verkko -onlynet parametrina: '%s'</translation>
</message>
diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts
index 67d920fd5e..fe140634e6 100644
--- a/src/qt/locale/bitcoin_fr.ts
+++ b/src/qt/locale/bitcoin_fr.ts
@@ -1,4 +1,4 @@
-<TS language="fr" version="2.1">
+<TS language="fr" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -2809,10 +2809,6 @@
<translation>Se lier à l'adresse donnée et toujours l'écouter. Utilisez la notation [host]:port pour l'IPv6</translation>
</message>
<message>
- <source>Continuously rate-limit free transactions to &lt;n&gt;*1000 bytes per minute (default: %u)</source>
- <translation>Limiter continuellement les transactions gratuites à &lt;n&gt;*1000 octets par minute (par défaut : %u)</translation>
- </message>
- <message>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Supprimer toutes les transactions du portefeuille et ne récupérer que ces parties de la chaîne de bloc avec -rescan au démarrage</translation>
</message>
@@ -2821,18 +2817,10 @@
<translation>Distribué sous la licence MIT d'utilisation d'un logiciel. Consultez le fichier joint COPYING ou &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Passer en mode de test de régression qui utilise une chaîne spéciale dans laquelle les blocs sont résolus instantanément.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Exécuter la commande lorsqu'une transaction de portefeuille change (%s dans la commande est remplacée par TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>Dans ce mode -genproclimit contrôle combien de blocs sont générés immédiatement.</translation>
- </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>
@@ -2853,6 +2841,14 @@
<translation>Impossible de se lier à %s sur cet ordinateur. Bitcoin Core fonctionne probablement déjà.</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVERTISSEMENT : un nombre anormalement élevé de blocs a été généré, %d blocs reçus durant les %d dernières heures (%d attendus)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>AVERTISSEMENT : vérifiez votre connexion réseau, %d blocs reçus durant les %d dernières heures (%d attendus)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Avertissement : -paytxfee est réglé sur un montant très élevé ! Il s'agit des frais de transaction que vous payerez si vous envoyez une transaction.</translation>
</message>
@@ -2989,10 +2985,6 @@
<translation>Spécifiez le fichier de portefeuille (dans le répertoire de données)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Ceci est à l'intention des outils de test de régression et du développement applicatif.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Utiliser l'UPnP pour mapper le port d'écoute (par défaut : %u)</translation>
</message>
@@ -3069,10 +3061,6 @@
<translation>Les frais (en BTC/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour le relayage (par défaut : %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Les frais (en BTC/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour la création de transactions (par défaut : %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Si paytxfee n'est pas défini, inclure suffisamment de frais afin que les transactions commencent la confirmation en moyenne avant n blocs (par défaut : %u)</translation>
</message>
@@ -3165,10 +3153,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com
<translation>Activation de la meilleure chaîne...</translation>
</message>
<message>
- <source>Allow self signed root certificates (default: 0)</source>
- <translation>Permettre les certificats racine autosignés (par défaut : 0)</translation>
- </message>
- <message>
<source>Can't run with a wallet in prune mode.</source>
<translation>L'exécution est impossible quand le portefeuille est en mode élagage.</translation>
</message>
@@ -3261,18 +3245,14 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com
<translation>Prise en charge de RPC pour les connexions persistantes HTTP (par défaut : %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Abandonner aléatoirement 1 message du réseau sur &lt;n&gt;</translation>
- </message>
- <message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Tester aléatoirement 1 message du réseau sur &lt;n&gt;</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>
<message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Recevoir et afficher les alertes du réseau poste à poste (%u par défaut)</translation>
+ </message>
+ <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log</translation>
</message>
@@ -3417,18 +3397,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com
<translation>(1 = conserver les métadonnées de transmission, par ex. les informations du propriétaire du compte et de la demande de paiement, 2 = abandonner les métadonnées de transmission)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Purger l’activité de la base de données de la zone de mémoire vers le journal sur disque tous les &lt;n&gt; mégaoctets (par défaut : %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Degré de profondeur de la vérification des blocs -checkblocks (0-4, par défaut : %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Lors du minage, journaliser la priorité des transactions et les frais par ko (par défaut : %u) </translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Maintenir un index complet des transactions, utilisé par l'appel RPC getrawtransaction (obtenir la transaction brute) (par défaut : %u)</translation>
</message>
@@ -3457,18 +3429,10 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com
<translation>Toujours demander les adresses des pairs par recherche DNS (par défaut : %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Désactiver le mode sans échec, passer outre un événement sans échec réel (par défaut : %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>Erreur lors du chargement de wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Forcer le mode sans échec (par défaut : %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Générer des pièces (défaut : %u)</translation>
</message>
@@ -3485,10 +3449,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com
<translation>Adresse -proxy invalide : « %s »</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Limiter la taille du cache des signatures à &lt;n&gt; entrées (par défaut : %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Écouter les connexions JSON-RPC sur &lt;port&gt; (par défaut : %u ou tesnet : %u)</translation>
</message>
@@ -3513,10 +3473,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com
<translation>Tampon maximal d'envoi par connexion », &lt;n&gt;*1000 octets (par défaut : %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>N'accepter qu'une chaîne de blocs correspondant aux points de vérification intégrés (par défaut : %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Ajouter l'horodatage au début de la sortie de débogage (par défaut : %u)</translation>
</message>
@@ -3529,10 +3485,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com
<translation>Relayer les multisignatures non-P2SH (par défaut : %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Exécuter une tâche pour purger le portefeuille périodiquement (par défaut : %u) </translation>
- </message>
- <message>
<source>Set key pool size to &lt;n&gt; (default: %u)</source>
<translation>Définir la taille de la réserve de clefs à &lt;n&gt; (par défaut : %u)</translation>
</message>
@@ -3541,10 +3493,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com
<translation>Définir la taille de bloc minimale en octets (par défaut : %u)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Définit le drapeau DB_PRIVATE dans l'environnement de la BD du portefeuille (par défaut : %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Spécifier le fichier de configuration (par défaut : %s)</translation>
</message>
@@ -3561,10 +3509,6 @@ par exemple : alertnotify=echo %%s | mail -s "Alerte Bitcoin" admin@foo.com
<translation>Dépenser la monnaie non confirmée lors de l'envoi de transactions (par défaut : %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Cesser l'exécution après l'importation des blocs du disque (par défaut : %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Seuil de déconnexion des pairs présentant un mauvais comportement (par défaut : %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_fr_CA.ts b/src/qt/locale/bitcoin_fr_CA.ts
index 186985d493..f4fe7d6597 100644
--- a/src/qt/locale/bitcoin_fr_CA.ts
+++ b/src/qt/locale/bitcoin_fr_CA.ts
@@ -1,4 +1,4 @@
-<TS language="fr_CA" version="2.1">
+<TS language="fr_CA" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts
index 2473260c84..709b17e2f7 100644
--- a/src/qt/locale/bitcoin_gl.ts
+++ b/src/qt/locale/bitcoin_gl.ts
@@ -1,4 +1,4 @@
-<TS language="gl" version="2.1">
+<TS language="gl" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_gu_IN.ts b/src/qt/locale/bitcoin_gu_IN.ts
index b7b091aa39..ef99b0dd39 100644
--- a/src/qt/locale/bitcoin_gu_IN.ts
+++ b/src/qt/locale/bitcoin_gu_IN.ts
@@ -1,4 +1,4 @@
-<TS language="gu_IN" version="2.1">
+<TS language="gu_IN" version="2.0">
<context>
<name>AddressBookPage</name>
</context>
diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts
index 66dd05fca7..9c1863de8a 100644
--- a/src/qt/locale/bitcoin_he.ts
+++ b/src/qt/locale/bitcoin_he.ts
@@ -1,4 +1,4 @@
-<TS language="he" version="2.1">
+<TS language="he" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -2511,10 +2511,6 @@
<translation>מחיקת כל העברות הארנק ולשחזר רק את החלקים המסוימים בשרשרת המקטעים באמצעות ‎-rescan עם ההפעלה</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>כניסה למצב בדיקת נסיגה, שמשתמש בשרשרת מיוחדת בה ניתן לפתור את המקטעים במהירות.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>ביצוע פקודה כאשר העברה בארנק משתנה (%s ב־cmd יוחלף ב־TxID)</translation>
</message>
@@ -2647,10 +2643,6 @@
<translation>ציון קובץ ארנק (בתוך תיקיית הנתונים)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>תכונה זו מיועדת לכלי בדיקות נסיגה ופיתוח יישומים.</translation>
- </message>
- <message>
<source>Verifying blocks...</source>
<translation>המקטעים מאומתים…</translation>
</message>
@@ -2679,10 +2671,6 @@
<translation>הרץ פקודה כאשר ההתראה הרלוונטית מתקבלת או כשאנחנו עדים לפיצול ארוך מאוד (%s בשורת הפקודה יוחלף ע"י ההודעה)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>העמלות (ב־BTC/ק״ב) הנמוכות מהסכום הזה נחשבות לעמלות אפס ליצירת העברה (בררת מחדל: %s)</translation>
- </message>
- <message>
<source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
<translation>אזהרה: נא לבדוק שהתאריך והשעה של המחשב שלך נכונים! אם השעון שלך שגוי ליבת ביטקוין לא תעבוד כראוי.</translation>
</message>
@@ -2759,10 +2747,6 @@
<translation>הגדרות שרת RPC</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>להשמיט אקראית אחת מתוך כל &lt;n&gt; הודעות רשת</translation>
- </message>
- <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>שלח מידע דיבאג ועקבה לקונסולה במקום לקובץ debug.log</translation>
</message>
diff --git a/src/qt/locale/bitcoin_hi_IN.ts b/src/qt/locale/bitcoin_hi_IN.ts
index 5fe8635dc0..01e074ffc6 100644
--- a/src/qt/locale/bitcoin_hi_IN.ts
+++ b/src/qt/locale/bitcoin_hi_IN.ts
@@ -1,4 +1,4 @@
-<TS language="hi_IN" version="2.1">
+<TS language="hi_IN" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_hr.ts b/src/qt/locale/bitcoin_hr.ts
index 62bfe6a11f..74d380ec2b 100644
--- a/src/qt/locale/bitcoin_hr.ts
+++ b/src/qt/locale/bitcoin_hr.ts
@@ -1,7 +1,11 @@
-<TS language="hr" version="2.1">
+<TS language="hr" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
+ <source>Right-click to edit address or label</source>
+ <translation>Desni klik za uređivanje adresa i oznaka</translation>
+ </message>
+ <message>
<source>Create a new address</source>
<translation>Dodajte novu adresu</translation>
</message>
@@ -23,7 +27,7 @@
</message>
<message>
<source>&amp;Copy Address</source>
- <translation>&amp;Kopirati adresu</translation>
+ <translation>&amp;Kopiraj adresu</translation>
</message>
<message>
<source>Delete the currently selected address from the list</source>
@@ -31,15 +35,15 @@
</message>
<message>
<source>Export the data in the current tab to a file</source>
- <translation>Izvoz podataka iz trenutnog taba u datoteku</translation>
+ <translation>Izvoz podataka iz trenutnog lista u datoteku</translation>
</message>
<message>
<source>&amp;Export</source>
- <translation>&amp;Izvoz</translation>
+ <translation>&amp;Izvozi</translation>
</message>
<message>
<source>&amp;Delete</source>
- <translation>&amp;Brisanje</translation>
+ <translation>Iz&amp;briši</translation>
</message>
<message>
<source>Choose the address to send coins to</source>
@@ -63,19 +67,19 @@
</message>
<message>
<source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
- <translation>Ovo su vaše Bitcoin adrese za slanje uplate. Uvijek provjerite iznos i adresu primatelja prije slanja novca.</translation>
+ <translation>Ovo su vaše Bitcoin adrese za slanje novca. Uvijek provjerite iznos i adresu primatelja prije slanja novca.</translation>
</message>
<message>
<source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
- <translation>Ovo su vaše Bitcoin adrese za primanje isplate. Preporučamo da koristite novu primateljsku adresu za svaku transakciju.</translation>
+ <translation>Ovo su vaše Bitcoin adrese za primanje novca. Preporučamo da koristite novu adresu za primanje za svaku transakciju.</translation>
</message>
<message>
<source>Copy &amp;Label</source>
- <translation>Kopirati &amp;oznaku</translation>
+ <translation>Kopiraj &amp;oznaku</translation>
</message>
<message>
<source>&amp;Edit</source>
- <translation>&amp;Izmjeniti</translation>
+ <translation>&amp;Uredi</translation>
</message>
<message>
<source>Export Address List</source>
@@ -157,7 +161,7 @@
</message>
<message>
<source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
- <translation>Upozorenje: Ako šifrirate vaš novčanik i izgubite lozinku, &lt;b&gt;IZGUBIT ĆETE SVE SVOJE BITCOINSE!&lt;/b&gt;</translation>
+ <translation>Upozorenje: Ako šifrirate vaš novčanik i izgubite lozinku, &lt;b&gt;IZGUBIT ĆETE SVE SVOJE BITCOINE!&lt;/b&gt;</translation>
</message>
<message>
<source>Are you sure you wish to encrypt your wallet?</source>
@@ -180,6 +184,10 @@
<translation>Unesite novu lozinku za novčanik. &lt;br/&gt;Molimo Vas da koristite zaporku od &lt;b&gt;deset ili više slučajnih znakova&lt;/b&gt;, ili &lt;b&gt;osam ili više riječi.&lt;/b&gt;</translation>
</message>
<message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Unesite staru i novu lozinku za novčanik.</translation>
+ </message>
+ <message>
<source>Wallet encryption failed</source>
<translation>Šifriranje novčanika nije uspjelo</translation>
</message>
@@ -256,7 +264,7 @@
</message>
<message>
<source>&amp;Options...</source>
- <translation>Pos&amp;tavke</translation>
+ <translation>Pos&amp;tavke...</translation>
</message>
<message>
<source>&amp;Encrypt Wallet...</source>
@@ -264,19 +272,19 @@
</message>
<message>
<source>&amp;Backup Wallet...</source>
- <translation>Si&amp;gurnosno kopiraj novčanik...</translation>
+ <translation>Spremi &amp;kopiju novčanika...</translation>
</message>
<message>
<source>&amp;Change Passphrase...</source>
- <translation>&amp;Promjena lozinke...</translation>
+ <translation>Promjena &amp;lozinke...</translation>
</message>
<message>
<source>&amp;Sending addresses...</source>
- <translation>Adrese za s&amp;lanje</translation>
+ <translation>Adrese za &amp;slanje</translation>
</message>
<message>
<source>&amp;Receiving addresses...</source>
- <translation>Adrese za p&amp;rimanje</translation>
+ <translation>Adrese za &amp;primanje</translation>
</message>
<message>
<source>Open &amp;URI...</source>
@@ -308,11 +316,11 @@
</message>
<message>
<source>&amp;Debug window</source>
- <translation>&amp;Ispravljanje programerskih pogrešaka</translation>
+ <translation>Konzola za dijagnostiku</translation>
</message>
<message>
<source>Open debugging and diagnostic console</source>
- <translation>Otvori konzolu za dijagnostiku i otklanjanje programskih pogrešaka.</translation>
+ <translation>Otvori konzolu za dijagnostiku</translation>
</message>
<message>
<source>&amp;Verify message...</source>
@@ -332,11 +340,11 @@
</message>
<message>
<source>&amp;Receive</source>
- <translation>Pri&amp;miti</translation>
+ <translation>Pri&amp;mi</translation>
</message>
<message>
<source>Show information about Bitcoin Core</source>
- <translation>Prikaži informacije o Bitcoin Coreu</translation>
+ <translation>Prikaži informacije o programu Bitcoin Core</translation>
</message>
<message>
<source>&amp;Show / Hide</source>
@@ -348,15 +356,15 @@
</message>
<message>
<source>Encrypt the private keys that belong to your wallet</source>
- <translation>Šifriraj privatne ključeve koji pripadaju tvom novčaniku</translation>
+ <translation>Šifriranje privatnih ključeva koji u novčaniku</translation>
</message>
<message>
<source>Sign messages with your Bitcoin addresses to prove you own them</source>
- <translation>Potpiši poruke svojim Bitcoin adresama kako bi dokazao da si njihov vlasnik</translation>
+ <translation>Poruku potpišemo s bitcoin adresom, kako bi dokazali vlasništvo nad tom adresom</translation>
</message>
<message>
<source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
- <translation>Provjerite porkue kako bi se uvjerili da su potpisane navedenim Bitcoin adresama</translation>
+ <translation>Provjeravanje poruke, kao dokaz, da je potpisana navedenom bitcoin adresom</translation>
</message>
<message>
<source>&amp;File</source>
@@ -376,23 +384,75 @@
</message>
<message>
<source>Bitcoin Core</source>
- <translation>Bitcoin Jezgra</translation>
+ <translation>Bitcoin Core</translation>
</message>
<message>
<source>Request payments (generates QR codes and bitcoin: URIs)</source>
- <translation>Zatraži uplate (Stvara QR kodove i bitcoin: URIje)</translation>
+ <translation>Zatraži uplatu (stvara QR kod i bitcoin: URI adresu)</translation>
</message>
<message>
<source>&amp;About Bitcoin Core</source>
- <translation>&amp;O Bitcoin Jezgri</translation>
+ <translation>&amp;O programu Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Promijeni postavke programa</translation>
</message>
<message>
<source>Show the list of used sending addresses and labels</source>
- <translation>Prikaži popis korištenih adresa i oznaka za slanje isplate</translation>
+ <translation>Prikaži popis korištenih adresa i oznaka za slanje novca</translation>
</message>
<message>
<source>Show the list of used receiving addresses and labels</source>
- <translation>Prikaži popis korištenih adresa i oznaka za primanje isplate</translation>
+ <translation>Prikaži popis korištenih adresa i oznaka za primanje novca</translation>
+ </message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Otvori bitcoin: URI adresu ili zahtjev za uplatu</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Opcije &amp;naredbene linije</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Ispis svih opcija naredbene linije programa sa kratkim opisom</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktivna veza na Bitcoin mrežu</numerusform><numerusform>%n aktivnih veza na Bitcoin mrežu</numerusform><numerusform>%n aktivnih veza na Bitcoin mrežu</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Obrađen %n blok povijesti transakcije.</numerusform><numerusform>Obrađeno %n bloka povijesti transakcije.</numerusform><numerusform>Obrađeno %n blokova povijesti transakcije.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n sat</numerusform><numerusform>%n sata</numerusform><numerusform>%n sati</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dan</numerusform><numerusform>%n dana</numerusform><numerusform>%n dana</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n tjedan</numerusform><numerusform>%n tjedna</numerusform><numerusform>%n tjedana</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 i %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n godina</numerusform><numerusform>%n godine</numerusform><numerusform>%n godina</numerusform></translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Zadnji primljeni blok je bio ustvaren prije %1.</translation>
+ </message>
+ <message>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transakcije izvršene za tim blokom nisu još prikazane.</translation>
</message>
<message>
<source>Error</source>
@@ -415,6 +475,36 @@
<translation>Ažuriranje...</translation>
</message>
<message>
+ <source>Date: %1
+</source>
+ <translation>Datum: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Iznos: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Vrsta: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Oznaka: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adresa: %1
+</translation>
+ </message>
+ <message>
<source>Sent transaction</source>
<translation>Poslana transakcija</translation>
</message>
@@ -437,34 +527,146 @@
<context>
<name>CoinControlDialog</name>
<message>
+ <source>Coin Selection</source>
+ <translation>Izbor ulaza transakcije</translation>
+ </message>
+ <message>
+ <source>Quantity:</source>
+ <translation>Količina:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bajtova:</translation>
+ </message>
+ <message>
<source>Amount:</source>
<translation>Iznos:</translation>
</message>
<message>
+ <source>Priority:</source>
+ <translation>Prioriteta:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Naknada:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Prah:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Vraćeno:</translation>
+ </message>
+ <message>
+ <source>(un)select all</source>
+ <translation>Izaberi sve/ništa</translation>
+ </message>
+ <message>
<source>Amount</source>
<translation>Iznos</translation>
</message>
<message>
+ <source>Received with label</source>
+ <translation>Primljeno pod oznakom</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Primljeno na adresu</translation>
+ </message>
+ <message>
<source>Date</source>
<translation>Datum</translation>
</message>
<message>
+ <source>Confirmations</source>
+ <translation>Broj potvrda</translation>
+ </message>
+ <message>
<source>Confirmed</source>
<translation>Potvrđeno</translation>
</message>
<message>
+ <source>Priority</source>
+ <translation>Prioriteta</translation>
+ </message>
+ <message>
<source>Copy address</source>
- <translation>Kopirati adresu</translation>
+ <translation>Kopiraj adresu</translation>
</message>
<message>
<source>Copy label</source>
- <translation>Kopirati oznaku</translation>
+ <translation>Kopiraj oznaku</translation>
</message>
<message>
<source>Copy amount</source>
<translation>Kopiraj iznos</translation>
</message>
<message>
+ <source>Copy transaction ID</source>
+ <translation>Kopiraj ID transakcije</translation>
+ </message>
+ <message>
+ <source>highest</source>
+ <translation>najviša</translation>
+ </message>
+ <message>
+ <source>higher</source>
+ <translation>viša</translation>
+ </message>
+ <message>
+ <source>high</source>
+ <translation>visoka</translation>
+ </message>
+ <message>
+ <source>medium-high</source>
+ <translation>srednje visoka</translation>
+ </message>
+ <message>
+ <source>medium</source>
+ <translation>srednja</translation>
+ </message>
+ <message>
+ <source>low-medium</source>
+ <translation>srednje niska</translation>
+ </message>
+ <message>
+ <source>low</source>
+ <translation>niska</translation>
+ </message>
+ <message>
+ <source>lower</source>
+ <translation>niža</translation>
+ </message>
+ <message>
+ <source>lowest</source>
+ <translation>najniža</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Oznaka postane crvene boje ako je transakcija veća od 1000 bajtova.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Oznaka postane crvene boje ako je prioriteta transakcije niža od "srednja"</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Oznaka postane crvene boje ako je iznos manji od %1</translation>
+ </message>
+ <message>
+ <source>yes</source>
+ <translation>da</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>ne</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Transakcije više prioritete imaju veću vjerojatnost da budu prije dodane u novi blok.</translation>
+ </message>
+ <message>
<source>(no label)</source>
<translation>(bez oznake)</translation>
</message>
@@ -473,13 +675,21 @@
<name>EditAddressDialog</name>
<message>
<source>Edit Address</source>
- <translation>Izmjeni adresu</translation>
+ <translation>Uredi adresu</translation>
</message>
<message>
<source>&amp;Label</source>
<translation>&amp;Oznaka</translation>
</message>
<message>
+ <source>The label associated with this address list entry</source>
+ <translation>Oznaka bitcoin adrese</translation>
+ </message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Bitcoin adresa. Izmjene adrese su moguće samo za adrese za slanje.</translation>
+ </message>
+ <message>
<source>&amp;Address</source>
<translation>&amp;Adresa</translation>
</message>
@@ -519,29 +729,49 @@
<context>
<name>FreespaceChecker</name>
<message>
+ <source>A new data directory will be created.</source>
+ <translation>Stvoren će biti novi direktorij za podatke.</translation>
+ </message>
+ <message>
<source>name</source>
<translation>ime</translation>
</message>
- </context>
+ <message>
+ <source>Cannot create data directory here.</source>
+ <translation>Nije moguće stvoriti direktorij za podatke na tom mjestu.</translation>
+ </message>
+</context>
<context>
<name>HelpMessageDialog</name>
<message>
<source>Bitcoin Core</source>
- <translation>Bitcoin Jezgra</translation>
+ <translation>Bitcoin Core</translation>
</message>
<message>
<source>version</source>
<translation>verzija</translation>
</message>
<message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
+ <message>
<source>About Bitcoin Core</source>
- <translation>O Bitcoinovoj jezgri</translation>
+ <translation>O programu Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Command-line options</source>
+ <translation>Opcije programa u naredbenoj liniji</translation>
</message>
<message>
<source>Usage:</source>
<translation>Upotreba:</translation>
</message>
- </context>
+ <message>
+ <source>command-line options</source>
+ <translation>opcije programa u naredbenoj liniji</translation>
+ </message>
+</context>
<context>
<name>Intro</name>
<message>
@@ -549,8 +779,12 @@
<translation>Dobrodošli</translation>
</message>
<message>
+ <source>Welcome to Bitcoin Core.</source>
+ <translation>Dobrodošli u programu Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Bitcoin Core</source>
- <translation>Bitcoin Jezgra</translation>
+ <translation>Bitcoin Core</translation>
</message>
<message>
<source>Error</source>
@@ -559,7 +793,27 @@
</context>
<context>
<name>OpenURIDialog</name>
- </context>
+ <message>
+ <source>Open URI</source>
+ <translation>Otvori URI adresu</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Otvori zahtjev za plaćanje iz URI adrese ili datoteke</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Izaberi datoteku zahtjeva za plaćanje</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Izaberi datoteku zahtjeva za plaćanje</translation>
+ </message>
+</context>
<context>
<name>OptionsDialog</name>
<message>
@@ -571,10 +825,58 @@
<translation>&amp;Glavno</translation>
</message>
<message>
+ <source>Size of &amp;database cache</source>
+ <translation>Veličina predmemorije baze podataka</translation>
+ </message>
+ <message>
+ <source>MB</source>
+ <translation>MB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Broj CPU niti za verifikaciju transakcija</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Dozvoli povezivanje izvana</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>IP adresa proxy servera (npr. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimizirati aplikaciju umjesto zatvoriti, kada se zatvori prozor. Kada je ova opcija omogućena, aplikacija će biti zatvorena tek nakon odabira naredbe Izlaz u izborniku.</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Nastavi sve postavke programa na početne vrijednosti.</translation>
+ </message>
+ <message>
+ <source>&amp;Reset Options</source>
+ <translation>Po&amp;nastavi postavke</translation>
+ </message>
+ <message>
<source>&amp;Network</source>
<translation>&amp;Mreža</translation>
</message>
<message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Program se automatski pokrene po prijavi u sustav.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Pokreni program kod prijave u sustav</translation>
+ </message>
+ <message>
+ <source>W&amp;allet</source>
+ <translation>&amp;Novčanik</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>&amp;Trošenje nepotvrđenih vraćenih iznosa</translation>
+ </message>
+ <message>
<source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
<translation>Automatski otvori port Bitcoin klijenta na ruteru. To radi samo ako ruter podržava UPnP i ako je omogućen.</translation>
</message>
@@ -587,8 +889,12 @@
<translation>Proxy &amp;IP:</translation>
</message>
<message>
+ <source>&amp;Port:</source>
+ <translation>&amp;Vrata:</translation>
+ </message>
+ <message>
<source>Port of the proxy (e.g. 9050)</source>
- <translation>Port od proxy-a (npr. 9050)</translation>
+ <translation>Proxy vrata (npr. 9050)</translation>
</message>
<message>
<source>&amp;Window</source>
@@ -611,8 +917,12 @@
<translation>&amp;Prikaz</translation>
</message>
<message>
+ <source>User Interface &amp;language:</source>
+ <translation>Jezi&amp;k sučelja:</translation>
+ </message>
+ <message>
<source>&amp;Unit to show amounts in:</source>
- <translation>&amp;Jedinica za prikazivanje iznosa:</translation>
+ <translation>&amp;Jedinica za prikaz iznosa:</translation>
</message>
<message>
<source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
@@ -674,6 +984,10 @@
<context>
<name>QRImageWidget</name>
<message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Spremi sliku...</translation>
+ </message>
+ <message>
<source>Save QR Code</source>
<translation>Spremi QR kod</translation>
</message>
@@ -694,11 +1008,11 @@
</message>
<message>
<source>&amp;Information</source>
- <translation>&amp;Informacija</translation>
+ <translation>&amp;Informacije</translation>
</message>
<message>
<source>Using OpenSSL version</source>
- <translation>Koristim OpenSSL verziju</translation>
+ <translation>OpenSSL verzija u upotrebi</translation>
</message>
<message>
<source>Network</source>
@@ -710,7 +1024,7 @@
</message>
<message>
<source>Number of connections</source>
- <translation>Broj konekcija</translation>
+ <translation>Broj veza</translation>
</message>
<message>
<source>Block chain</source>
@@ -721,6 +1035,34 @@
<translation>Trenutni broj blokova</translation>
</message>
<message>
+ <source>Received</source>
+ <translation>Primljeno</translation>
+ </message>
+ <message>
+ <source>Sent</source>
+ <translation>Poslano</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Smjer</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Verzija</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Trajanje veze</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Bajtova poslano</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Bajtova primljeno</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Posljednje vrijeme bloka</translation>
</message>
@@ -733,6 +1075,10 @@
<translation>&amp;Konzola</translation>
</message>
<message>
+ <source>&amp;Network Traffic</source>
+ <translation>&amp;Mrežni promet</translation>
+ </message>
+ <message>
<source>Totals</source>
<translation>Ukupno:</translation>
</message>
@@ -741,23 +1087,47 @@
<translation>Očisti konzolu</translation>
</message>
<message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Dobrodošli u Bitcoin RPC konzolu.</translation>
+ </message>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
- <translation>Kako bi navigirali kroz povijest koristite strelice gore i dolje. &lt;b&gt;Ctrl-L&lt;/b&gt; kako bi očistili ekran.</translation>
+ <translation>Koristite tipke gore i dolje za izbor već korištenih naredbi. &lt;b&gt;Ctrl-L&lt;/b&gt; kako bi očistili ekran i povijest naredbi.</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Nepoznato</translation>
</message>
</context>
<context>
<name>ReceiveCoinsDialog</name>
<message>
+ <source>&amp;Amount:</source>
+ <translation>&amp;Iznos:</translation>
+ </message>
+ <message>
<source>&amp;Label:</source>
<translation>&amp;Oznaka:</translation>
</message>
<message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Poruka:</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Obriši sva polja</translation>
+ </message>
+ <message>
+ <source>&amp;Request payment</source>
+ <translation>&amp;Zatraži plaćanje</translation>
+ </message>
+ <message>
<source>Show</source>
<translation>Pokaži</translation>
</message>
<message>
<source>Copy label</source>
- <translation>Kopirati oznaku</translation>
+ <translation>Kopiraj oznaku</translation>
</message>
<message>
<source>Copy amount</source>
@@ -771,6 +1141,22 @@
<translation>QR kôd</translation>
</message>
<message>
+ <source>Copy &amp;URI</source>
+ <translation>Kopiraj &amp;URI</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Address</source>
+ <translation>Kopiraj &amp;adresu</translation>
+ </message>
+ <message>
+ <source>&amp;Save Image...</source>
+ <translation>&amp;Spremi sliku...</translation>
+ </message>
+ <message>
+ <source>URI</source>
+ <translation>URI</translation>
+ </message>
+ <message>
<source>Address</source>
<translation>Adresa</translation>
</message>
@@ -788,9 +1174,13 @@
</message>
<message>
<source>Resulting URI too long, try to reduce the text for label / message.</source>
- <translation>Rezultirajući URI je predug, probajte umanjiti tekst za naslov / poruku.</translation>
+ <translation>URI je predug, probajte skratiti tekst za naslov / poruku.</translation>
</message>
- </context>
+ <message>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Greška kod kodiranja URI adrese u QR kod.</translation>
+ </message>
+</context>
<context>
<name>RecentRequestsTableModel</name>
<message>
@@ -813,7 +1203,15 @@
<source>(no label)</source>
<translation>(bez oznake)</translation>
</message>
- </context>
+ <message>
+ <source>(no message)</source>
+ <translation>(bez poruke)</translation>
+ </message>
+ <message>
+ <source>(no amount)</source>
+ <translation>(bez iznosa)</translation>
+ </message>
+</context>
<context>
<name>SendCoinsDialog</name>
<message>
@@ -821,18 +1219,46 @@
<translation>Slanje novca</translation>
</message>
<message>
+ <source>Quantity:</source>
+ <translation>Količina:</translation>
+ </message>
+ <message>
+ <source>Bytes:</source>
+ <translation>Bajtova:</translation>
+ </message>
+ <message>
<source>Amount:</source>
<translation>Iznos:</translation>
</message>
<message>
+ <source>Priority:</source>
+ <translation>Prioriteta:</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Naknada:</translation>
+ </message>
+ <message>
+ <source>Change:</source>
+ <translation>Vraćeno:</translation>
+ </message>
+ <message>
<source>Send to multiple recipients at once</source>
- <translation>Pošalji k nekoliko primatelja odjednom</translation>
+ <translation>Pošalji novce većem broju primatelja u jednoj transakciji</translation>
</message>
<message>
<source>Add &amp;Recipient</source>
<translation>&amp;Dodaj primatelja</translation>
</message>
<message>
+ <source>Clear all fields of the form.</source>
+ <translation>Obriši sva polja</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Prah:</translation>
+ </message>
+ <message>
<source>Clear &amp;All</source>
<translation>Obriši &amp;sve</translation>
</message>
@@ -866,11 +1292,11 @@
</message>
<message>
<source>The amount exceeds your balance.</source>
- <translation>Iznos je veći od stanja računa.</translation>
+ <translation>Iznos je veći od raspoložljivog stanja novčanika.</translation>
</message>
<message>
<source>The total exceeds your balance when the %1 transaction fee is included.</source>
- <translation>Iznos je veći od stanja računa kad se doda naknada za transakcije od %1.</translation>
+ <translation>Iznos je veći od stanja novčanika kad se doda naknada za transakcije od %1.</translation>
</message>
<message>
<source>(no label)</source>
@@ -966,7 +1392,7 @@
<name>SplashScreen</name>
<message>
<source>Bitcoin Core</source>
- <translation>Bitcoin Jezgra</translation>
+ <translation>Bitcoin Core</translation>
</message>
<message>
<source>[testnet]</source>
@@ -1087,7 +1513,7 @@
</message>
<message>
<source>This pane shows a detailed description of the transaction</source>
- <translation>Ova panela prikazuje detaljni opis transakcije</translation>
+ <translation>Ovaj prozor prikazuje detaljni opis transakcije</translation>
</message>
</context>
<context>
@@ -1110,7 +1536,7 @@
</message>
<message>
<source>This block was not received by any other nodes and will probably not be accepted!</source>
- <translation>Generirano - Upozorenje: ovaj blok nije bio primljen od strane bilo kojeg drugog noda i vjerojatno neće biti prihvaćen!</translation>
+ <translation>Ovaj blok nije bio primljen od strane bilo kojeg drugog čvora i vjerojatno neće biti prihvaćen!</translation>
</message>
<message>
<source>Generated but not accepted</source>
@@ -1201,7 +1627,7 @@
</message>
<message>
<source>To yourself</source>
- <translation>Tebi</translation>
+ <translation>Samom sebi</translation>
</message>
<message>
<source>Mined</source>
@@ -1221,19 +1647,23 @@
</message>
<message>
<source>Copy address</source>
- <translation>Kopirati adresu</translation>
+ <translation>Kopiraj adresu</translation>
</message>
<message>
<source>Copy label</source>
- <translation>Kopirati oznaku</translation>
+ <translation>Kopiraj oznaku</translation>
</message>
<message>
<source>Copy amount</source>
<translation>Kopiraj iznos</translation>
</message>
<message>
+ <source>Copy transaction ID</source>
+ <translation>Kopiraj ID transakcije</translation>
+ </message>
+ <message>
<source>Edit label</source>
- <translation>Izmjeniti oznaku</translation>
+ <translation>Izmjeni oznaku</translation>
</message>
<message>
<source>Show transaction details</source>
@@ -1305,7 +1735,7 @@
</message>
<message>
<source>Backup Wallet</source>
- <translation>Backup novčanika</translation>
+ <translation>Arhiviranje novčanika</translation>
</message>
<message>
<source>Wallet Data (*.dat)</source>
@@ -1313,7 +1743,7 @@
</message>
<message>
<source>Backup Failed</source>
- <translation>Backup nije uspio</translation>
+ <translation>Arhiviranje nije uspjelo</translation>
</message>
</context>
<context>
@@ -1324,7 +1754,7 @@
</message>
<message>
<source>Specify data directory</source>
- <translation>Odredi direktorij za datoteke</translation>
+ <translation>Odaberi direktorij za datoteke</translation>
</message>
<message>
<source>Specify your own public address</source>
@@ -1352,15 +1782,15 @@
</message>
<message>
<source>Connect only to the specified node(s)</source>
- <translation>Poveži se samo sa određenim nodom</translation>
+ <translation>Poveži se samo sa određenim čvorom/čvorovima</translation>
</message>
<message>
<source>Error: Disk space is low!</source>
- <translation>Pogreška: Nema prostora na disku!</translation>
+ <translation>Pogreška: Nema dovoljno prostora na disku!</translation>
</message>
<message>
<source>Imports blocks from external blk000??.dat file</source>
- <translation>Importiraj blokove sa vanjskog blk000??.dat fajla</translation>
+ <translation>Uvozi blokove sa vanjske blk000??.dat datoteke</translation>
</message>
<message>
<source>Information</source>
@@ -1412,7 +1842,7 @@
</message>
<message>
<source>Allow DNS lookups for -addnode, -seednode and -connect</source>
- <translation>Dozvoli DNS upite za dodavanje nodova i povezivanje</translation>
+ <translation>Dozvoli DNS upite za -addnode, -seednode i -connect</translation>
</message>
<message>
<source>Loading addresses...</source>
@@ -1420,11 +1850,11 @@
</message>
<message>
<source>Error loading wallet.dat: Wallet corrupted</source>
- <translation>Greška kod učitavanja wallet.dat: Novčanik pokvaren</translation>
+ <translation>Greška kod učitavanja datoteke wallet.dat: Novčanik pokvaren</translation>
</message>
<message>
<source>Error loading wallet.dat</source>
- <translation>Greška kod učitavanja wallet.dat</translation>
+ <translation>Greška kod učitavanja datoteke wallet.dat</translation>
</message>
<message>
<source>Invalid -proxy address: '%s'</source>
@@ -1432,7 +1862,7 @@
</message>
<message>
<source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
- <translation>Nevaljali iznos za opciju -paytxfee=&lt;amount&gt;: '%s'</translation>
+ <translation>Nevaljali iznos za opciju -paytxfee=&lt;iznos&gt;: '%s'</translation>
</message>
<message>
<source>Insufficient funds</source>
@@ -1444,7 +1874,7 @@
</message>
<message>
<source>Add a node to connect to and attempt to keep the connection open</source>
- <translation>Unesite nod s kojim se želite spojiti and attempt to keep the connection open</translation>
+ <translation>Doda čvor s kojim se želite povezati i nastoji održati vezu otvorenu</translation>
</message>
<message>
<source>Loading wallet...</source>
@@ -1460,7 +1890,7 @@
</message>
<message>
<source>Rescanning...</source>
- <translation>Rescaniranje</translation>
+ <translation>Ponovno pretraživanje...</translation>
</message>
<message>
<source>Done loading</source>
diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts
index c84d2c4e87..fd476611ee 100644
--- a/src/qt/locale/bitcoin_hu.ts
+++ b/src/qt/locale/bitcoin_hu.ts
@@ -1,4 +1,4 @@
-<TS language="hu" version="2.1">
+<TS language="hu" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -414,6 +414,10 @@
<source>No block source available...</source>
<translation>Blokk forrása ismeretlen...</translation>
</message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n óra</numerusform><numerusform>%n óra</numerusform></translation>
+ </message>
<message>
<source>%1 and %2</source>
<translation>%1 és %2</translation>
@@ -451,6 +455,18 @@
<translation>Frissítés...</translation>
</message>
<message>
+ <source>Date: %1
+</source>
+ <translation>Dátum: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Típus: %1
+</translation>
+ </message>
+ <message>
<source>Sent transaction</source>
<translation>Tranzakció elküldve.</translation>
</message>
@@ -789,6 +805,10 @@
<translation>Üdvözlünk a Bitcoin Core-ban.</translation>
</message>
<message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>A Bitcoin Core le fogja tölteni és tárolni fogja a Bitcoin blokklánc egy másolatát. Legalább %1GB adat lesz tárolva ebben a mappában, és ez folyamatosan nőni fog. A tárca szintén itt lesz tárolva.</translation>
+ </message>
+ <message>
<source>Use the default data directory</source>
<translation>Az alapértelmezett adat könyvtár használata</translation>
</message>
@@ -871,6 +891,14 @@
<translation>&amp;Hálózat</translation>
</message>
<message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>A Bitcoin elindítása bejelentkezéskor</translation>
+ </message>
+ <message>
+ <source>Expert</source>
+ <translation>szakértő</translation>
+ </message>
+ <message>
<source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
<translation>A Bitcoin-kliens portjának automatikus megnyitása a routeren. Ez csak akkor működik, ha a routered támogatja az UPnP-t és az engedélyezve is van rajta.</translation>
</message>
@@ -879,6 +907,10 @@
<translation>&amp;UPnP port-feltérképezés</translation>
</message>
<message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Csatlakozás a Bitcoin hálózatához SOCKS5 proxyn keresztül</translation>
+ </message>
+ <message>
<source>Proxy &amp;IP:</source>
<translation>Proxy &amp;IP:</translation>
</message>
@@ -1016,6 +1048,10 @@
<context>
<name>PeerTableModel</name>
<message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Ping idő</translation>
</message>
@@ -1137,10 +1173,30 @@
<translation>Verzió</translation>
</message>
<message>
+ <source>User Agent</source>
+ <translation>User Agent</translation>
+ </message>
+ <message>
<source>Services</source>
<translation>Szolgáltatások</translation>
</message>
<message>
+ <source>Last Send</source>
+ <translation>Legutóbbi küldés</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Legutóbbi fogadás</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Küldött bájtok</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Fogadott bájtok</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Ping idő</translation>
</message>
@@ -1212,6 +1268,10 @@
<source>never</source>
<translation>soha</translation>
</message>
+ <message>
+ <source>Unknown</source>
+ <translation>Ismeretlen</translation>
+ </message>
</context>
<context>
<name>ReceiveCoinsDialog</name>
@@ -1220,6 +1280,10 @@
<translation>Címke:</translation>
</message>
<message>
+ <source>&amp;Message:</source>
+ <translation>&amp;Üzenet:</translation>
+ </message>
+ <message>
<source>Clear</source>
<translation>Törlés</translation>
</message>
@@ -1353,6 +1417,14 @@
<translation>Visszajáró:</translation>
</message>
<message>
+ <source>Transaction Fee:</source>
+ <translation>Tranzakciós díj</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Elrejtés</translation>
+ </message>
+ <message>
<source>Send to multiple recipients at once</source>
<translation>Küldés több címzettnek egyszerre</translation>
</message>
@@ -1750,6 +1822,10 @@
<translation>Címke</translation>
</message>
<message>
+ <source>Unconfirmed</source>
+ <translation>Megerősítetlen:</translation>
+ </message>
+ <message>
<source>Received with</source>
<translation>Erre a címre</translation>
</message>
@@ -1877,6 +1953,10 @@
<translation>Az exportálás sikertelen volt</translation>
</message>
<message>
+ <source>Exporting Successful</source>
+ <translation>Sikeres exportálás</translation>
+ </message>
+ <message>
<source>Comma separated file (*.csv)</source>
<translation>Vesszővel elválasztott fájl (*.csv)</translation>
</message>
@@ -2057,6 +2137,10 @@
<translation>Tárca ellenőrzése...</translation>
</message>
<message>
+ <source>Wallet options:</source>
+ <translation>Tárca beállítások:</translation>
+ </message>
+ <message>
<source>You need to rebuild the database using -reindex to change -txindex</source>
<translation>Az adatbázist újra kell építeni -reindex használatával (módosítás -tindex).</translation>
</message>
@@ -2065,6 +2149,14 @@
<translation>Adatkönyvtár kiválasztása induláskor (alapbeállítás: 0)</translation>
</message>
<message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i A Bitcoin Core Fejlesztői</translation>
+ </message>
+ <message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Hiba az adatbázis olvasásakor, leállítás</translation>
+ </message>
+ <message>
<source>Information</source>
<translation>Információ</translation>
</message>
diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts
index dec30dafb3..6855d11c80 100644
--- a/src/qt/locale/bitcoin_id_ID.ts
+++ b/src/qt/locale/bitcoin_id_ID.ts
@@ -1,4 +1,4 @@
-<TS language="id_ID" version="2.1">
+<TS language="id_ID" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts
index c81f458e39..d3cc576979 100644
--- a/src/qt/locale/bitcoin_it.ts
+++ b/src/qt/locale/bitcoin_it.ts
@@ -1,4 +1,4 @@
-<TS language="it" version="2.1">
+<TS language="it" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -2806,10 +2806,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation>
<translation>Associa all'indirizzo indicato e resta permanentemente in ascolto su di esso. Usa la notazione [host]:porta per l'IPv6</translation>
</message>
<message>
- <source>Continuously rate-limit free transactions to &lt;n&gt;*1000 bytes per minute (default: %u)</source>
- <translation>Limita la quantità di transazioni gratuite ad &lt;n&gt;*1000 byte al minuto (predefinito: %u)</translation>
- </message>
- <message>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Elimina tutte le transazioni dal portamonete e recupera solo quelle che fanno parte della blockchain attraverso il comando -rescan all'avvio.</translation>
</message>
@@ -2818,18 +2814,10 @@ Per specificare più URL separarli con una barra verticale "|".</translation>
<translation>Distribuito secondo la licenza software MIT, vedi il file COPYING incluso oppure &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Entra in modalità test di regressione. Questa utilizza una speciale catena in cui i blocchi possono essere risolti istantaneamente.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Esegue un comando quando lo stato di una transazione del portamonete cambia (%s in cmd è sostituito da TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>In questa modalità -genproclimit determina quanti blocchi saranno generati immediatamente.</translation>
- </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>
@@ -2850,6 +2838,14 @@ Per specificare più URL separarli con una barra verticale "|".</translation>
<translation>Impossibile associarsi a %s su questo computer. Probabilmente Bitcoin Core è già in esecuzione.</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ATTENZIONE, il numero di blocchi generati è insolitamente elevato: %d blocchi ricevuti nelle ultime %d ore (%d previsti)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ATTENZIONE, si consiglia di verificare la connessione di rete: %d blocchi ricevuti nelle ultime %d ore (%d previsti)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Attenzione: -paytxfee è impostato su un valore molto elevato. Questa è la commissione che si paga quando si invia una transazione.</translation>
</message>
@@ -2986,10 +2982,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation>
<translation>Specifica il file del portamonete (all'interno della cartella dati)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Questa impostazione è destinata all'uso con i test di regressione e per lo sviluppo di applicazioni.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Usa UPnP per mappare la porta di ascolto (predefinito: %u)</translation>
</message>
@@ -3062,10 +3054,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation>
<translation>Le commissioni (in BTC/kB) inferiori a questo valore sono considerate pari a zero relativamente alla trasmissione (predefinito: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Le commissioni (in BTC/kB) inferiori a questo valore sono considerate pari a zero relativamente alla creazione della transazione (predefinito: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Nel caso in cui paytxfee non sia impostato, include una commissione tale da ottenere un avvio delle conferme entro una media di n blocchi (predefinito: %u)</translation>
</message>
@@ -3090,10 +3078,6 @@ Per specificare più URL separarli con una barra verticale "|".</translation>
<translation>Randomizza le credenziali per ogni connessione proxy. Permette la Tor stream isolation (predefinito: %u)</translation>
</message>
<message>
- <source>Require high priority for relaying free or low-fee transactions (default: %u)</source>
- <translation>Richiedi alta priorità per la trasmissione di transazioni a zero o basse commissioni (predefinito: %u)</translation>
- </message>
- <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Imposta la dimensione massima in byte delle transazioni ad alta-priorità/basse-commissioni (predefinito: %d)</translation>
</message>
@@ -3161,10 +3145,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d
<translation>Attivazione della blockchain migliore...</translation>
</message>
<message>
- <source>Allow self signed root certificates (default: 0)</source>
- <translation>Permette certificati radice auto-firmati (predefinito: 0)</translation>
- </message>
- <message>
<source>Can't run with a wallet in prune mode.</source>
<translation>Impossibile operare con un portamonete in modalità prune.</translation>
</message>
@@ -3257,12 +3237,12 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d
<translation>Supporto RPC per le connessioni HTTP persistenti (predefinito: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Scarta casualmente 1 ogni &lt;n&gt; messaggi di rete</translation>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Ricostruzione dell'indice della block chain dai file blk000??.dat correnti all'avvio</translation>
</message>
<message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Altera casualmente 1 ogni &lt;n&gt; messaggi di rete</translation>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Ricevi e visualizza gli alerts della rete P2P (default: %u)</translation>
</message>
<message>
<source>Send trace/debug info to console instead of debug.log file</source>
@@ -3409,18 +3389,10 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d
<translation>(1 = mantiene metadati tx, ad es. proprietario account ed informazioni di richiesta di pagamento, 2 = scarta metadati tx)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Scarica l'attività del database dal pool in memoria al log su disco ogni &lt;n&gt; megabyte (predefinito: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Determina quanto sarà approfondita la verifica da parte di -checkblocks (0-4, predefinito: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Abilita il log della priorità di transazione e della commissione per kB quando si generano blocchi (predefinito: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Mantiene l'indice completo delle transazioni usato dalla chiamata rpc getrawtransaction (predefinito: %u)</translation>
</message>
@@ -3449,18 +3421,10 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d
<translation>Interroga sempre i DNS per ottenere gli indirizzi dei peer (predefinito: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Disabilita la modalità sicura ignorando gli eventi che porterebbero alla sua attivazione (predefinito: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>Errore caricamento wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Forza modalità sicura (predefinito: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Genera bitcoin (predefinito: %u)</translation>
</message>
@@ -3477,10 +3441,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d
<translation>Indirizzo -proxy non valido: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Limita la dimensione della cache delle firme a &lt;n&gt; voci (predefinito: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Resta in attesa di connessioni JSON-RPC su &lt;port&gt; (predefinito: %u o testnet: %u)</translation>
</message>
@@ -3505,10 +3465,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d
<translation>Buffer di invio massimo per connessione, &lt;n&gt;*1000 byte (predefinito: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Accetta solo block chain corrispondenti ai checkpoint integrati nel codice (predefinito: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Antepone un timestamp all'output del debug (predefinito: %u)</translation>
</message>
@@ -3521,10 +3477,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d
<translation>Trasmette transazioni non-P2SH multisig (predefinito: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Mantieni in esecuzione un thread per scaricare periodicamente il portamonete (predefinito: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>File del certificato del server (predefinito: %s)</translation>
</message>
@@ -3545,10 +3497,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d
<translation>Imposta il numero di thread destinati a rispondere alle chiamate RPC (predefinito %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Imposta il flag DB_PRIVATE nell'ambiente di database del portamonete (predefinito: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Specifica il file di configurazione (predefinito: %s)</translation>
</message>
@@ -3565,10 +3513,6 @@ Si raccomanda inoltre di configurare alertnotify in modo da ricevere notifiche d
<translation>Abilita la spesa di resto non confermato quando si inviano transazioni (predefinito: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Interrompi l'esecuzione dopo aver importato i blocchi dal disco (predefinito: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Soglia di disconnessione per i peer che si comportano in maniera anomala (predefinito: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts
index 376d36bed0..e2c22f7f6d 100644
--- a/src/qt/locale/bitcoin_ja.ts
+++ b/src/qt/locale/bitcoin_ja.ts
@@ -1,4 +1,4 @@
-<TS language="ja" version="2.1">
+<TS language="ja" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -2817,10 +2817,6 @@
<translation>指定のアドレスへバインドし、その上で常にリスンします。IPv6 は [ホスト名]:ポート番号 と表記します</translation>
</message>
<message>
- <source>Continuously rate-limit free transactions to &lt;n&gt;*1000 bytes per minute (default: %u)</source>
- <translation>継続的に無料トランザクションのレートを一分間に&lt;n&gt;*1000バイトに制限する (規定値: %u)</translation>
- </message>
- <message>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>ウォレットの全トランザクションを削除し、これらを-rescanオプションを用いることで起動時にブロックチェインのデータのみからリカバリします。</translation>
</message>
@@ -2829,18 +2825,10 @@
<translation>MITソフトウェアライセンスのもとで配布されています。付属のCOPYINGファイルまたは&lt;http://www.opensource.org/licenses/mit-license.php&gt;を参照してください。</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>ブロックを瞬時に解決することができる特別なチェーンを使用して、リグレッションテストモードに入る。</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>ウォレットの取引を変更する際にコマンドを実行 (cmd の %s は TxID に置換される)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>このモードでは -genproclimit は何個のブロックをただちに生成するのか制御します。</translation>
- </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>
@@ -2861,6 +2849,14 @@
<translation>このコンピュータの %s にバインドすることができません。おそらく Bitcoin Core は既に実行されています。</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>警告:異常に多くの数のブロックが生成されています。%d ブロックが最近 %d 時間以内に受け取られました。(期待値: %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>警告:ネットワーク接続を確認してください。%d ブロックが最近 %d 時間以内にに受け取られました。(期待値: %d)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>警告: -paytxfee が非常に高く設定されています! これは取引を送信する場合に支払う取引手数料です。</translation>
</message>
@@ -2998,10 +2994,6 @@
<translation>ウォレットのファイルを指定 (データ・ディレクトリの中に)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>これはリグレッションテストツールやアプリ開発のためのものです。</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>リッスンポートの割当に UPnP を使用 (初期値: %u)</translation>
</message>
@@ -3078,10 +3070,6 @@
<translation>中継の際、この値未満の手数料 (BTC/Kb単位) はゼロであるとみなす (デフォルト: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>トランザクション作成の際、この値未満の手数料 (BTC/Kb単位) はゼロであるとみなす (デフォルト: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>paytxfee が設定されていなかった場合、平均して n ブロック以内にトランザクションが検証され始めるのに十分な手数料を含める (初期値: %u)</translation>
</message>
@@ -3106,10 +3094,6 @@
<translation>認証情報をプロキシー接続ごとにランダム化する。これによりTorストリーム分離をすることができます (規定値: %u)</translation>
</message>
<message>
- <source>Require high priority for relaying free or low-fee transactions (default: %u)</source>
- <translation>無料や低い手数料のトランザクションのリレーに際し、高い優先度を要求する (規定値: %u)</translation>
- </message>
- <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>最優先/最低手数料の最大サイズをバイトで指定 (初期値: %d)</translation>
</message>
@@ -3178,10 +3162,6 @@ rpcpassword=%s
<translation>最優良のチェインを有効化しています...</translation>
</message>
<message>
- <source>Allow self signed root certificates (default: 0)</source>
- <translation>自己署名ルート証明書を許可する (規定値: 0)</translation>
- </message>
- <message>
<source>Can't run with a wallet in prune mode.</source>
<translation>剪定モードではウォレット機能付きで起動できません。</translation>
</message>
@@ -3274,18 +3254,14 @@ rpcpassword=%s
<translation>RPCにおけるHTTPの持続的接続のサポート (初期値: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>&lt;n&gt; 個のネットワークメッセージごとにひとつをランダムに捨てる</translation>
- </message>
- <message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>&lt;n&gt;個のネットワークメッセージごとにひとつをランダムに改変する</translation>
- </message>
- <message>
<source>Rebuild block chain index from current blk000??.dat files on startup</source>
<translation>起動時に現在の blk000??.dat ファイルからブロック チェーンのインデックスを再構築</translation>
</message>
<message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>P2Pネットワークのアラートの受け取りと表示を行う (デフォルト: %u)</translation>
+ </message>
+ <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>トレース/デバッグ情報を debug.log ファイルの代わりにコンソールへ送る</translation>
</message>
@@ -3430,18 +3406,10 @@ rpcpassword=%s
<translation>(1 = トランザクションのメタデータ、例えばアカウントの所有者や支払リクエストの内容を保持する, 2 = トランザクションのメタデータを破棄する)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>&lt;n&gt; メガバイトごとにメモリプールからデータベースのアクティビティをディスクログに書き出す (初期値: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>-checkblocks のブロックの検証レベル (0-4, 初期値: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>ブロックの採掘時にトランザクションの優先度と1kBあたりの手数料をログに残す (デフォルト: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>getrawtransaction rpc 呼び出し時に用いる、完全なトランザクションインデックスを保持する (初期値: %u)</translation>
</message>
@@ -3470,18 +3438,10 @@ rpcpassword=%s
<translation>DNS ルックアップを通してピアアドレスを常に問い合わせる (初期値: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>セーフモードを無効化し、実際のセーフモードイベントも無効化する (初期値: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>wallet.dat 読み込みエラー</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>セーフモードを強制する (初期値: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>コインを生成 (初期値: %u)</translation>
</message>
@@ -3498,10 +3458,6 @@ rpcpassword=%s
<translation>無効な -proxy アドレス: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>署名キャッシュのサイズを &lt;n&gt; エントリーに制限する (デフォルト: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>&lt;port&gt; で JSON-RPC 接続をリスン (初期値: %u、testnet は %u)</translation>
</message>
@@ -3526,10 +3482,6 @@ rpcpassword=%s
<translation>接続毎の最大送信バッファ &lt;n&gt;*1000 バイト (初期値: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>内蔵のチェックポイントと一致するブロック チェーンのみを許可 (初期値: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>デバッグ出力にタイムスタンプを付ける (初期値: %u)</translation>
</message>
@@ -3542,10 +3494,6 @@ rpcpassword=%s
<translation>P2SHでないマルチシグトランザクションをリレーする (初期値: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>ウォレットを定期的に書き出すためのスレッドを走らせる (初期値: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>サーバ証明書ファイル (初期値: %s)</translation>
</message>
@@ -3566,10 +3514,6 @@ rpcpassword=%s
<translation>RPC サービスのスレッド数を設定 (初期値: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>ウォレットDB環境内にDB_PRIVATEフラグを設定する (デフォルト: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>設定ファイルの指定 (初期値: %s)</translation>
</message>
@@ -3586,10 +3530,6 @@ rpcpassword=%s
<translation>トランザクション送信時に未検証のおつりを使用する (デフォルト: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>ディスクからブロックを読み込んだ後に終了する (デフォルト: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>不正なピアを切断するためのしきい値 (初期値: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts
index b9e118a620..4c6ce13eff 100644
--- a/src/qt/locale/bitcoin_ka.ts
+++ b/src/qt/locale/bitcoin_ka.ts
@@ -1,4 +1,4 @@
-<TS language="ka" version="2.1">
+<TS language="ka" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -2215,10 +2215,6 @@
<translation>მოცემულ მისამართზე მიჯაჭვა მუდმივად მასზე მიყურადებით. გამოიყენეთ [host]:port ფორმა IPv6-სათვის</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>გადასვლა რეგრესული ტესტირების რეჟიმში, რომელიც იყენებს სპეციალურ ჯაჭვს ბლოკების დაუყოვნებლივი პოვნის შესაძლებლობით.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>კომანდის შესრულება საფულის ტრანსაქციის ცვლილებისას (%s კომანდაში ჩანაცვლდება TxID-ით)</translation>
</message>
@@ -2323,10 +2319,6 @@
<translation>მიუთითეთ საფულის ფაილი (კატალოგში)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>გამოიყენება რეგრესული ტესტირების ინსტრუმენტებისა და პროგრამების შემუშავებისას.</translation>
- </message>
- <message>
<source>Verifying blocks...</source>
<translation>ბლოკების ვერიფიკაცია...</translation>
</message>
diff --git a/src/qt/locale/bitcoin_kk_KZ.ts b/src/qt/locale/bitcoin_kk_KZ.ts
index 4cc709fdb2..5ee9040633 100644
--- a/src/qt/locale/bitcoin_kk_KZ.ts
+++ b/src/qt/locale/bitcoin_kk_KZ.ts
@@ -1,4 +1,4 @@
-<TS language="kk_KZ" version="2.1">
+<TS language="kk_KZ" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts
index 42eb9eedbb..5126e53f8e 100644
--- a/src/qt/locale/bitcoin_ko_KR.ts
+++ b/src/qt/locale/bitcoin_ko_KR.ts
@@ -1,7 +1,11 @@
-<TS language="ko_KR" version="2.1">
+<TS language="ko_KR" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
+ <source>Right-click to edit address or label</source>
+ <translation>지갑 주소나 이름을 수정하려면 우클릭하세요.</translation>
+ </message>
+ <message>
<source>Create a new address</source>
<translation>새 주소 만들기</translation>
</message>
@@ -89,7 +93,11 @@
<source>Exporting Failed</source>
<translation>내보내기 실패</translation>
</message>
- </context>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>%1으로 주소 리스트를 저장하는 동안 오류가 발생했습니다. 다시 시도해주세요.</translation>
+ </message>
+</context>
<context>
<name>AddressTableModel</name>
<message>
@@ -477,6 +485,10 @@
<context>
<name>CoinControlDialog</name>
<message>
+ <source>Coin Selection</source>
+ <translation>코인 선택</translation>
+ </message>
+ <message>
<source>Quantity:</source>
<translation>수량:</translation>
</message>
@@ -895,6 +907,14 @@
<translation>사용중인 UPnP 포트 매핑(&amp;U)</translation>
</message>
<message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>SOCKS5 프록시를 통해 비트코인 네트워크 연결</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>SOCKS5 프록시를 거쳐 연결합니다 (기본값 프록시):</translation>
+ </message>
+ <message>
<source>Proxy &amp;IP:</source>
<translation>프록시 IP(&amp;I):</translation>
</message>
@@ -1091,6 +1111,10 @@
<translation>거래량</translation>
</message>
<message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>비트코인 주소를 입력하기 (예. %1)</translation>
+ </message>
+ <message>
<source>N/A</source>
<translation>없음</translation>
</message>
@@ -2403,10 +2427,6 @@
<translation>RPC 서버 설정</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>모든 네트워크 메시지 마다 무작위로 1이 떨어진다</translation>
- </message>
- <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>추적오류 정보를 degug.log 자료로 보내는 대신 콘솔로 보내기</translation>
</message>
diff --git a/src/qt/locale/bitcoin_ky.ts b/src/qt/locale/bitcoin_ky.ts
index 8edee19c70..442d7c5d52 100644
--- a/src/qt/locale/bitcoin_ky.ts
+++ b/src/qt/locale/bitcoin_ky.ts
@@ -1,4 +1,4 @@
-<TS language="ky" version="2.1">
+<TS language="ky" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts
index 3e25cf95b6..b1a69c9a9e 100644
--- a/src/qt/locale/bitcoin_la.ts
+++ b/src/qt/locale/bitcoin_la.ts
@@ -1,4 +1,4 @@
-<TS language="la" version="2.1">
+<TS language="la" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_lt.ts b/src/qt/locale/bitcoin_lt.ts
index 01fa94bab3..4e468911dc 100644
--- a/src/qt/locale/bitcoin_lt.ts
+++ b/src/qt/locale/bitcoin_lt.ts
@@ -1,7 +1,11 @@
-<TS language="lt" version="2.1">
+<TS language="lt" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
+ <source>Right-click to edit address or label</source>
+ <translation>Spustelėkite dešinįjį klaviša norint keisti adresą arba etiketę</translation>
+ </message>
+ <message>
<source>Create a new address</source>
<translation>Sukurti naują adresą</translation>
</message>
@@ -26,6 +30,10 @@
<translation>&amp;Kopijuoti adresą</translation>
</message>
<message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Ištrinti pasirinktą adresą iš sąrašo</translation>
+ </message>
+ <message>
<source>&amp;Export</source>
<translation>&amp;Eksportuoti</translation>
</message>
@@ -34,6 +42,10 @@
<translation>&amp;Trinti</translation>
</message>
<message>
+ <source>Choose the address to send coins to</source>
+ <translation>Pasirinkite adresą kuriam siūsite monetas</translation>
+ </message>
+ <message>
<source>C&amp;hoose</source>
<translation>P&amp;asirinkti</translation>
</message>
@@ -247,6 +259,10 @@
<translation>&amp;Gaunami adresai...</translation>
</message>
<message>
+ <source>Open &amp;URI...</source>
+ <translation>Atidaryti &amp;URI...</translation>
+ </message>
+ <message>
<source>Bitcoin Core client</source>
<translation>Bitcoin Core klientas</translation>
</message>
@@ -385,6 +401,10 @@
<context>
<name>CoinControlDialog</name>
<message>
+ <source>Coin Selection</source>
+ <translation>Monetų pasirinkimas</translation>
+ </message>
+ <message>
<source>Quantity:</source>
<translation>Kiekis:</translation>
</message>
@@ -715,6 +735,10 @@
<translation>niekas</translation>
</message>
<message>
+ <source>Confirm options reset</source>
+ <translation>Patvirtinti nustatymų atstatymą</translation>
+ </message>
+ <message>
<source>The supplied proxy address is invalid.</source>
<translation>Nurodytas tarpinio serverio adresas negalioja.</translation>
</message>
@@ -726,6 +750,14 @@
<translation>Forma</translation>
</message>
<message>
+ <source>Available:</source>
+ <translation>Galimi:</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Laukiantys:</translation>
+ </message>
+ <message>
<source>Immature:</source>
<translation>Nepribrendę:</translation>
</message>
@@ -745,6 +777,10 @@
<translation>URI apdorojimas</translation>
</message>
<message>
+ <source>Payment request rejected</source>
+ <translation>Mokėjimo siuntimas atmestas</translation>
+ </message>
+ <message>
<source>Network request error</source>
<translation>Tinklo užklausos klaida</translation>
</message>
@@ -821,6 +857,26 @@
<translation>Dabartinis blokų skaičius</translation>
</message>
<message>
+ <source>Received</source>
+ <translation>Gauta</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Kryptis</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Versija</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Nusiųsti baitai</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Gauti baitai</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Paskutinio bloko laikas</translation>
</message>
@@ -864,6 +920,10 @@
<source>%1 GB</source>
<translation>%1 GB</translation>
</message>
+ <message>
+ <source>never</source>
+ <translation>Niekada</translation>
+ </message>
</context>
<context>
<name>ReceiveCoinsDialog</name>
@@ -872,6 +932,10 @@
<translation>Ž&amp;ymė:</translation>
</message>
<message>
+ <source>Clear</source>
+ <translation>Išvalyti</translation>
+ </message>
+ <message>
<source>Copy label</source>
<translation>Kopijuoti žymę</translation>
</message>
diff --git a/src/qt/locale/bitcoin_lv_LV.ts b/src/qt/locale/bitcoin_lv_LV.ts
index 25f92b6642..23b846bd49 100644
--- a/src/qt/locale/bitcoin_lv_LV.ts
+++ b/src/qt/locale/bitcoin_lv_LV.ts
@@ -1,4 +1,4 @@
-<TS language="lv_LV" version="2.1">
+<TS language="lv_LV" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_mn.ts b/src/qt/locale/bitcoin_mn.ts
index a1a07af8d5..73793482d6 100644
--- a/src/qt/locale/bitcoin_mn.ts
+++ b/src/qt/locale/bitcoin_mn.ts
@@ -1,4 +1,4 @@
-<TS language="mn" version="2.1">
+<TS language="mn" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -6,18 +6,66 @@
<translation>Шинэ хаяг нээх</translation>
</message>
<message>
+ <source>&amp;New</source>
+ <translation>&amp;Шинэ</translation>
+ </message>
+ <message>
<source>Copy the currently selected address to the system clipboard</source>
<translation>Одоогоор сонгогдсон байгаа хаягуудыг сануулах</translation>
</message>
<message>
+ <source>&amp;Copy</source>
+ <translation>&amp;Хуулах</translation>
+ </message>
+ <message>
+ <source>C&amp;lose</source>
+ <translation>&amp;Хаах</translation>
+ </message>
+ <message>
<source>&amp;Copy Address</source>
<translation>Хаягийг &amp;Хуулбарлах</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>&amp;Export</source>
+ <translation>&amp;Экспортдлох</translation>
+ </message>
+ <message>
<source>&amp;Delete</source>
<translation>&amp;Устгах</translation>
</message>
<message>
+ <source>Choose the address to send coins to</source>
+ <translation>Зооснуудыг илгээх хаягийг сонгоно уу</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>Зооснуудыг хүлээн авах хаягийг сонгоно уу</translation>
+ </message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>Илгээх хаягууд</translation>
+ </message>
+ <message>
+ <source>Receiving addresses</source>
+ <translation>Хүлээн авах хаяг</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Эдгээр Биткойн хаягууд нь илгээх хаягууд. Хүлээн авах хаяг болон тоо хэмжээг илгээхээсээ өмнө сайн нягталж үзэж байна уу</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Эдгээр Биткойн хаягууд нь хүлээн авах хаягууд. Гүйлгээ болгонд шинээр хаяг үүсгэхийг бид санал болгож байна.</translation>
+ </message>
+ <message>
<source>Copy &amp;Label</source>
<translation>&amp;Шошгыг хуулбарлах</translation>
</message>
@@ -26,6 +74,10 @@
<translation>&amp;Ѳѳрчлѳх</translation>
</message>
<message>
+ <source>Export Address List</source>
+ <translation>Экспорт хийх хаягуудын жагсаалт</translation>
+ </message>
+ <message>
<source>Comma separated file (*.csv)</source>
<translation>Таслалаар тусгаарлагдсан хүснэгтэн файл (.csv)</translation>
</message>
@@ -959,6 +1011,14 @@
</context>
<context>
<name>WalletView</name>
+ <message>
+ <source>&amp;Export</source>
+ <translation>&amp;Экспортдлох</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Сонгогдсон таб дээрхи дата-г экспортлох</translation>
+ </message>
</context>
<context>
<name>bitcoin-core</name>
diff --git a/src/qt/locale/bitcoin_ms_MY.ts b/src/qt/locale/bitcoin_ms_MY.ts
index 999961beb8..5e10c80aff 100644
--- a/src/qt/locale/bitcoin_ms_MY.ts
+++ b/src/qt/locale/bitcoin_ms_MY.ts
@@ -1,4 +1,4 @@
-<TS language="ms_MY" version="2.1">
+<TS language="ms_MY" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts
index 6e2b4e9fcc..385f038d46 100644
--- a/src/qt/locale/bitcoin_nb.ts
+++ b/src/qt/locale/bitcoin_nb.ts
@@ -1,4 +1,4 @@
-<TS language="nb" version="2.1">
+<TS language="nb" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -2817,10 +2817,6 @@
<translation>Bind til angitt adresse. Bruk [vertsmaskin]:port notasjon for IPv6</translation>
</message>
<message>
- <source>Continuously rate-limit free transactions to &lt;n&gt;*1000 bytes per minute (default: %u)</source>
- <translation>Ratebegrens gratistransaksjoner kontinuerlig til &lt;n&gt;*1000 bytes per minutt (standardverdi: %u)</translation>
- </message>
- <message>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Slett alle transaksjoner i lommeboken og gjenopprett kun de delene av blokkjeden gjennom -rescan ved oppstart</translation>
</message>
@@ -2829,18 +2825,10 @@
<translation>Distribuert under MIT programvarelisensen, se medfølgende fil COPYING eller &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Gå til modus for regresjonstesting, som bruker en spesiell blokkjede der blokker kan bli løst momentant.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Kjør kommando når en lommeboktransaksjon endres (%s i kommando er erstattet med TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>I denne modusen kontrollerer -genproclimit hvor mange blokker som genereres øyeblikkelig.</translation>
- </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>
@@ -2861,6 +2849,14 @@
<translation>Ute av stand til å binde til %s på denne datamaskinen. Bitcoin Core kjører sannsynligvis allerede.</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ADVARSEL: unormalt høyt antall blokker generert, %d blokker mottatt de siste %d timene (%d forventet)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ADVARSEL: kontroller nettverkstilkoblingen, mottok %d blokker i de siste %d timene (%d forventet)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Advarsel: -paytxfee er satt veldig høyt! Dette er transaksjonsgebyret du betaler når du sender transaksjoner.</translation>
</message>
@@ -2997,10 +2993,6 @@
<translation>Angi lommebokfil (inne i datamappe)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Dette er tiltenkt verktøy for regresjonstesting og apputvikling.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Bruk UPnP for å sette opp lytteport (standardverdi: %u)</translation>
</message>
@@ -3077,10 +3069,6 @@
<translation>Gebyrer (i BTC/Kb) mindre enn dette anses som null gebyr for videresending (standardverdi: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Gebyrer (i BTC/Kb) mindre enn dette anses som null gebyr for laging av transaksjoner (standardverdi: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Hvis paytxfee ikke er angitt, inkluderer da nok i gebyr til at transaksjoner gjennomsnittligt bekreftes innen n blokker (standardverdi: %u)</translation>
</message>
@@ -3105,10 +3093,6 @@
<translation>Bruk tilfeldig identitet for hver proxytilkobling. Dette muliggjør TOR stream isolasjon (standardverdi: %u)</translation>
</message>
<message>
- <source>Require high priority for relaying free or low-fee transactions (default: %u)</source>
- <translation>Krev høy prioritet for videresending av gratistransaksjoner eller transaksjoner med lavt gebyr (standardverdi: %u)</translation>
- </message>
- <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Sett maksimum størrelse for transaksjoner med høy prioritet / lavt gebyr, i bytes (standardverdi: %d)</translation>
</message>
@@ -3177,10 +3161,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Aktiverer beste kjede...</translation>
</message>
<message>
- <source>Allow self signed root certificates (default: 0)</source>
- <translation>Tillat selvsignerte rotsertifikater (standardverdi: 0)</translation>
- </message>
- <message>
<source>Can't run with a wallet in prune mode.</source>
<translation>Kan ikke kjøre med en lommebok i beskjæringsmodus.</translation>
</message>
@@ -3273,18 +3253,14 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>RPC-støtte for persistente HTTP-forbindelser (standardverdi: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Slumpvis dropp 1 av hver &lt;n&gt; nettverksmeldinger</translation>
- </message>
- <message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Slumpvis bland 1 av hver &lt;n&gt; nettverksmeldinger</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>
<message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Motta og vis P2P nettverksvarsler (standardvalg: %u)</translation>
+ </message>
+ <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Send spor-/feilsøkingsinformasjon til konsollen istedenfor filen debug.log</translation>
</message>
@@ -3429,18 +3405,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>(1 = behold metadata for transaksjon som f. eks. kontoeier og informasjon om betalingsanmodning, 2 = dropp metadata for transaksjon)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Overfør aktiviteten i databasen fra minnelageret til loggen på harddisken for hver &lt;n&gt; megabytes (standardverdi: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Hvor grundig blokkverifiseringen til -checkblocks er (0-4, standardverdi: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Logg transaksjonsprioritet og gebyr per kB under blokkutvinning (standardverdi: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Oppretthold en full transaksjonsindeks, brukt av getrawtransaction RPC-kall (standardverdi: %u)</translation>
</message>
@@ -3469,18 +3437,10 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Alltid søk etter nodeadresser via DNS-oppslag (standardverdi: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Slå av sikkerhetsmodus, overstyr en virkelig sikkerhetsmodushendelse (standardverdi: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>Feil ved lasting av wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Tving sikkerhetsmodus (standardverdi: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Generer mynter (standardverdi: %u)</translation>
</message>
@@ -3497,10 +3457,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Ugyldig -proxy adresse: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Begrens størrelsen på hurtigbufferen for signaturer til &lt;n&gt; oppføringer (standardverdi: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Lytt etter JSON-RPC tilkoblinger på &lt;port&gt; (standardverdi: %u eller testnett: %u)</translation>
</message>
@@ -3525,10 +3481,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Maks sendebuffer per forbindelse, &lt;n&gt;*1000 bytes (standardverdi: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Aksepter kun blokkjeden som stemmer med innebygde sjekkpunkter (standardvalg: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Sett inn tidsstempel i front av feilsøkingsdata (standardverdi: %u)</translation>
</message>
@@ -3541,10 +3493,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Videresend ikke-P2SH multisig (standardverdi: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Kjør en tråd som skriver lommeboken til disk periodisk (standardverdi: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>Fil for tjenersertifikat (standardverdi: %s)</translation>
</message>
@@ -3565,10 +3513,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Sett antall tråder til betjening av RPC-kall (standardverdi: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Setter flagget DB_PRIVATE i miljøet til lommebokdatabasen (standardverdi: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Angi konfigurasjonsfil (standardverdi: %s)</translation>
</message>
@@ -3585,10 +3529,6 @@ for eksempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Bruk ubekreftet veksel ved sending av transaksjoner (standardverdi: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Avslutt etter import av blokker fra disk (standardverdi: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Grenseverdi for å koble fra noder med dårlig oppførsel (standardverdi: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts
index 385972845a..7999e263e4 100644
--- a/src/qt/locale/bitcoin_nl.ts
+++ b/src/qt/locale/bitcoin_nl.ts
@@ -1,4 +1,4 @@
-<TS language="nl" version="2.1">
+<TS language="nl" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -399,6 +399,10 @@
<translation>&amp;Over Bitcoin Core</translation>
</message>
<message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Wijzig configuratieopties voor Bitcoin Core</translation>
+ </message>
+ <message>
<source>Show the list of used sending addresses and labels</source>
<translation>Toon de lijst met gebruikt verzend adressen en labels</translation>
</message>
@@ -973,6 +977,10 @@
<translation>IP-adres van de proxy (bijv. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
</message>
<message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimaliseren in plaats van de applicatie af te sluiten wanneer het venster is afgesloten. Als deze optie is ingeschakeld, zal de toepassing pas worden afgesloten na het selecteren van Exit in het menu.</translation>
+ </message>
+ <message>
<source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
<translation>Stel hier de taal van de applicatie in. Deze instelling zal van kracht worden na het herstarten van de applicatie.</translation>
</message>
@@ -1259,10 +1267,18 @@
<translation>Betalingsverzoek-bestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoek-bestand.</translation>
</message>
<message>
+ <source>Payment request expired.</source>
+ <translation>Betalingsverzoek verlopen.</translation>
+ </message>
+ <message>
<source>Unverified payment requests to custom payment scripts are unsupported.</source>
<translation>Niet-geverifieerde betalingsverzoeken naar aangepaste betaling scripts worden niet ondersteund.</translation>
</message>
<message>
+ <source>Invalid payment request.</source>
+ <translation>Ongeldig betalingsverzoek.</translation>
+ </message>
+ <message>
<source>Refund from %1</source>
<translation>Restitutie van %1</translation>
</message>
@@ -1423,6 +1439,10 @@
<translation>Huidig aantal blokken</translation>
</message>
<message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Open het Bitcoin Core debug logbestand van de huidige gegevens directory. Dit kan enkele seconden duren voor grote logbestanden.</translation>
+ </message>
+ <message>
<source>Received</source>
<translation>Ontvangen</translation>
</message>
@@ -1535,6 +1555,10 @@
<translation>Maak console leeg</translation>
</message>
<message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Welkom op de Bitcoin Core RPC console.</translation>
+ </message>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
<translation>Gebruik de pijltjestoetsen om door de geschiedenis te navigeren, en &lt;b&gt;Ctrl-L&lt;/b&gt; om het scherm leeg te maken.</translation>
</message>
@@ -1831,6 +1855,10 @@
<translation>Als de aangepaste toeslag is ingesteld op 1000 satoshis en de transactie is maar 250 bytes, dan wordt bij "per kilobyte" 250 satoshis aan toeslag berekend, terwijl er bij "totaal tenminste" 1000 satoshis worden berekend. Voor transacties die groter zijn dan een kilobyte, wordt in beide gevallen per kilobyte de toeslag berekend.</translation>
</message>
<message>
+ <source>Hide</source>
+ <translation>Verbergen</translation>
+ </message>
+ <message>
<source>total at least</source>
<translation>totaal ten minste</translation>
</message>
@@ -1971,10 +1999,22 @@
<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>Payment request expired.</source>
+ <translation>Betalingsverzoek verlopen.</translation>
+ </message>
+ <message>
<source>Pay only the minimum fee of %1</source>
<translation>Betaal alleen de minimale transactiekosten van %1</translation>
</message>
<message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Het adres van de ontvanger is niet geldig. Gelieve opnieuw te controleren..</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Dubbel adres gevonden: adressen mogen maar één keer worden gebruikt worden.</translation>
+ </message>
+ <message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Waarschuwing: Ongeldig Bitcoin adres</translation>
</message>
@@ -2050,6 +2090,14 @@
<translation>Bericht:</translation>
</message>
<message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Dit is een niet-geverifieerd betalingsverzoek.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Dit is een geverifieerd betalingsverzoek.</translation>
+ </message>
+ <message>
<source>Enter a label for this address to add it to the list of used addresses</source>
<translation>Vul een label voor dit adres in om het aan de lijst met gebruikte adressen toe te voegen</translation>
</message>
@@ -2088,6 +2136,10 @@
<translation>O&amp;nderteken 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>
+ </message>
+ <message>
<source>The Bitcoin address to sign the message with</source>
<translation>Het Bitcoin adres om bericht mee te ondertekenen</translation>
</message>
@@ -2741,18 +2793,10 @@
<translation>Uitgegeven onder de MIT software licentie, zie het bijgevoegde bestand COPYING of &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Schakel regressietest-modus in, die een speciale blokketen gebruikt waarin blokken onmiddellijk opgelost kunnen worden.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Voer opdracht uit zodra een portemonneetransactie verandert (%s in cmd wordt vervangen door TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>In deze modus, -genproclimit controleert hoeveel blokken er onmiddellijk worden gegenereerd.</translation>
- </message>
- <message>
<source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
<translation>Kies het aantal script verificatie processen (%u tot %d, 0 = auto, &lt;0 = laat dit aantal kernen vrij, standaard: %d)</translation>
</message>
@@ -2765,6 +2809,10 @@
<translation>Niet in staat om %s te verbinden op deze computer. Bitcoin Core draait waarschijnlijk al.</translation>
</message>
<message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>WAARSCHUWING: controleer uw netwerkverbinding, %d blokken ontvangen in de laatste %d uren (%d verwacht)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Waarschuwing: -paytxfee is zeer hoog ingesteld. Dit zijn de transactiekosten die u betaalt bij het versturen van een transactie.</translation>
</message>
@@ -2893,10 +2941,6 @@
<translation>Specificeer het portemonnee bestand (vanuit de gegevensmap)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Dit is bedoeld voor regressie test toepassingen en applicatie onwikkeling.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Gebruik UPnP om de luisterende poort te mappen (standaard: %u)</translation>
</message>
@@ -2917,6 +2961,10 @@
<translation>Portemonnee instellingen:</translation>
</message>
<message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Waarschuwing: Deze versie is verouderd; upgraden verplicht!</translation>
+ </message>
+ <message>
<source>You need to rebuild the database using -reindex to change -txindex</source>
<translation>Om -txindex te kunnen veranderen dient u de database opnieuw te bouwen met gebruik van -reindex.</translation>
</message>
@@ -2965,10 +3013,6 @@
<translation>Toeslagen (in BTC/Kb) kleiner dan dit worden beschouwd als geen vergoeding (voor doorgeven) (standaard: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Toeslagen (in BTC/Kb) kleiner dan dit worden beschouwd als geen vergoeding transactieaanmaak (standaard: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Als paytxfee niet is ingesteld, het pakket voldoende vergoeding zodat transacties beginnen bevestiging gemiddeld binnen in blokken (default: %u)</translation>
</message>
@@ -2994,10 +3038,37 @@
<translation>Stel het aantal threads in voor het genereren van coins indien ingesteld (-1 = alle kernen, standaard: %d)</translation>
</message>
<message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Het transactiebedrag is te klein om te versturen nadat de vergoeding in mindering is gebracht</translation>
+ </message>
+ <message>
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; 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 &lt;https://www.openssl.org/&gt; 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>
@@ -3010,10 +3081,18 @@
<translation>Goedgekeurde peers kunnen niet ge-DoS-banned worden en hun transacties worden altijd doorgestuurd, zelfs als ze reeds in de mempool aanwezig zijn, nuttig voor bijv. een gateway</translation>
</message>
<message>
+ <source>(default: %u)</source>
+ <translation>(standaard: %u)</translation>
+ </message>
+ <message>
<source>Accept public REST requests (default: %u)</source>
<translation>Accepteer publieke REST-requests (standaard: %u)</translation>
</message>
<message>
+ <source>Activating best chain...</source>
+ <translation>Beste reeks activeren...</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>Kan -whitebind adres niet herleiden: '%s'</translation>
</message>
@@ -3102,14 +3181,6 @@
<translation>RPC ondersteuning voor HTTP persisten verbindingen (default: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Laat willekeurig 1 elke &lt;n&gt; netwerkberichten vallen</translation>
- </message>
- <message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Fuzz willekeurig 1 van elke &lt;n&gt; netwerkberichten</translation>
- </message>
- <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Stuur trace/debug-info naar de console in plaats van het debug.log bestand</translation>
</message>
@@ -3146,6 +3217,10 @@
<translation>Geminimaliseerd starten</translation>
</message>
<message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Het transactiebedrag is te klein om de vergoeding te betalen</translation>
+ </message>
+ <message>
<source>This is experimental software.</source>
<translation>Dit is experimentele software.</translation>
</message>
@@ -3166,6 +3241,10 @@
<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>
@@ -3246,18 +3325,10 @@
<translation>(1 = behoudt tx meta data bijv. account eigenaar en betalingsverzoek informatie, 2. sla tx meta data niet op)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Leeg database-activiteit uit de geheugen pool naar schijf log elke &lt;n&gt; megabytes (standaard: %u) </translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Hoe grondig de blokverificatie van -checkblocks is (0-4, standaard: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Log transactieprioriteit en -kosten per kB bij het mijnen van blokken (standaard: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Onderhoud een volledige transactieindex, gebruikt door de getrawtransaction rpc call (standaard: %u)</translation>
</message>
@@ -3282,18 +3353,10 @@
<translation>Vind anderen door middel van een DNS-naslag (standaard: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Veilige modus uitschakelen, hef een echte veilige modus gebeurtenis uit (default: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>Fout bij laden wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Forceer veilige modus (default: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Genereer munten (standaard: %u)</translation>
</message>
@@ -3310,10 +3373,6 @@
<translation>Ongeldig -proxy adres: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Limiteer grootte van de handtekening cache tot &lt;n&gt; entries (default: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Luister naar JSON-RPC-verbindingen op poort &lt;port&gt; (standaard: %u of testnet: %u)</translation>
</message>
@@ -3326,6 +3385,10 @@
<translation>Onderhoud maximaal &lt;n&gt; verbindingen naar peers (standaard: %u)</translation>
</message>
<message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Laat de portemonnee transacties uitsturen</translation>
+ </message>
+ <message>
<source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
<translation>Maximum per-connectie ontvangstbuffer, &lt;n&gt;*1000 bytes (standaard: %u)</translation>
</message>
@@ -3334,10 +3397,6 @@
<translation>Maximum per-connectie zendbuffer, &lt;n&gt;*1000 bytes (standaard: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Accepteer alleen blokkenketen die overeenkomt met de ingebouwde checkpoints (standaard: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Prepend debug output met tijdstempel (standaard: %u)</translation>
</message>
@@ -3350,10 +3409,6 @@
<translation>Relay non-P2SH multisig (default: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Draai een proces om de wallet periodiek te flushen (default: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>Certificaat-bestand voor server (standaard: %s)</translation>
</message>
@@ -3374,10 +3429,6 @@
<translation>Stel het aantal threads in om RPC-aanvragen mee te bedienen (standaard: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Plaatst de DB_PRIVATE vlag in de wallet db omgeving (default: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Specificeer configuratie bestand (standaard: %s)</translation>
</message>
@@ -3394,10 +3445,6 @@
<translation>Besteed onbevestigd wisselgeld bij het versturen van transacties (standaard: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Stop uitvoeren na het importeren van blokken van de schijf (standaard: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Drempel om verbinding te verbreken naar zich misdragende peers (standaard: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_pam.ts b/src/qt/locale/bitcoin_pam.ts
index 54c30dfb6f..4939dff4b0 100644
--- a/src/qt/locale/bitcoin_pam.ts
+++ b/src/qt/locale/bitcoin_pam.ts
@@ -1,7 +1,11 @@
-<TS language="pam" version="2.1">
+<TS language="pam" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
+ <source>Right-click to edit address or label</source>
+ <translation>I-right click ban alilan ing address o libel</translation>
+ </message>
+ <message>
<source>Create a new address</source>
<translation>Maglalang kang bayung address</translation>
</message>
diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts
index db49e20cf1..5bc7df0aca 100644
--- a/src/qt/locale/bitcoin_pl.ts
+++ b/src/qt/locale/bitcoin_pl.ts
@@ -1,4 +1,4 @@
-<TS language="pl" version="2.1">
+<TS language="pl" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -168,6 +168,10 @@
<translation>Jesteś pewien, że chcesz zaszyfrować swój portfel?</translation>
</message>
<message>
+ <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>Program Bitcoin Core zamknie się, aby dokończyć proces szyfrowania. Pamiętaj, że szyfrowanie portfela nie zabezpiecza w pełni Twoich bitcoinów przed kradzieżą przez wirusy lub trojany mogące zainfekować Twój komputer.</translation>
+ </message>
+ <message>
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
<translation>WAŻNE: Wszystkie wykonane wcześniej kopie pliku portfela powinny być zamienione na nowe, szyfrowane pliki. Z powodów bezpieczeństwa, poprzednie kopie nieszyfrowanych plików portfela staną się bezużyteczne jak tylko zaczniesz korzystać z nowego, szyfrowanego portfela.</translation>
</message>
@@ -184,6 +188,10 @@
<translation>Wprowadź nowe hasło do portfela.&lt;br/&gt;Proszę używać hasła złożonego z &lt;b&gt;10 lub więcej losowych znaków&lt;/b&gt; lub &lt;b&gt;ośmiu lub więcej słów.&lt;/b&gt;</translation>
</message>
<message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Podaj stare i nowe hasło do portfela.</translation>
+ </message>
+ <message>
<source>Wallet encryption failed</source>
<translation>Szyfrowanie portfela nie powiodło się</translation>
</message>
@@ -391,6 +399,10 @@
<translation>&amp;O Bitcoin Core</translation>
</message>
<message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Zmień opcje konfiguracji dla Bitcoin Core</translation>
+ </message>
+ <message>
<source>Show the list of used sending addresses and labels</source>
<translation>Pokaż listę adresów i etykiet użytych do wysyłania</translation>
</message>
@@ -410,14 +422,34 @@
<source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
<translation>Pokaż pomoc Rdzenia Bitcoin, aby zobaczyć listę wszystkich opcji linii poleceń</translation>
</message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktywnych połączeń do sieci Bitcoin</numerusform><numerusform>%n aktywnych połączeń do sieci Bitcoin</numerusform><numerusform>%n aktywnych połączeń do sieci Bitcoin</numerusform></translation>
+ </message>
<message>
<source>No block source available...</source>
<translation>Brak dostępnych źródeł bloków...</translation>
</message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Przetworzono %n bloków historii transakcji.</numerusform><numerusform>Przetworzono %n bloków historii transakcji.</numerusform><numerusform>Przetworzono %n bloków historii transakcji.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n godzin</numerusform><numerusform>%n godzin</numerusform><numerusform>%n godzin</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n tygodni</numerusform><numerusform>%n tygodni</numerusform><numerusform>%n tygodni</numerusform></translation>
+ </message>
<message>
<source>%1 and %2</source>
<translation>%1 i %2</translation>
</message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n lat</numerusform><numerusform>%n lat</numerusform><numerusform>%n lat</numerusform></translation>
+ </message>
<message>
<source>%1 behind</source>
<translation>%1 wstecz</translation>
@@ -451,6 +483,36 @@
<translation>Synchronizuję się...</translation>
</message>
<message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Kwota: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Typ: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Etykieta: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adres: %1
+</translation>
+ </message>
+ <message>
<source>Sent transaction</source>
<translation>Transakcja wysłana</translation>
</message>
@@ -649,6 +711,18 @@
<translation>żaden</translation>
</message>
<message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Ta etykieta staje się czerwona, kiedy transakcja jest większa niż 1000 bajtów.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Ta etykieta jest czerwona, jeżeli priorytet jest mniejszy niż "średni"</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Etykieta staje się czerwona kiedy którykolwiek odbiorca otrzymuje kwotę mniejszą niż %1.</translation>
+ </message>
+ <message>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation>Waha się +/- %1 satoshi na wejście.</translation>
</message>
@@ -832,7 +906,15 @@
<source>Error</source>
<translation>Błąd</translation>
</message>
- </context>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB dostępnego wolnego miejsca</numerusform><numerusform>%n GB dostępnego wolnego miejsca</numerusform><numerusform>%n GB dostępnego wolnego miejsca</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(z %n GB potrzebnych)</numerusform><numerusform>(z %n GB potrzebnych)</numerusform><numerusform>(z %n GB potrzebnych)</numerusform></translation>
+ </message>
+</context>
<context>
<name>OpenURIDialog</name>
<message>
@@ -891,6 +973,22 @@
<translation>Adres IP serwera proxy (np. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
</message>
<message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimalizuje zamiast zakończyć działanie programu przy zamykaniu okna. Kiedy ta opcja jest włączona, program zakończy działanie po wybieraniu Zamknij w menu.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Można tu ustawić język interfejsu uzytkownika. Żeby ustawienie przyniosło skutek trzeba uruchomić ponownie Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Zewnętrzne URL podglądu transakcji (np. eksplorator bloków), które będą wyświetlały się w menu kontekstowym, w zakładce transakcji. %s będzie zamieniany w adresie na hash transakcji. Oddziel wiele adresów pionową kreską |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Zewnętrzny URL podglądu transakcji</translation>
+ </message>
+ <message>
<source>Active command-line options that override above options:</source>
<translation>Aktywne opcje linii komend, które nadpisują powyższe opcje:</translation>
</message>
@@ -907,6 +1005,14 @@
<translation>&amp;Sieć</translation>
</message>
<message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Automatycznie uruchamia Bitcoin po zalogowaniu do systemu.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>Uruchamiaj Bitcoin wraz z zalogowaniem do &amp;systemu</translation>
+ </message>
+ <message>
<source>(0 = auto, &lt;0 = leave that many cores free)</source>
<translation>(0 = automatycznie, &lt;0 = zostaw tyle wolnych rdzeni)</translation>
</message>
@@ -923,6 +1029,10 @@
<translation>Włącz funk&amp;cje kontoli monet</translation>
</message>
<message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Jeżeli wyłączysz możliwość wydania niezatwierdzonej wydanej reszty, reszta z transakcji nie będzie mogła zostać wykorzystana, dopóki ta transakcja nie będzie miała przynajmniej jednego potwierdzenia. To także ma wpływ na obliczanie Twojego salda.</translation>
+ </message>
+ <message>
<source>&amp;Spend unconfirmed change</source>
<translation>Wydaj niepotwierdzoną re&amp;sztę</translation>
</message>
@@ -1015,6 +1125,10 @@
<translation>Wymagany restart programu, aby uaktywnić zmiany.</translation>
</message>
<message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Program zostanie wyłączony. Czy chcesz kontynuować?</translation>
+ </message>
+ <message>
<source>This change would require a client restart.</source>
<translation>Ta zmiana może wymagać ponownego uruchomienia klienta.</translation>
</message>
@@ -1137,14 +1251,50 @@
<translation>URL pobrania żądania zapłaty jest nieprawidłowe: %1</translation>
</message>
<message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI nie może zostać przetworzony! Może to być spowodowane nieprawidłowym adresem Bitcoin lub uszkodzonymi parametrami URI.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Przechwytywanie plików żądania płatności</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Plików żądania płatności nie może zostać odczytany. Mogło to być spowodowane nieprawidłowym plikiem żądania płatności.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Żądanie płatności upłynęło.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Niezweryfikowane żądania płatności do własnych skryptów płatności są niewspierane.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Nieprawidłowe żądanie płatności</translation>
+ </message>
+ <message>
<source>Refund from %1</source>
<translation>Zwrot z %1</translation>
</message>
<message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Żądanie płatności %1 jest zbyt duże (%2 bajtów, dozwolone %3 bajtów).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Zabezpieczenie żądania płatności przed atakiem DoS</translation>
+ </message>
+ <message>
<source>Error communicating with %1: %2</source>
<translation>Błąd komunikacji z %1 : %2</translation>
</message>
<message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Żądanie płatności nie może zostać przetworzone.</translation>
+ </message>
+ <message>
<source>Bad response from server %1</source>
<translation>Błędna odpowiedź z serwera %1</translation>
</message>
@@ -1160,6 +1310,14 @@
<context>
<name>PeerTableModel</name>
<message>
+ <source>User Agent</source>
+ <translation>Aplikacja kliencka</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Węzeł/Usługi</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Czas odpowiedzi</translation>
</message>
@@ -1281,6 +1439,10 @@
<translation>Aktualna liczba bloków</translation>
</message>
<message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Otwórz plik logowania debugowania Bitcoin Core z obecnego katalogu z danymi. Może to potrwać kilka sekund przy większych plikach.</translation>
+ </message>
+ <message>
<source>Received</source>
<translation>Otrzymane</translation>
</message>
@@ -1289,6 +1451,10 @@
<translation>Wysłane</translation>
</message>
<message>
+ <source>&amp;Peers</source>
+ <translation>&amp;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>
@@ -1301,6 +1467,10 @@
<translation>Wersja</translation>
</message>
<message>
+ <source>User Agent</source>
+ <translation>Aplikacja kliencka</translation>
+ </message>
+ <message>
<source>Services</source>
<translation>Usługi</translation>
</message>
@@ -1309,10 +1479,26 @@
<translation>Początkowa wysokość</translation>
</message>
<message>
+ <source>Sync Height</source>
+ <translation>Zsynchronizowana wysokość</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Punkty karne</translation>
+ </message>
+ <message>
<source>Connection Time</source>
<translation>Czas połączenia</translation>
</message>
<message>
+ <source>Last Send</source>
+ <translation>Ostatnio wysłano</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Ostatnio odebrano</translation>
+ </message>
+ <message>
<source>Bytes Sent</source>
<translation>Bajtów wysłano</translation>
</message>
@@ -1325,6 +1511,10 @@
<translation>Czas odpowiedzi</translation>
</message>
<message>
+ <source>Time Offset</source>
+ <translation>Przesunięcie czasu</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Czas ostatniego bloku</translation>
</message>
@@ -1369,6 +1559,10 @@
<translation>Wyczyść konsolę</translation>
</message>
<message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Witaj w konsoli Bitcoin Core RPC.</translation>
+ </message>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
<translation>Użyj strzałek do przewijania historii i &lt;b&gt;Ctrl-L&lt;/b&gt; aby wyczyścić ekran</translation>
</message>
@@ -1436,6 +1630,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>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Opcjonalna wiadomość do dołączenia do żądania płatności, która będzie wyświetlana, gdy żądanie zostanie otwarte. Uwaga: wiadomość ta nie zostanie wysłana wraz z płatnością w sieci Bitcoin.</translation>
+ </message>
+ <message>
<source>An optional label to associate with the new receiving address.</source>
<translation>Opcjonalna etykieta do skojarzenia z nowym adresem odbiorczym.</translation>
</message>
@@ -1653,6 +1851,22 @@
<translation>za kilobajt</translation>
</message>
<message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Jeżeli własna opłata zostanie ustawiona na 1000 satoshi, a transakcja będzie miała tylko 250 bajtów, to "za kilobajt" płaci tylko 250 satoshi, podczas gdy, "razem przynajmniej" płaci 1000 satoshi. Przy transakcjach większych niż kilobajt, w obu przypadkach płaci za każdy kilobajt.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Ukryj</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>razem przynajmniej</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Zapłacenie tylko minimalnej opłaty jest nadal wystarczające, dopóki jest mniejszy wolumen transakcji niż miejsca w blokach. Należy jednak mieć świadomość, że może skończyć się to niezatwierdzeniem nigdy transakcji, gdy jest większe zapotrzebowanie na transakcje bitcoina niż sieć może przetworzyć.</translation>
+ </message>
+ <message>
<source>(read the tooltip)</source>
<translation>(przeczytaj podpowiedź)</translation>
</message>
@@ -1661,6 +1875,10 @@
<translation>Zalecane:</translation>
</message>
<message>
+ <source>Custom:</source>
+ <translation>Własna:</translation>
+ </message>
+ <message>
<source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
<translation>(Sprytne opłaty nie są jeszcze zainicjowane. Trwa to zwykle kilka bloków...)</translation>
</message>
@@ -1781,10 +1999,30 @@
<translation>Transakcja została odrzucona! Może się to zdarzyć jeśli część monet z portfela została już wydana używając kopii pliku wallet.dat i nie zostało to tutaj uwzględnione.</translation>
</message>
<message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Opłata wyższa niż %1 jest uważana za szalenie wysoką.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Żądanie płatności upłynęło.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform><numerusform>Przybliżony czas zatwierdzenia: %n bloków.</numerusform></translation>
+ </message>
+ <message>
<source>Pay only the minimum fee of %1</source>
<translation>Płac tylko minimalna opłatę %1</translation>
</message>
<message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Adres odbiorcy jest nieprawidłowy, proszę sprawić ponownie.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Znaleziono powtórzony adres, można wysłać tylko raz na każdy adres podczas jednej operacji wysyłania.</translation>
+ </message>
+ <message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Ostrzeżenie: nieprawidłowy adres Bitcoin</translation>
</message>
@@ -1836,6 +2074,10 @@
<translation>To jest standardowa płatność</translation>
</message>
<message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Adres Bitcoin gdzie wysłać płatność</translation>
+ </message>
+ <message>
<source>Alt+A</source>
<translation>Alt+A</translation>
</message>
@@ -1852,14 +2094,34 @@
<translation>Usuń ten wpis</translation>
</message>
<message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Opłata zostanie odjęta od kwoty wysyłane.Odbiorca otrzyma mniej niż bitcoins wpisz w polu kwoty. Jeśli wybrano kilku odbiorców, opłata jest podzielona równo.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>Odejmij od wysokości opłaty</translation>
+ </message>
+ <message>
<source>Message:</source>
<translation>Wiadomość:</translation>
</message>
<message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>To żądanie zapłaty nie zostało zweryfikowane.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>To żądanie zapłaty jest zweryfikowane.</translation>
+ </message>
+ <message>
<source>Enter a label for this address to add it to the list of used addresses</source>
<translation>Wprowadź etykietę dla tego adresu by dodać go do listy użytych adresów</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>Wiadomość, która została dołączona do URI bitcoin:, która będzie przechowywana wraz z transakcją w celach informacyjnych. Uwaga: Ta wiadomość nie będzie rozsyłana w sieci Bitcoin.</translation>
+ </message>
+ <message>
<source>Pay To:</source>
<translation>Wpłać do:</translation>
</message>
@@ -1890,6 +2152,14 @@
<translation>Podpi&amp;sz Wiadomość</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>Możesz podpisywać wiadomości swoimi adresami aby udowodnić, że jesteś ich właścicielem. Uważaj, aby nie podpisywać niczego co wzbudza Twoje podejrzenia, ponieważ ktoś może stosować phishing próbując nakłonić Cię do ich podpisania. Akceptuj i podpisuj tylko w pełni zrozumiałe komunikaty i wiadomości.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Adres Bitcoin, za pomocą którego podpisać wiadomość</translation>
+ </message>
+ <message>
<source>Choose previously used address</source>
<translation>Wybierz wcześniej użyty adres</translation>
</message>
@@ -1938,6 +2208,10 @@
<translation>&amp;Zweryfikuj wiadomość</translation>
</message>
<message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Adres Bitcoin, którym została podpisana wiadomość</translation>
+ </message>
+ <message>
<source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
<translation>Zweryfikuj wiadomość, aby upewnić się, że została podpisana odpowiednim adresem Bitcoin.</translation>
</message>
@@ -2050,6 +2324,10 @@
<source>Status</source>
<translation>Status</translation>
</message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, przekazywany przez %n węzłów</numerusform><numerusform>, przekazywany przez %n węzłów</numerusform><numerusform>, przekazywany przez %n węzłów</numerusform></translation>
+ </message>
<message>
<source>Date</source>
<translation>Data</translation>
@@ -2075,6 +2353,10 @@
<translation>własny adres</translation>
</message>
<message>
+ <source>watch-only</source>
+ <translation>tylko-obserwowany</translation>
+ </message>
+ <message>
<source>label</source>
<translation>etykieta</translation>
</message>
@@ -2082,6 +2364,10 @@
<source>Credit</source>
<translation>Przypisy</translation>
</message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>potwierdzona przy %n blokach więcej</numerusform><numerusform>potwierdzona przy %n blokach więcej</numerusform><numerusform>potwierdzona przy %n blokach więcej</numerusform></translation>
+ </message>
<message>
<source>not accepted</source>
<translation>niezaakceptowane</translation>
@@ -2091,6 +2377,14 @@
<translation>Debet</translation>
</message>
<message>
+ <source>Total debit</source>
+ <translation>Razem wychodzących</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Razem przychodzących</translation>
+ </message>
+ <message>
<source>Transaction fee</source>
<translation>Opłata transakcyjna</translation>
</message>
@@ -2146,6 +2440,10 @@
<source>, has not been successfully broadcast yet</source>
<translation>, nie został jeszcze pomyślnie rozesłany</translation>
</message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform></translation>
+ </message>
<message>
<source>unknown</source>
<translation>nieznany</translation>
@@ -2176,6 +2474,10 @@
<source>Immature (%1 confirmations, will be available after %2)</source>
<translation>Niedojrzała (%1 potwierdzeń, będzie dostępna po %2)</translation>
</message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform><numerusform>Otwórz dla %n następnych bloków</numerusform></translation>
+ </message>
<message>
<source>Open until %1</source>
<translation>Otwórz do %1</translation>
@@ -2233,6 +2535,10 @@
<translation>Wydobyto</translation>
</message>
<message>
+ <source>watch-only</source>
+ <translation>tylko-obserwowany</translation>
+ </message>
+ <message>
<source>(n/a)</source>
<translation>(brak)</translation>
</message>
@@ -2249,6 +2555,14 @@
<translation>Rodzaj transakcji.</translation>
</message>
<message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Czy adres tylko-obserwowany jest lub nie użyty w tej transakcji.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Zdefiniowana przez użytkownika intencja/cel transakcji.</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
<translation>Kwota usunięta z lub dodana do konta.</translation>
</message>
@@ -2340,6 +2654,10 @@
<translation>Eksport historii transakcji</translation>
</message>
<message>
+ <source>Watch-only</source>
+ <translation>Tylko obserwowany</translation>
+ </message>
+ <message>
<source>Exporting Failed</source>
<translation>Błąd przy próbie eksportu</translation>
</message>
@@ -2487,6 +2805,14 @@
<translation>Skojarz z podanym adresem i nasłuchuj na nim. Użyj formatu [host]:port dla IPv6</translation>
</message>
<message>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Usuwa wszystkie transakcje w portfelu i tylko odtwarza te części z łańcucha bloków poprzez -rescan przy starcie</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Rozprowadzane na licencji MIT, zobacz dołączony plik COPYING lub &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Wykonaj polecenie, kiedy transakcja portfela ulegnie zmianie (%s w poleceniu zostanie zastąpione przez TxID)</translation>
</message>
@@ -2523,6 +2849,10 @@
<translation>Ostrzeżenie: Odtworzono dane z uszkodzonego pliku wallet.dat! Oryginalny wallet.dat został zapisany jako wallet.{timestamp}.bak w %s; jeśli twoje saldo lub transakcje są niepoprawne powinieneś odtworzyć kopię zapasową.</translation>
</message>
<message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Dodawaj do białej listy węzły łączące się z podanej maski sieciowej lub adresu IP. Może być określona kilka razy.</translation>
+ </message>
+ <message>
<source>(default: 1)</source>
<translation>(domyślnie: 1)</translation>
</message>
@@ -2591,6 +2921,10 @@
<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 &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Jeżeli &lt;category&gt; nie zostanie określona, wyświetl wszystkie informacje debugowania.</translation>
+ </message>
+ <message>
<source>Importing...</source>
<translation>Importowanie…</translation>
</message>
@@ -2611,6 +2945,10 @@
<translation>Łącz z węzłami tylko w sieci &lt;net&gt; (ipv4, piv6 lub onion)</translation>
</message>
<message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Tryb ograniczony jest niekompatybilny z -txindex.</translation>
+ </message>
+ <message>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation>Ustaw wielkość pamięci podręcznej w megabajtach (%d do %d, domyślnie: %d)</translation>
</message>
@@ -2623,10 +2961,6 @@
<translation>Określ plik portfela (w obrębie folderu danych)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Jest to przeznaczone dla narzędzi testowania regresji i rozwoju aplikacji.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Użyj UPnP do przekazania portu nasłuchu (domyślnie : %u)</translation>
</message>
@@ -2647,6 +2981,10 @@
<translation>Opcje portfela:</translation>
</message>
<message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Uwaga: Ta wersja jest przestarzała, wymagana jest aktualizacja!</translation>
+ </message>
+ <message>
<source>You need to rebuild the database using -reindex to change -txindex</source>
<translation>Musisz przebudować bazę używając parametru -reindex aby zmienić -txindex</translation>
</message>
@@ -2663,10 +3001,22 @@
<translation>Napotkano błąd podczas ustawiania adres RPC %s port %u dla nasłuchiwania: %s</translation>
</message>
<message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Podepnij się do podanego adresu i dodawaj do białej listy węzły łączące się z nim. Użyj notacji [host]:port dla IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Powiąż się z podanym adresem, aby nasłuchiwać połączenia JSON-RPC. Użyj notacji [host]:port dla IPv6. Ta opcja może być określona kilka razy (domyślnie: powiąż ze wszystkimi interfejsami)</translation>
+ </message>
+ <message>
<source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
<translation>Nie można uzyskać blokady na katalogu z danymi %s. Rdzeń Bitcoin najprawdopodobniej jest już uruchomiony.</translation>
</message>
<message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Twórz nowe pliki z domyślnymi dla systemu uprawnieniami, zamiast umask 077 (skuteczne tylko przy wyłączonej funkcjonalności portfela)</translation>
+ </message>
+ <message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Błąd: Nasłuchiwanie połączeń przychodzących nie powiodło się (nasłuch zwrócił błąd %s)</translation>
</message>
@@ -2679,6 +3029,18 @@
<translation>Uruchom polecenie przy otrzymaniu odpowiedniego powiadomienia lub gdy zobaczymy naprawdę długie rozgałęzienie (%s w poleceniu jest podstawiane za komunikat)</translation>
</message>
<message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Opłaty (w BTC/Kb) mniejsze niż ta będą traktowane jako bez opłaty przy propagowaniu (domyślnie: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Jeżeli nie ustawiono paytxfee, dołącz wystarczająca opłatę, aby transakcja mogła zostać zatwierdzona w ciągu średniej ilości n bloków (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Niewłaściwa ilość dla -maxtxfee=&lt;ilość&gt;: '%s' (musi wynosić przynajmniej minimalną wielkość %s aby zapobiec utknięciu transakcji)</translation>
+ </message>
+ <message>
<source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
<translation>Maksymalny rozmiar danych w transakcji przekazującej dane które przekazujemy i wydobywamy (domyślnie: %u)</translation>
</message>
@@ -2695,14 +3057,70 @@
<translation>Ustaw liczbę wątków dla generowania monet (-1 = wszystkie rdzenie, domyślnie: %d)</translation>
</message>
<message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Zbyt niska kwota transakcji do wysłania po odjęciu opłaty</translation>
+ </message>
+ <message>
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
<translation>Program ten zawiera oprogramowanie stworzone przez OpenSSL Project do użycia w OpensSSL Toolkit &lt;https://www.openssl.org/&gt;, oprogramowanie kryptograficzne napisane przez Eric Young oraz oprogramowanie UPnP napisane przez Thomas Bernard.</translation>
</message>
<message>
+ <source>To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file:
+%s
+It is recommended you use the following random password:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(you do not need to remember this password)
+The username and password MUST NOT be the same.
+If the file does not exist, create it with owner-readable-only file permissions.
+It is also recommended to set alertnotify so you are notified of problems;
+for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
+</source>
+ <translation>Aby korzystać z bitcoind, lub opcji -server w bitcoin-qt, musisz ustawić opcję rpcpassword w pliku konfiguracyjnym:
+%s
+Zalecane jest użycie poniższego losowego hasła:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(nie musisz pamiętać tego hasła)
+Nazwa użytkownika i hasło NIE MOGĄ być takie same.
+Jeżeli ten plik nie istnieje, utwórz go z uprawnieniami tylko-do-odczytu przez właściciela.
+Zalecane jest także ustawienie opcji alertnotify, dzięki której będziesz powiadamiany o problemach;
+na przykład: alertnotify=echo %%s | mail -s "Alarm Bitcoin" admin@foo.com
+</translation>
+ </message>
+ <message>
<source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
<translation>Ostrzeżenie: -matxfee jest ustawione bardzo wysokie! Tak wysokie opłaty mogą być zapłacone w jednej transakcji.</translation>
</message>
<message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Ostrzeżenie: Proszę sprawdzić czy data i czas na Twoim komputerze są poprawne! Jeżeli ustawienia zegara będą złe, Bitcoin Core nie będzie działał prawidłowo.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Węzły z białej listy nie mogą zostać zbanowane za ataki DoS, a ich transakcje będą zawsze przekazywane, nawet jeżeli będą znajdywać się już w pamięci, przydatne np. dla bramek płatniczych</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Akceptuj publiczne żądania REST (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Aktywuje najlepszy łańcuch</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Nie można uruchomić z portfela w trybie ograniczonym.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Nie można rozwiązać adresu -whitebind: '%s'</translation>
+ </message>
+ <message>
<source>Choose data directory on startup (default: 0)</source>
<translation>Wybierz folder danych przy starcie (domyślnie: 0)</translation>
</message>
@@ -2715,6 +3133,10 @@
<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>
@@ -2755,6 +3177,14 @@
<translation>Nieprawidłowa kwota dla -paytxfee=&lt;amount&gt;: '%s' (musi być co najmniej %s)</translation>
</message>
<message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Nieprawidłowa maska sieci określona w -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>Przechowuj w pamięci maksymalnie &lt;n&gt; transakcji nie możliwych do połączenia (domyślnie: %u)</translation>
+ </message>
+ <message>
<source>Node relay options:</source>
<translation>Opcje przekaźnikowe węzła:</translation>
</message>
@@ -2767,12 +3197,16 @@
<translation>Opcje serwera RPC:</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Losowo ignoruje 1 z każdych &lt;n&gt; wiadomości sieciowych.</translation>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Wsparcie RPC dla ciągłych połączeń HTTP (domyślnie: %d)</translation>
</message>
<message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Losowo miesza 1 z wszystkich &lt;n&gt; wiadomości sieciowych.</translation>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Odbuduj indeks łańcucha bloków z obecnych plików blk000??.dat podczas ponownego uruchomienia</translation>
+ </message>
+ <message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Odbieranie i wyświetlanie alertów sieci P2P (domyślnie: %u)</translation>
</message>
<message>
<source>Send trace/debug info to console instead of debug.log file</source>
@@ -2811,6 +3245,10 @@
<translation>Uruchom zminimalizowany</translation>
</message>
<message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Zbyt niska kwota transakcji by zapłacić opłatę</translation>
+ </message>
+ <message>
<source>This is experimental software.</source>
<translation>To oprogramowanie eksperymentalne.</translation>
</message>
@@ -2831,6 +3269,10 @@
<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>
@@ -2915,10 +3357,6 @@
<translation>Jak dokładna jest weryfikacja bloków przy -checkblocks (0-4, domyślnie: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Loguj priorytety transakcji i opłaty na kB podczas kopania bloków (domyślnie: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Utrzymuj pełny indeks transakcji, używany przy wywołaniu RPC getrawtransaction (domyślnie: %u)</translation>
</message>
@@ -2927,16 +3365,28 @@
<translation>Czas w sekundach, przez jaki nietrzymające się zasad węzły nie będą mogły ponownie się podłączyć (domyślnie: %u)</translation>
</message>
<message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Wypuść informacje debugowania (domyślnie: %u, podanie &lt;category&gt; jest opcjonalne)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Użyj oddzielnego prozy SOCKS5 aby osiągnąć węzły w ukrytych usługach Tor (domyślnie: %s)</translation>
+ </message>
+ <message>
<source>(default: %s)</source>
<translation>(domyślnie: %s)</translation>
</message>
<message>
- <source>Error loading wallet.dat</source>
- <translation>Błąd ładowania wallet.dat</translation>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Akceptowane szyfry (domyślne: %s)</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Wymuś tryb bezpieczny (domyślnie: %u)</translation>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Zawsze wypytuj o adresy węzłów poprzez podejrzenie DNS (domyślnie: %u)</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat</source>
+ <translation>Błąd ładowania wallet.dat</translation>
</message>
<message>
<source>Generate coins (default: %u)</source>
@@ -2955,10 +3405,6 @@
<translation>Nieprawidłowy adres -proxy: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Ogranicz rozmiar pamięci podręcznej sygnatur do &lt;n&gt; wpisów (domyślnie: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Nasłuchuj połączeń JSON-RPC na &lt;port&gt; (domyślnie: %u lub testnet: %u)</translation>
</message>
@@ -2971,6 +3417,10 @@
<translation>Utrzymuj maksymalnie &lt;n&gt; połączeń z węzłami (domyślnie: %u)</translation>
</message>
<message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Spraw by portfel dokonał transmisji transakcji</translation>
+ </message>
+ <message>
<source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
<translation>Maksymalny bufor odbioru na połączenie, &lt;n&gt;*1000 bajtów (domyślnie: %u)</translation>
</message>
@@ -2979,10 +3429,6 @@
<translation>Maksymalny bufor wysyłania na połączenie, &lt;n&gt;*1000 bajtów (domyślnie: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Akceptuj tylko łańcuch bloków zgodny z wbudowanymi punktami kontrolnymi (domyślnie: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Dołączaj znacznik czasu do logowania (domyślnie: %u)</translation>
</message>
@@ -2995,10 +3441,6 @@
<translation>Przekazuj transakcje multisig inne niż P2SH (domyślnie: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Uruchom wątek do okresowego zapisywania portfela (domyślnie: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>Plik certyfikatu serwera (domyślnie: %s)</translation>
</message>
@@ -3019,10 +3461,6 @@
<translation>Ustaw liczbę wątków do obsługi RPC (domyślnie: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Ustaw flagę DB_PRIVATE w środowisku wallet db (domyślnie: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Wskaż plik konfiguracyjny (domyślnie: %s)</translation>
</message>
@@ -3039,10 +3477,6 @@
<translation>Wydawaj niepotwierdzoną resztę podczas wysyłania transakcji (domyślnie: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Zatrzymaj po zaimportowaniu bloków z dysku (domyślnie: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Próg, po którym nastąpi rozłączenie węzłów nietrzymających się zasad (domyślnie: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts
index 42a781de99..cd2a5a6323 100644
--- a/src/qt/locale/bitcoin_pt_BR.ts
+++ b/src/qt/locale/bitcoin_pt_BR.ts
@@ -1,4 +1,4 @@
-<TS language="pt_BR" version="2.1">
+<TS language="pt_BR" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -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>Estes são os seus endereços Bitcoin para receber pagamentos. Você pode querer enviar um endereço diferente para cada remetente, para acompanhar quem está pagando.</translation>
+ <translation>Esses são seus endereços Bitcoin para enviar pagamentos. Certifique-se sempre da quantia e do destinatário antes de enviar moedas.</translation>
</message>
<message>
<source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
@@ -276,7 +276,7 @@
</message>
<message>
<source>&amp;Backup Wallet...</source>
- <translation>&amp;Backup Carteira...</translation>
+ <translation>&amp;Backup da carteira...</translation>
</message>
<message>
<source>&amp;Change Passphrase...</source>
@@ -288,7 +288,7 @@
</message>
<message>
<source>&amp;Receiving addresses...</source>
- <translation>Endereços de &amp;Recebimento...</translation>
+ <translation>Endereços de &amp;recebimento...</translation>
</message>
<message>
<source>Open &amp;URI...</source>
@@ -1831,6 +1831,10 @@
<translation>Escolher</translation>
</message>
<message>
+ <source>collapse fee-settings</source>
+ <translation>colapso Taxa de definições</translation>
+ </message>
+ <message>
<source>per kilobyte</source>
<translation>por kilobyte</translation>
</message>
@@ -2078,6 +2082,10 @@
<translation>Remover esta entrada</translation>
</message>
<message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>A taxa será deduzida da quantia sendo enviada. O beneficiario receberá menos bitcoins do que você colocou no campo de quantidade. Se varios beneficiarios estão selecionados, a taxa é dividida igualmente.</translation>
+ </message>
+ <message>
<source>S&amp;ubtract fee from amount</source>
<translation>&amp;Retirar taxa da quantia</translation>
</message>
@@ -2086,6 +2094,14 @@
<translation>Mensagem:</translation>
</message>
<message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Esta é uma cobrança não autenticada.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Esta é uma cobrança autenticada.</translation>
+ </message>
+ <message>
<source>Enter a label for this address to add it to the list of used addresses</source>
<translation>Digite um rótulo para este endereço para adicioná-lo no catálogo</translation>
</message>
@@ -2110,7 +2126,7 @@
</message>
<message>
<source>Do not shut down the computer until this window disappears.</source>
- <translation>Não desligue o computador até esta janela desapareça.</translation>
+ <translation>Não desligue o computador até que esta janela desapareça.</translation>
</message>
</context>
<context>
@@ -2523,6 +2539,10 @@
<translation>Tipo de transação.</translation>
</message>
<message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Mostrar ou não endereços Bitcoin na lista de transações.</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
<translation>Quantidade debitada ou creditada ao saldo.</translation>
</message>
@@ -2734,7 +2754,7 @@
</message>
<message>
<source>Specify data directory</source>
- <translation>Especificar diretório de dados</translation>
+ <translation>Especificar o diretório de dados</translation>
</message>
<message>
<source>Connect to a node to retrieve peer addresses, and disconnect</source>
@@ -2773,16 +2793,12 @@
<translation>Distribuido sob a licença MIT software license. Veja os termos em &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Entra no modo de teste de regressão, que usa uma cadeia especial onde os blocos podem ser resolvidos instantaneamente.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
- <translation>Executar comando quando uma transação da carteira mudar (%s no comando será substituído por TxID)</translation>
+ <translation>Executa um comando quando uma transação da carteira mudar (%s no comando será substituído por TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>Neste modo -genproclimit controla quantos blocos são gerados imediatamente.</translation>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%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, &gt;%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, &lt;0 = leave that many cores free, default: %d)</source>
@@ -2817,6 +2833,10 @@
<translation>Atenção: wallet.dat corrompido, dados recuperados! Arquivo wallet.dat original salvo como wallet.{timestamp}.bak em %s; se seu saldo ou transações estiverem incorretos, você deve restaurar o backup.</translation>
</message>
<message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Lista Branca pares de ligação da máscara de rede dado ou o endereço IP . Pode ser especificado várias vezes.</translation>
+ </message>
+ <message>
<source>(default: 1)</source>
<translation>(padrão: 1)</translation>
</message>
@@ -2834,7 +2854,7 @@
</message>
<message>
<source>Connect only to the specified node(s)</source>
- <translation>Conectar apenas a nó(s) específico(s)</translation>
+ <translation>Conectar apenas a cliente(s) específico(s)</translation>
</message>
<message>
<source>Connection options:</source>
@@ -2909,6 +2929,14 @@
<translation>Somente conectar a clientes na rede &lt;net&gt; (ipv4, ipv6 ou onion)</translation>
</message>
<message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>O modo Prune não pode ser configurado com um valor negativo.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>O modo Prune é incompatível com -txindex.</translation>
+ </message>
+ <message>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation>Define o tamanho do cache do banco de dados em megabytes (%d para %d, padrão: %d)</translation>
</message>
@@ -2921,10 +2949,6 @@
<translation>Especifique o arquivo da carteira (dentro do diretório de dados)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Isso é usado para testes de regressão e ferramentas de desenvolvimento.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Use UPnP para mapear a porta de entrada (padrão: %u)</translation>
</message>
@@ -2965,24 +2989,32 @@
<translation>Um erro ocorreu enquanto configurando o endereço RPC %s porta %u para escuta: %s</translation>
</message>
<message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Vincular ao endereço fornecido e sempre escutar nele. Use a notação [host]:port para IPv6</translation>
+ </message>
+ <message>
<source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
<translation>Não foi possível obter acesso exclusivo ao diretório de dados %s. Provavelmente Bitcoin já está sendo executado.</translation>
</message>
<message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Descobrir o próprio IP (padrão: 1 enquanto aguardando conexões e sem -externalip ou -proxy)</translation>
+ </message>
+ <message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Erro: Aceitar conexões de entrada falhou (retornou erro %s)</translation>
</message>
<message>
<source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
- <translation>Executa o comando quando um alerta relevante é recebido ou vemos uma longa segregação (%s em cmd é substituído pela mensagem)</translation>
+ <translation>Executa um comando quando um alerta relevante é recebido ou vemos uma longa segregação (%s em cmd é substituído pela mensagem)</translation>
</message>
<message>
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
<translation>Taxas (em BTC/Kb) menores do que este valor são consideradas inexistentes para divulgação (padrão: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Taxas (em BTC/Kb) menores do que este valor são consideradas inexistentes para a criação da transação (padrão: %s)</translation>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Prunagem configurada abaixo do mínimo de %d MB. Use um número maior.</translation>
</message>
<message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
@@ -3013,10 +3045,18 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br
</translation>
</message>
<message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Você precisa reconstruir o banco de dados usando -reindex para sair do modo prune. Isso irá rebaixar todo o blockchain.</translation>
+ </message>
+ <message>
<source>(default: %u)</source>
<translation>(padrão: %u)</translation>
</message>
<message>
+ <source>Activating best chain...</source>
+ <translation>Ativando a melhor sequência...</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>Impossível resolver endereço -whitebind: '%s'</translation>
</message>
@@ -3081,6 +3121,10 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br
<translation>Necessário informar uma porta com -whitebind: '%s'</translation>
</message>
<message>
+ <source>Node relay options:</source>
+ <translation>Opções de relé nó :</translation>
+ </message>
+ <message>
<source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
<translation>Opções RPC SSL: (veja o Bitcoin Wiki para instruções de configuração SSL)</translation>
</message>
@@ -3089,14 +3133,6 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br
<translation>Opções do servidor RPC:</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Aleatoriamente descarta 1 em cada &lt;n&gt; mensagens da rede</translation>
- </message>
- <message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Aleatoriamente embaralha 1 em cada &lt;n&gt; mensagens da rede</translation>
- </message>
- <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Mandar informação de trace/debug para o console em vez de para o arquivo debug.log</translation>
</message>
@@ -3194,7 +3230,7 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br
</message>
<message>
<source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
- <translation>Executar comando quando o melhor bloco mudar (%s no comando será substituído pelo hash do bloco)</translation>
+ <translation>Executa um comando quando o melhor bloco mudar (%s no comando será substituído pelo hash do bloco)</translation>
</message>
<message>
<source>Upgrade wallet to latest format</source>
@@ -3210,7 +3246,7 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br
</message>
<message>
<source>This help message</source>
- <translation>Esta mensagem de ajuda</translation>
+ <translation>Exibe esta mensagem de ajuda</translation>
</message>
<message>
<source>Allow DNS lookups for -addnode, -seednode and -connect</source>
@@ -3229,18 +3265,22 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br
<translation>(padrão: %s)</translation>
</message>
<message>
- <source>Error loading wallet.dat</source>
- <translation>Erro ao carregar wallet.dat</translation>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Cífras aceitas (padrão: %s)</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Forçar modo seguro (default: %u)</translation>
+ <source>Error loading wallet.dat</source>
+ <translation>Erro ao carregar wallet.dat</translation>
</message>
<message>
<source>Generate coins (default: %u)</source>
<translation>Gerar moedas (padrão: %u)</translation>
</message>
<message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Quantos blocos devem ser checados ao iniciar (padrão: %u, 0 = todos)</translation>
+ </message>
+ <message>
<source>Include IP addresses in debug output (default: %u)</source>
<translation>Incluir endereço IP na saída de depuração (padrão: %u)</translation>
</message>
@@ -3249,14 +3289,18 @@ 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>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Tamanho limite do cache de assinaturas de &lt;n&gt; entradas (padrão: %u)</translation>
- </message>
- <message>
<source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Aguardar por conexões na porta &lt;port&gt; (padrão: %u ou testnet: %u)</translation>
</message>
<message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Adiciona timestamp como prefixo no debug (default: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Retransmitir P2SH não multisig (default: %u)</translation>
+ </message>
+ <message>
<source>Server certificate file (default: %s)</source>
<translation>Arquivo de certificado do servidor (padrão: %s)</translation>
</message>
@@ -3265,6 +3309,18 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br
<translation>Chave privada do servidor (padrão: %s)</translation>
</message>
<message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Definir tamanho mínimo do bloco, em bytes (padrão: %u)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Especificar arquivo de configuração (padrão: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Especificar tempo para desistência de conexões, em mili segundos (mínimo: 1, padrão: %d)</translation>
+ </message>
+ <message>
<source>Specify pid file (default: %s)</source>
<translation>Especificar aqrquivo pid (default: %s)</translation>
</message>
@@ -3294,7 +3350,7 @@ por exemplo: alertnotify=echo %%s | mail -s "Alerta do Bitcoin" admin@foo.com.br
</message>
<message>
<source>Add a node to connect to and attempt to keep the connection open</source>
- <translation>Adicionar um nó com o qual se conectar e tentar manter a conexão ativa</translation>
+ <translation>Adicionar um cliente para se conectar e tentar manter a conexão ativa</translation>
</message>
<message>
<source>Loading wallet...</source>
diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts
index 5012ff8d83..7ac0a4fa5c 100644
--- a/src/qt/locale/bitcoin_pt_PT.ts
+++ b/src/qt/locale/bitcoin_pt_PT.ts
@@ -1,4 +1,4 @@
-<TS language="pt_PT" version="2.1">
+<TS language="pt_PT" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -168,6 +168,10 @@
<translation>Tem a certeza que deseja encriptar a carteira?</translation>
</message>
<message>
+ <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>O cliente Bitcoin Core irá agora ser fechado para terminar o processo de encriptação. Recorde que a encriptação da sua carteira não protegerá totalmente os seus bitcoins de serem roubados por programas maliciosos que infectem o seu computador.</translation>
+ </message>
+ <message>
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
<translation>IMPORTANTE: Qualquer cópia de segurança da carteira anterior deverá ser substituída com o novo ficheiro de carteira, agora encriptado. Por razões de segurança, cópias de segurança não encriptadas tornar-se-ão inúteis assim que começar a usar a nova carteira encriptada.</translation>
</message>
@@ -184,6 +188,10 @@
<translation>Escreva a nova frase de seguraça da sua carteira. &lt;br/&gt; Por favor, use uma frase de &lt;b&gt;10 ou mais caracteres aleatórios,&lt;/b&gt; ou &lt;b&gt;oito ou mais palavras&lt;/b&gt;.</translation>
</message>
<message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Escreva a antiga frase de segurança da carteira, seguida da nova.</translation>
+ </message>
+ <message>
<source>Wallet encryption failed</source>
<translation>A encriptação da carteira falhou</translation>
</message>
@@ -391,6 +399,10 @@
<translation>&amp;Sobre o Bitcoin Core</translation>
</message>
<message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Modificar opções de configuração de Bitcoin Core</translation>
+ </message>
+ <message>
<source>Show the list of used sending addresses and labels</source>
<translation>Mostrar a lista de rótulos e endereços de envio usados</translation>
</message>
@@ -419,6 +431,10 @@
<translation>Nenhuma fonte de blocos disponível...</translation>
</message>
<message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Processado %n bloco do histórico de transações.</numerusform><numerusform>Processados %n blocos do histórico de transações.</numerusform></translation>
+ </message>
+ <message numerus="yes">
<source>%n hour(s)</source>
<translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation>
</message>
@@ -471,6 +487,36 @@
<translation>Recuperando o atraso...</translation>
</message>
<message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Quantia: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Tipo: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Rótulo: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Endereço: %1
+</translation>
+ </message>
+ <message>
<source>Sent transaction</source>
<translation>Transação enviada</translation>
</message>
@@ -669,6 +715,18 @@
<translation>nenhum</translation>
</message>
<message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Este rótulo fica vermelho se o tamanho da transacção exceder os 1000 bytes.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Esta legenda fica vermelha se a prioridade for menor que "média".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Este rótulo fica vermelho se algum recipiente receber uma quantia menor que %1.</translation>
+ </message>
+ <message>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation>Pode variar +/- %1 satoshi(s) por entrada</translation>
</message>
@@ -919,6 +977,14 @@
<translation>Endereço IP do proxy (p.ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
</message>
<message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimize ao invés de sair da aplicação quando a janela é fechada. Com esta opção selecionada, a aplicação apenas será encerrada quando escolher Sair da aplicação no menú.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>A linguagem da interface do utilizador pode ser definida aqui. Esta definição entrará em efeito após reiniciar o Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
<translation>URLs de outrem (ex. um explorador de blocos) que aparece no separador de transações como itens do menu de contexto.
%s do URL é substituído por hash de transação. Vários URLs são separados por barra vertical |.</translation>
@@ -944,6 +1010,14 @@
<translation>&amp;Rede</translation>
</message>
<message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Começar o Bitcoin Core automaticamente ao iniciar sessão no sistema.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Começar o Bitcoin Core ao iniciar o sistema</translation>
+ </message>
+ <message>
<source>(0 = auto, &lt;0 = leave that many cores free)</source>
<translation>(0 = auto, &lt;0 = Deixar essa quantidade de núcleos livre)</translation>
</message>
@@ -1056,6 +1130,10 @@
<translation>É necessário reiniciar o cliente para ativar as alterações.</translation>
</message>
<message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>O cliente será desligado. Deseja continuar?</translation>
+ </message>
+ <message>
<source>This change would require a client restart.</source>
<translation>Esta alteração requer um reinício do cliente.</translation>
</message>
@@ -1190,10 +1268,18 @@
<translation>O ficheiro de pedido de pagamento não pôde ser lido! Isto pode ter sido causado por um ficheiro de pedido de pagamento inválido.</translation>
</message>
<message>
+ <source>Payment request expired.</source>
+ <translation>Pedido de pagamento expirou.</translation>
+ </message>
+ <message>
<source>Unverified payment requests to custom payment scripts are unsupported.</source>
<translation>Pedidos de pagamento não-verificados para scripts de pagamento personalizados não são suportados.</translation>
</message>
<message>
+ <source>Invalid payment request.</source>
+ <translation>Pedido de pagamento inválido.</translation>
+ </message>
+ <message>
<source>Refund from %1</source>
<translation>Reembolsar de %1</translation>
</message>
@@ -1233,6 +1319,10 @@
<translation>Agente Usuário</translation>
</message>
<message>
+ <source>Node/Service</source>
+ <translation>Nó/Serviço</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Tempo de Latência</translation>
</message>
@@ -1466,6 +1556,10 @@
<translation>Limpar consola</translation>
</message>
<message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Bem-vindo à consola RPC do Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
<translation>Use as setas para cima e para baixo para navegar no histórico e &lt;b&gt;Ctrl-L&lt;/b&gt; para limpar o ecrã.</translation>
</message>
@@ -1762,6 +1856,10 @@
<translation>Se a taxa fixa for 1000 satoshis e a transação for somente 250 bytes, pagará somente 250 satoshis "por kilobyte" em custos se trasacionar "pelo menos" 1000 satoshis. Transações superiores a um kilobyte são cobradas por kilobyte.</translation>
</message>
<message>
+ <source>Hide</source>
+ <translation>Esconder</translation>
+ </message>
+ <message>
<source>total at least</source>
<translation>total minimo</translation>
</message>
@@ -1902,6 +2000,10 @@
<translation>A transação foi rejeitada! Isto poderá acontecer se algumas das moedas na sua carteira já tiverem sido gastas, se por exemplo tiver usado uma cópia do ficheiro wallet.dat e as moedas tiverem sido gastas na cópia mas não tiverem sido marcadas como gastas aqui.</translation>
</message>
<message>
+ <source>Payment request expired.</source>
+ <translation>Pedido de pagamento expirou.</translation>
+ </message>
+ <message>
<source>Pay only the minimum fee of %1</source>
<translation>Pagar somente a taxa minima de %1</translation>
</message>
@@ -2672,18 +2774,10 @@
<translation>Distribuido através da licença de software MIT, verifique o ficheiro anexado COPYING ou &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Entre no modo de teste de regressão, que usa uma cadeia especial cujos blocos podem ser resolvidos instantaneamente.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Executar comando quando uma das transações na carteira mudar (no comando, %s é substituído pelo ID da Transação)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>O modo -genproclimit controla quantos blocos são generados imediatamente.</translation>
- </message>
- <message>
<source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
<translation>Defina o número de processos de verificação (%u até %d, 0 = automático, &lt;0 = ldisponibiliza esse número de núcleos livres, por defeito: %d)</translation>
</message>
@@ -2824,10 +2918,6 @@
<translation>Especifique ficheiro de carteira (dentro da pasta de dados)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Isto têm como fim a realização de testes de regressão para pools e desenvolvimento de aplicações.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Use UPnP para mapear a porto de escuta (default: %u)</translation>
</message>
@@ -2848,6 +2938,10 @@
<translation>Opções da carteira:</translation>
</message>
<message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Aviso: Esta versão está desatualizada; atualização necessária!</translation>
+ </message>
+ <message>
<source>You need to rebuild the database using -reindex to change -txindex</source>
<translation>É necessário reconstruir as bases de dados usando -reindex para mudar o -txindex</translation>
</message>
@@ -2880,10 +2974,26 @@
<translation>Definir tamanho máximo de transações com alta-prioridade/baixa-taxa em bytes (por defeito: %d)</translation>
</message>
<message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Atenção: Por favor verifique que a data e hora do seu computador estão correctas! Se o seu relógio não estiver certo o Bitcoin Core não irá funcionar correctamente.</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(por defeito: %u)</translation>
+ </message>
+ <message>
<source>Choose data directory on startup (default: 0)</source>
<translation>Escolha a pasta de dados ao iniciar (por defeito: 0)</translation>
</message>
<message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i Os Programadores do Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Erro ao carregar wallet.dat: A Carteira requer uma versão mais recente do Bitcoin Core</translation>
+ </message>
+ <message>
<source>Information</source>
<translation>Informação</translation>
</message>
@@ -2944,6 +3054,10 @@
<translation>Nome de utilizador para ligações JSON-RPC</translation>
</message>
<message>
+ <source>Wallet needed to be rewritten: restart Bitcoin Core to complete</source>
+ <translation>A Carteira precisou de ser reescrita: reinicie o Bitcoin Core para completar o processo</translation>
+ </message>
+ <message>
<source>Warning</source>
<translation>Aviso</translation>
</message>
@@ -3000,6 +3114,58 @@
<translation>Endereço -proxy inválido: '%s'</translation>
</message>
<message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escutar por ligações JSON-RPC na porta &lt;port&gt; (por defeito: %u ou rede de testes: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Escute ligações na porta &lt;port&gt; (por defeito: %u ou testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
+ <translation>Manter no máximo &lt;n&gt; ligações a outros nós da rede (por defeito: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximo armazenamento intermédio de recepção por ligação, &lt;n&gt;*1000 bytes (por defeito: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximo armazenamento intermédio de envio por ligação, &lt;n&gt;*1000 bytes (por defeito: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Adicionar data e hora à informação de depuração (por defeito: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Ficheiro de certificado do servidor (por defeito: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Chave privada do servidor (por defeito: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Definir o tamanho da memória de chaves para &lt;n&gt; (por defeito: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Definir tamanho minímo de um bloco em bytes (por defeito: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Defina o número de processos para servir as chamadas RPC (por defeito: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Especificar ficheiro de configuração (por defeito: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Especificar tempo de espera da ligação em milissegundos (mínimo 1, por defeito: %d)</translation>
+ </message>
+ <message>
<source>Unknown network specified in -onlynet: '%s'</source>
<translation>Rede desconhecida especificada em -onlynet: '%s'</translation>
</message>
diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts
index 11a29e86c9..be24668536 100644
--- a/src/qt/locale/bitcoin_ro_RO.ts
+++ b/src/qt/locale/bitcoin_ro_RO.ts
@@ -1,4 +1,4 @@
-<TS language="ro_RO" version="2.1">
+<TS language="ro_RO" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -2713,18 +2713,10 @@
<translation>Distribuit sub licenţa de programe MIT/X11, vezi fişierul însoţitor COPYING sau &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Iniţiază modul de test regresie, care foloseşte un lanţ special în care blocurile pot fi rezolvate instantaneu.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Execută comanda cînd o tranzacţie a portofelului se schimbă (%s în cmd este înlocuit de TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>În acest mod -genproclimit controlează cîte blocuri sînt generate imediat.</translation>
- </message>
- <message>
<source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
<translation>Setează numărul de thread-uri de verificare a script-urilor (%u la %d, 0 = auto, &lt;0 = lasă atîtea nuclee libere, implicit: %d)</translation>
</message>
@@ -2857,10 +2849,6 @@
<translation>Specifică fişierul portofel (în dosarul de date)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Este folosită pentru programe de testare a regresiei în algoritmi şi dezvoltare de alte aplicaţii.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Foloseşte mapare UPnP pentru asculatere port (implicit: %u)</translation>
</message>
@@ -2985,14 +2973,6 @@
<translation>RPC suportă pentru HTTP conexiuni persistente (implicit: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Aleator sccapă 1 din fiecare &lt;n&gt; mesaje ale reţelei</translation>
- </message>
- <message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Aleator aproximează 1 din fiecare &lt;n&gt; mesaje ale reţelei</translation>
- </message>
- <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Trimite informaţiile trace/debug la consolă în locul fişierului debug.log</translation>
</message>
@@ -3125,10 +3105,6 @@
<translation>Eroare la încărcarea wallet.dat: Portofel corupt</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Goleşte baza de date a activităţii din memoria pool în jurnal pe disc la fiecare &lt;n&gt; megaocteţi (implicit: %u)</translation>
- </message>
- <message>
<source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
<translation>Produce toate informaţiile de depanare (implicit: %u &lt;category&gt; furnizată este opţională)</translation>
</message>
@@ -3145,10 +3121,6 @@
<translation>Eroare la încărcarea wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Forţează mod sigur (implicit: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Generează monede (implicit: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts
index c208b3e25e..004208d345 100644
--- a/src/qt/locale/bitcoin_ru.ts
+++ b/src/qt/locale/bitcoin_ru.ts
@@ -1,4 +1,4 @@
-<TS language="ru" version="2.1">
+<TS language="ru" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -164,6 +164,10 @@
<translation>Вы уверены, что хотите зашифровать ваш бумажник?</translation>
</message>
<message>
+ <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>Сейчас программа закроется для завершения процесса шифрования. Помните, что шифрование вашего бумажника не может полностью защитить ваши биткоины от кражи с помощью инфицирования вашего компьютера вредоносным ПО.</translation>
+ </message>
+ <message>
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
<translation>ВАЖНО: все предыдущие резервные копии вашего бумажника должны быть заменены новым зашифрованным файлом. В целях безопасности предыдущие резервные копии незашифрованного бумажника станут бесполезны, как только вы начнёте использовать новый зашифрованный бумажник.</translation>
</message>
@@ -180,6 +184,10 @@
<translation>Введите новый пароль бумажника.&lt;br/&gt;Используйте пароль, состоящий из &lt;b&gt;десяти или более случайных символов&lt;/b&gt;, или &lt;b&gt;восьми или более слов&lt;/b&gt;.</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>
@@ -387,6 +395,10 @@
<translation>&amp;О Bitcoin Core</translation>
</message>
<message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Изменить опции конфигурации Bitcoin Core</translation>
+ </message>
+ <message>
<source>Show the list of used sending addresses and labels</source>
<translation>Показать список использованных адресов и меток отправки</translation>
</message>
@@ -410,6 +422,10 @@
<source>No block source available...</source>
<translation>Источник блоков недоступен...</translation>
</message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Обработан %n блок истории транзакций.</numerusform><numerusform>Обработано %n блока истории транзакций.</numerusform><numerusform>Обработано %n блоков истории транзакций.</numerusform><numerusform>Обработано %n блоков истории транзакций.</numerusform></translation>
+ </message>
<message>
<source>%1 and %2</source>
<translation>%1 и %2</translation>
@@ -447,6 +463,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>
@@ -645,6 +691,18 @@
<translation>ничего</translation>
</message>
<message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Эта метка становится красной, если размер транзакции будет больше, чем 1000 байт.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Эта метка становится красной, если приоритет меньше, чем "среднее".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Эта метка становится красной, если любой из получателей принимает количество меньше, чем %1.</translation>
+ </message>
+ <message>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation>Может отличаться на +/- %1 сатоши на вход.</translation>
</message>
@@ -887,6 +945,14 @@
<translation>IP-адрес прокси (например IPv4: 127.0.0.1 / IPv6: ::1)</translation>
</message>
<message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Сворачивать вместо закрытия. Если данная опция будет выбрана — приложение закроется только после выбора соответствующего пункта в меню.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Здесь можно выбрать язык интерфейса. Настройки вступят в силу после перезапуска Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
<translation>Сторонние URL (например, block explorer), которые отображаются на вкладке транзакций как пункты контекстного меню. %s в URL заменяется хэшем транзакции. URL отделяются друг от друга вертикальной чертой |.</translation>
</message>
@@ -911,6 +977,14 @@
<translation>&amp;Сеть</translation>
</message>
<message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Автоматически запускать Bitcoin Core после входа в систему</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Запускать Bitcoin Core при входе в систему</translation>
+ </message>
+ <message>
<source>(0 = auto, &lt;0 = leave that many cores free)</source>
<translation>(0 = автоматически, &lt;0 = оставить столько незагруженных ядер)</translation>
</message>
@@ -1023,6 +1097,10 @@
<translation>Для применения изменений требуется перезапуск клиента.</translation>
</message>
<message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Клиент будет выключен. Желаете продолжить?</translation>
+ </message>
+ <message>
<source>This change would require a client restart.</source>
<translation>Это изменение потребует перезапуска клиента.</translation>
</message>
@@ -1157,10 +1235,18 @@
<translation>Файл запроса платежа не может быть прочитан! Обычно это происходит из-за неверного файла запроса платежа.</translation>
</message>
<message>
+ <source>Payment request expired.</source>
+ <translation>Запрос платежа просрочен.</translation>
+ </message>
+ <message>
<source>Unverified payment requests to custom payment scripts are unsupported.</source>
<translation>Непроверенные запросы платежей с нестандартными платёжными сценариями не поддерживаются.</translation>
</message>
<message>
+ <source>Invalid payment request.</source>
+ <translation>Неверный запрос платежа.</translation>
+ </message>
+ <message>
<source>Refund from %1</source>
<translation>Возврат от %1</translation>
</message>
@@ -1200,6 +1286,10 @@
<translation>Юзер-агент</translation>
</message>
<message>
+ <source>Node/Service</source>
+ <translation>Узел/сервис</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Время задержки</translation>
</message>
@@ -1321,6 +1411,10 @@
<translation>Текущее число блоков</translation>
</message>
<message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Открыть отладочный лог-файл Bitcoin Core из текущего каталога данных. Это может занять несколько секунд для больших лог-файлов.</translation>
+ </message>
+ <message>
<source>Received</source>
<translation>Получено</translation>
</message>
@@ -1389,6 +1483,10 @@
<translation>Время задержки</translation>
</message>
<message>
+ <source>Time Offset</source>
+ <translation>Смещение времени</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Время последнего блока</translation>
</message>
@@ -1433,6 +1531,10 @@
<translation>Очистить консоль</translation>
</message>
<message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Добро пожаловать в RPC-консоль Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
<translation>Используйте стрелки вверх и вниз для просмотра истории и &lt;b&gt;Ctrl-L&lt;/b&gt; для очистки экрана.</translation>
</message>
@@ -1729,6 +1831,10 @@
<translation>Если комиссия установлена в 1000 сатоши, а транзакция составляет лишь 250 байт, тогда комиссия "на килобайт" составит 250 сатоши, а "всего как минимум" — 1000 сатоши. Для транзакций крупнее килобайта в обоих случаях будет использоваться платёж "на килобайт".</translation>
</message>
<message>
+ <source>Hide</source>
+ <translation>Скрыть</translation>
+ </message>
+ <message>
<source>total at least</source>
<translation>Итого как минимум</translation>
</message>
@@ -1873,6 +1979,18 @@
<translation>Комиссия больше, чем %1, считается невероятно большой.</translation>
</message>
<message>
+ <source>Payment request expired.</source>
+ <translation>Запрос платежа просрочен.</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Адрес получателя неверный. Пожалуйста, перепроверьте.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Обнаружен дублирующийся адрес: используйте каждый адрес только один раз.</translation>
+ </message>
+ <message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Внимание: неверный адрес Bitcoin</translation>
</message>
@@ -1944,10 +2062,26 @@
<translation>Удалить эту запись</translation>
</message>
<message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>С отправляемой суммы будет удержана комиссия. Получателю придёт меньше биткоинов, чем вы вводите в поле количества. Если выбрано несколько получателей, комиссия распределяется поровну.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>Вычесть комиссию из суммы</translation>
+ </message>
+ <message>
<source>Message:</source>
<translation>Сообщение:</translation>
</message>
<message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Это неавторизованный запрос платежа.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Это авторизованный запрос платежа.</translation>
+ </message>
+ <message>
<source>Enter a label for this address to add it to the list of used addresses</source>
<translation>Введите метку для этого адреса, чтобы добавить его в список использованных</translation>
</message>
@@ -1986,6 +2120,10 @@
<translation>&amp;Подписать сообщение</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>Вы можете подписывать сообщения/соглашения своими адресами, чтобы доказать свою возможность получать биткоины на них. Будьте осторожны, не подписывайте что-то неопределённое или случайное, так как фишинговые атаки могут обманным путём заставить вас подписать нежелательные сообщения. Подписывайте только те сообщения, с которыми вы согласны вплоть до мелочей.</translation>
+ </message>
+ <message>
<source>The Bitcoin address to sign the message with</source>
<translation>Адрес Bitcoin, которым подписать сообщение</translation>
</message>
@@ -2038,6 +2176,10 @@
<translation>&amp;Проверить сообщение</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>Введите ниже адрес получателя, сообщение (убедитесь, что переводы строк, пробелы, табы и т.п. в точности скопированы) и подпись, чтобы проверить сообщение. Убедитесь, что не скопировали лишнего в подпись, по сравнению с самим подписываемым сообщением, чтобы не стать жертвой атаки "man-in-the-middle". Заметьте, что эта операция удостоверяет лишь авторство подписавшего, но не может удостоверить отправителя транзакции.</translation>
+ </message>
+ <message>
<source>The Bitcoin address the message was signed with</source>
<translation>Адрес Bitcoin, которым было подписано сообщение</translation>
</message>
@@ -2369,6 +2511,10 @@
<translation>Использовался ли в транзакции адрес для наблюдения.</translation>
</message>
<message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Определяемое пользователем намерение/цель транзакции.</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
<translation>Сумма, добавленная, или снятая с баланса.</translation>
</message>
@@ -2619,16 +2765,16 @@
<translation>Распространяется под лицензией MIT, см. приложенный файл COPYING или &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Войти в режим тестирования на регрессии, в котором используется специальная цепь, где блоки находятся мгновенно.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Выполнить команду, когда меняется транзакция в бумажнике (%s в команде заменяется на TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>В этом режиме -genproclimit определяет, сколько блоков генерируется немедленно.</translation>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Максимальная сумма комиссий для одной транзакции в бумажнике; слишком низкое значение может вызвать прерывание больших транзакций (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Уменьшить размер хранилища за счёт удаления (обрезания) старых блоков. Этот режим отключает поддержку бумажника и несовместим с -txindex. Внимание: переключение этой опции обратно потребует полной загрузки цепи блоков. (по умолчанию: 0 = отключить удаление блоков, &gt;%u = целевой размер в Мб для файлов блоков)</translation>
</message>
<message>
<source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
@@ -2643,6 +2789,14 @@
<translation>Не удалось забиндиться на %s на этом компьютере. Возможно, Bitcoin Core уже запущен.</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ВНИМАНИЕ: сгенерировано ненормально большое число блоков, %d блоков получено за последние %d часов (ожидалось %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>ВНИМАНИЕ: проверьте сетевое подключение, получено %d блоков за последние %d часов (ожидалось %d)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Внимание: установлено очень большое значение -paytxfee. Это комиссия, которую вы заплатите при проведении транзакции.</translation>
</message>
@@ -2759,6 +2913,14 @@
<translation>Соединяться только по сети &lt;net&gt; (ipv4, ipv6 или onion)</translation>
</message>
<message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Удаление блоков не может использовать отрицательное значение.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Режим удаления блоков несовместим с -txindex.</translation>
+ </message>
+ <message>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation>Установить размер кэша БД в мегабайтах(от %d до %d, по умолчанию: %d)</translation>
</message>
@@ -2771,10 +2933,6 @@
<translation>Укажите файл бумажника (внутри каталога данных)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Это рассчитано на инструменты регрессионного тестирования и разработку приложений.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Использовать UPnP для проброса порта (по умолчанию: %u)</translation>
</message>
@@ -2795,6 +2953,10 @@
<translation>Настройки бумажника:</translation>
</message>
<message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Внимание: эта версия устарела; требуется обновление!</translation>
+ </message>
+ <message>
<source>You need to rebuild the database using -reindex to change -txindex</source>
<translation>Вам необходимо пересобрать базы данных с помощью -reindex, чтобы изменить -txindex</translation>
</message>
@@ -2827,6 +2989,10 @@
<translation>Создавать новые файлы с системными правами по умолчанию вместо umask 077 (эффективно только при отключенном бумажнике)</translation>
</message>
<message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Обнаруживать собственный IP адрес (по умолчанию: 1 при прослушивании и без -externalip или -proxy)</translation>
+ </message>
+ <message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Ошибка: не удалось начать прослушивание входящих подключений (прослушивание вернуло ошибку %s)</translation>
</message>
@@ -2843,10 +3009,6 @@
<translation>Комиссии (в BTC/Кб) меньшие этого значения считаются нулевыми для трансляции (по умолчанию: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Комиссии (в BTC/Кб) меньшие этого значения считаются нулевыми для создания транзакции (по умолчанию: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Если paytxfee не задан, включить достаточную комиссию для подтверждения транзакции в среднем за n блоков (по умолчанию: %u)</translation>
</message>
@@ -2859,10 +3021,18 @@
<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>
<message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Использовать случайные учётные данные для каждого прокси-подключения. Эта функция позволяет изолировать потоки Tor (по умолчанию: %u)</translation>
+ </message>
+ <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Задать максимальный размер высокоприоритетных/низкокомиссионных транзакций в байтах (по умолчанию: %d)</translation>
</message>
@@ -2871,6 +3041,10 @@
<translation>Задать число потоков генерации монет, если она включена (-1 = все ядра процессора, по умолчанию: %d)</translation>
</message>
<message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Сумма транзакции за вычетом комиссии слишком мала</translation>
+ </message>
+ <message>
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
<translation>Этот продукт включает ПО, разработанное OpenSSL Project для использования в OpenSSL Toolkit &lt;https://www.openssl.org/&gt; и криптографическое ПО, написанное Eric Young и ПО для работы с UPnP, написанное Thomas Bernard.</translation>
</message>
@@ -2911,10 +3085,26 @@ rpcpassword=%s
<translation>Участники из белого списка не могуть быть забанены за DoS, и их транзакции всегда транслируются, даже если они уже содержатся в памяти. Полезно, например, для шлюза.</translation>
</message>
<message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Вам необходимо пересобрать базу данных с помощью -reindex, чтобы вернуться к полному режиму. Это приведёт к перезагрузке всей цепи блоков</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(по умолчанию: %u)</translation>
+ </message>
+ <message>
<source>Accept public REST requests (default: %u)</source>
<translation>Принимать публичные REST-запросы (по умолчанию: %u)</translation>
</message>
<message>
+ <source>Activating best chain...</source>
+ <translation>Активируется лучшая цепь...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Нельзя работать с бумажником в режиме с удалением блоков.</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>Не удаётся разрешить адрес в параметре -whitebind: '%s'</translation>
</message>
@@ -3003,12 +3193,12 @@ rpcpassword=%s
<translation>Поддержка RPC постоянных HTTP подключений (по умолчанию: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Случайно отбрасывать 1 из каждых &lt;n&gt; сетевых сообщений</translation>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>Перестроить при запуске индекс цепи блоков из текущих файлов blk000??.dat</translation>
</message>
<message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Случайно разбрасывать 1 из каждых &lt;n&gt; сетевых сообщений</translation>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Получать и отображать P2P сетевые тревоги (по умолчанию: %u)</translation>
</message>
<message>
<source>Send trace/debug info to console instead of debug.log file</source>
@@ -3047,6 +3237,10 @@ rpcpassword=%s
<translation>Запускать свёрнутым</translation>
</message>
<message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Сумма транзакции слишком мала для уплаты комиссии</translation>
+ </message>
+ <message>
<source>This is experimental software.</source>
<translation>Это экспериментальное ПО.</translation>
</message>
@@ -3067,6 +3261,10 @@ rpcpassword=%s
<translation>Транзакция слишком большая</translation>
</message>
<message>
+ <source>UI Options:</source>
+ <translation>Настройки интерфейса:</translation>
+ </message>
+ <message>
<source>Unable to bind to %s on this computer (bind returned error %s)</source>
<translation>Невозможно привязаться к %s на этом компьютере (bind вернул ошибку %s)</translation>
</message>
@@ -3147,18 +3345,10 @@ rpcpassword=%s
<translation>(1 = сохранять метаданные транзакции: например, владельца аккаунта и информацию запроса платежа; 2 = отбросить метаданные)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Сбрасывать активность базы данных из памяти на диск каждые &lt;n&gt; мегабайт (по умолчанию: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Насколько тщательна проверка контрольных блоков -checkblocks (0-4, по умолчанию: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Записывать в лог приоритет транзакции и комиссию на килобайт во время добычи блоков (по умолчанию: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Держать полный индекс транзакций, используемый RPC-запросом getrawtransaction (по умолчанию: %u)</translation>
</message>
@@ -3187,18 +3377,10 @@ rpcpassword=%s
<translation>Всегда запрашивать адреса участников с помощью DNS (по умолчанию: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Отключить безопасный режим, перекрыть реальное событие безопасного режима (по умолчанию: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>Ошибка при загрузке wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Принудительный безопасный режим (по умолчанию: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Включить добычу монет (по умолчанию: %u)</translation>
</message>
@@ -3215,10 +3397,6 @@ rpcpassword=%s
<translation>Неверный адрес -proxy: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Ограничить размер кэша подписей &lt;n&gt; записями (по умолчанию: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Прослушивать подключения JSON-RPC на &lt;порту&gt; (по умолчанию: %u или %u в тестовой сети)</translation>
</message>
@@ -3231,6 +3409,10 @@ rpcpassword=%s
<translation>Поддерживать не более &lt;n&gt; подключений к узлам (по умолчанию: %u)</translation>
</message>
<message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Рассылать транзакции из бумажника</translation>
+ </message>
+ <message>
<source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
<translation>Максимальный размер буфера приёма на соединение, &lt;n&gt;*1000 байт (по умолчанию: %u)</translation>
</message>
@@ -3239,10 +3421,6 @@ rpcpassword=%s
<translation>Максимальный размер буфера отправки на соединение, &lt;n&gt;*1000 байт (по умолчанию: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Принимать цепь блоков, лишь если она соответствует встроенным контрольным точкам (по умолчанию: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Дописывать отметки времени к отладочному выводу (по умолчанию: %u)</translation>
</message>
@@ -3255,10 +3433,6 @@ rpcpassword=%s
<translation>Транслировать не-P2SH мультиподпись (по умолчанию: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Запустить поток для периодического сохранения бумажника (по умолчанию: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>Файл сертификата сервера (по умолчанию: %s)</translation>
</message>
@@ -3275,10 +3449,6 @@ rpcpassword=%s
<translation>Задать число потоков выполнения запросов RPC (по умолчанию: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Установить флаг DB_PRIVATE в окружении базы данных бумажника (по умолчанию: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Указать конфигурационный файл (по умолчанию: %s)</translation>
</message>
@@ -3295,10 +3465,6 @@ rpcpassword=%s
<translation>Тратить неподтвержденную сдачу при отправке транзакций (по умолчанию: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Остановиться после импорта блоков с диска (по умолчанию: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Порог для отключения неправильно ведущих себя узлов (по умолчанию: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_sah.ts b/src/qt/locale/bitcoin_sah.ts
index 6cc17f480a..9ca08ee7da 100644
--- a/src/qt/locale/bitcoin_sah.ts
+++ b/src/qt/locale/bitcoin_sah.ts
@@ -1,4 +1,4 @@
-<TS language="sah" version="2.1">
+<TS language="sah" version="2.0">
<context>
<name>AddressBookPage</name>
</context>
diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts
index 8e7d38be00..48d5a09142 100644
--- a/src/qt/locale/bitcoin_sk.ts
+++ b/src/qt/locale/bitcoin_sk.ts
@@ -1,4 +1,4 @@
-<TS language="sk" version="2.1">
+<TS language="sk" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -168,6 +168,10 @@
<translation>Ste si istí, že si želáte zašifrovať peňaženku?</translation>
</message>
<message>
+ <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>Jadro Bitcoin sa teraz ukončí pre dokončenie procesu šifrovania. Pamätaj, že šifrovanie peňaženky Ťa nemôže úplne ochrániť pred krádežou bitcoinov pomocou škodlivého software.</translation>
+ </message>
+ <message>
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
<translation>DÔLEŽITÉ: Všetky doterajšie záložné kópie peňaženky ktoré ste zhotovili by mali byť nahradené novým zašifrovaným súborom s peňaženkou. Z bezpečnostných dôvodov sa predchádzajúce kópie nezašifrovanej peňaženky stanú neužitočné keď začnete používať novú zašifrovanú peňaženku.</translation>
</message>
@@ -184,6 +188,10 @@
<translation>Zadajte nové heslo k peňaženke.&lt;br/&gt;Prosím použite heslo s dĺžkou aspoň &lt;b&gt;10 alebo viac náhodných znakov&lt;/b&gt;, alebo &lt;b&gt;8 alebo viac slov&lt;/b&gt;.</translation>
</message>
<message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Zadajte staré a nové heslo k peňaženke.</translation>
+ </message>
+ <message>
<source>Wallet encryption failed</source>
<translation>Šifrovanie peňaženky zlyhalo</translation>
</message>
@@ -268,7 +276,7 @@
</message>
<message>
<source>&amp;Backup Wallet...</source>
- <translation>&amp;Backup peňaženku...</translation>
+ <translation>&amp;Zálohovať peňaženku...</translation>
</message>
<message>
<source>&amp;Change Passphrase...</source>
@@ -320,7 +328,7 @@
</message>
<message>
<source>&amp;Verify message...</source>
- <translation>Overiť správu</translation>
+ <translation>O&amp;veriť správu...</translation>
</message>
<message>
<source>Bitcoin</source>
@@ -384,13 +392,17 @@
</message>
<message>
<source>Request payments (generates QR codes and bitcoin: URIs)</source>
- <translation>Vyžiadať platbu (vygeneruje QR kód a bitcoin: URI)</translation>
+ <translation>Vyžiadať platby (vygeneruje QR kódy a bitcoin: URI)</translation>
</message>
<message>
<source>&amp;About Bitcoin Core</source>
<translation>O jadre Bitcoin</translation>
</message>
<message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Upraviť možnosti nastavenia pre Jadro Bitcoin</translation>
+ </message>
+ <message>
<source>Show the list of used sending addresses and labels</source>
<translation>Zobraziť zoznam použitých adries odosielateľa a ich popisy</translation>
</message>
@@ -410,14 +422,38 @@
<source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
<translation>Zobraziť pomocnú správu od Bitcoin Jadra pre získanie zoznamu dostupných možností príkazového riadku</translation>
</message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktívne pripojenie do siete Bitcoin</numerusform><numerusform>%n aktívne pripojenia do siete Bitcoin</numerusform><numerusform>%n aktívnych pripojení do siete Bitcoin</numerusform></translation>
+ </message>
<message>
<source>No block source available...</source>
<translation>Nedostupný zdroj blokov...</translation>
</message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Spracovaných %n blok transakčnej histórie.</numerusform><numerusform>Spracovaných %n bloky transakčnej histórie.</numerusform><numerusform>Spracovaných %n blokov transakčnej histórie.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n hodina</numerusform><numerusform>%n hodiny</numerusform><numerusform>%n hodín</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n deň</numerusform><numerusform>%n dni</numerusform><numerusform>%n dní</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n týždeň</numerusform><numerusform>%n týždne</numerusform><numerusform>%n týždňov</numerusform></translation>
+ </message>
<message>
<source>%1 and %2</source>
<translation> %1 a %2</translation>
</message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n rok</numerusform><numerusform>%n roky</numerusform><numerusform>%n rokov</numerusform></translation>
+ </message>
<message>
<source>%1 behind</source>
<translation>%1 pozadu</translation>
@@ -451,12 +487,42 @@
<translation>Sťahujem...</translation>
</message>
<message>
+ <source>Date: %1
+</source>
+ <translation>Dátum: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Suma: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Typ: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Popis: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Adresa: %1
+</translation>
+ </message>
+ <message>
<source>Sent transaction</source>
<translation>Odoslané transakcie</translation>
</message>
<message>
<source>Incoming transaction</source>
- <translation>Prijaté transakcie</translation>
+ <translation>Prijatá transakcia</translation>
</message>
<message>
<source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
@@ -649,6 +715,18 @@
<translation>žiadne</translation>
</message>
<message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Tento popis sčervenie ak veľkosť transakcie presiahne 1000 bajtov.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Tento popis sčervenie ak je priorita nižšia ako "stredná".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Tento popis sčervenie ak ktorýkoľvek príjemca dostane sumu menšiu ako %1.</translation>
+ </message>
+ <message>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation>Môže sa líšiť o +/- %1 satoshi pre každý vstup</translation>
</message>
@@ -825,10 +903,22 @@
<translation>Jadro Bitcoin</translation>
</message>
<message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Chyba: Zadaný priečinok pre dáta "%1" nemôže byť vytvorený.</translation>
+ </message>
+ <message>
<source>Error</source>
<translation>Chyba</translation>
</message>
- </context>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB voľného miesta</numerusform><numerusform>%n GB voľného miesta</numerusform><numerusform>%n GB voľného miesta</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(z %n GB potrebného)</numerusform><numerusform>(z %n GB potrebných)</numerusform><numerusform>(z %n GB potrebných)</numerusform></translation>
+ </message>
+</context>
<context>
<name>OpenURIDialog</name>
<message>
@@ -887,6 +977,14 @@
<translation>IP adresy proxy (napr. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
</message>
<message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Minimalizovať namiesto ukončenia aplikácie keď sa okno zavrie. Keď je zvolená táto možnosť, aplikácia sa zavrie len po zvolení Ukončiť v menu.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Tu sa dá nastaviť jazyk užívateľského rozhrania. Toto nastavenie bude účinné po reštartovaní Jadra Bitcoin.</translation>
+ </message>
+ <message>
<source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
<translation>URL tretích strán (napr. prehliadač blockchain) ktoré sa zobrazujú v záložke transakcií ako položky kontextového menu. %s v URL je nahradené hash-om transakcie. Viaceré URL sú oddelené zvislou čiarou |.</translation>
</message>
@@ -896,7 +994,7 @@
</message>
<message>
<source>Active command-line options that override above options:</source>
- <translation>Aktévne možnosti príkazového riadku ktoré prepíšu možnosti vyššie:</translation>
+ <translation>Aktívne možnosti príkazového riadku ktoré prepíšu možnosti vyššie:</translation>
</message>
<message>
<source>Reset all client options to default.</source>
@@ -911,6 +1009,14 @@
<translation>Sieť</translation>
</message>
<message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Automaticky spustiť Jadro Bitcoin po prihlásení do systému</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Spustiť Bitcoin pri spustení systému správy okien</translation>
+ </message>
+ <message>
<source>(0 = auto, &lt;0 = leave that many cores free)</source>
<translation>(0 = auto, &lt;0 = nechať toľko jadier voľných)</translation>
</message>
@@ -1023,6 +1129,10 @@
<translation>Reštart klienta potrebný pre aktivovanie zmien.</translation>
</message>
<message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Klient bude vypnutý, chcete pokračovať?</translation>
+ </message>
+ <message>
<source>This change would require a client restart.</source>
<translation>Táto zmena by vyžadovala reštart klienta.</translation>
</message>
@@ -1042,6 +1152,10 @@
<translation>Zobrazené informácie môžu byť neaktuálne. Vaša peňaženka sa automaticky synchronizuje so sieťou Bitcoin po nadviazaní spojenia, ale tento proces ešte nie je ukončený.</translation>
</message>
<message>
+ <source>Watch-only:</source>
+ <translation>Iba sledované:</translation>
+ </message>
+ <message>
<source>Available:</source>
<translation>Disponibilné:</translation>
</message>
@@ -1078,10 +1192,30 @@
<translation>Váš súčasný celkový zostatok</translation>
</message>
<message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Váš celkový zostatok pre adresy ktoré sa iba sledujú</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Použiteľné:</translation>
+ </message>
+ <message>
<source>Recent transactions</source>
<translation>Nedávne transakcie</translation>
</message>
- </context>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Nepotvrdené transakcie pre adresy ktoré sa iba sledujú</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Vyťažená suma pre adresy ktoré sa iba sledujú ale ešte nie je dozretá</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Aktuálny celkový zostatok pre adries ktoré sa iba sledujú</translation>
+ </message>
+</context>
<context>
<name>PaymentServer</name>
<message>
@@ -1093,6 +1227,18 @@
<translation>Neplatná adresa platby %1</translation>
</message>
<message>
+ <source>Payment request rejected</source>
+ <translation>Požiadavka na platbu zamietnutá</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Sieť požiadavky na platbu nie je zhodná so sieťou klienta.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Požiadavka na platbu nie je inicializovaná</translation>
+ </message>
+ <message>
<source>Requested payment amount of %1 is too small (considered dust).</source>
<translation>Požadovaná platba sumy %1 je príliš malá (považovaná za prach).</translation>
</message>
@@ -1109,22 +1255,50 @@
<translation>URL pre stiahnutie výzvy na zaplatenie je neplatné: %1</translation>
</message>
<message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI sa nedá analyzovať! To môže byť spôsobené neplatnou Bitcoin adresou alebo zle upravenými vlastnosťami URI.</translation>
+ </message>
+ <message>
<source>Payment request file handling</source>
<translation>Obsluha súboru s požiadavkou na platbu</translation>
</message>
<message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Súbor s výzvou na zaplatenie sa nedá čítať alebo spracovať! To môže byť spôsobené aj neplatným súborom s výzvou.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Vypršala platnosť požiadavky na platbu.</translation>
+ </message>
+ <message>
<source>Unverified payment requests to custom payment scripts are unsupported.</source>
<translation>Program nepodporuje neoverené platobné výzvy na vlastná skripty.</translation>
</message>
<message>
+ <source>Invalid payment request.</source>
+ <translation>Chybná požiadavka na platbu.</translation>
+ </message>
+ <message>
<source>Refund from %1</source>
<translation>Vrátenie z %1</translation>
</message>
<message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Požiadavka na platbu %1 je príliš veľká (%2 bajtov, povolené je %3 bajtov).</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Ochrana pred zahltením požiadavkami na platbu</translation>
+ </message>
+ <message>
<source>Error communicating with %1: %2</source>
<translation>Chyba komunikácie s %1: %2 </translation>
</message>
<message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Požiadavka na platbu nemôže byť analyzovaná!</translation>
+ </message>
+ <message>
<source>Bad response from server %1</source>
<translation>Zlá odpoveď zo servera %1</translation>
</message>
@@ -1144,6 +1318,10 @@
<translation>Aplikácia</translation>
</message>
<message>
+ <source>Node/Service</source>
+ <translation>Uzol/Služba</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Čas odozvy</translation>
</message>
@@ -1159,6 +1337,10 @@
<translation>Zadajte bitcoin adresu (napr. %1)</translation>
</message>
<message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
+ <message>
<source>%1 h</source>
<translation>%1 h</translation>
</message>
@@ -1167,6 +1349,14 @@
<translation>%1 m</translation>
</message>
<message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Žiadne</translation>
+ </message>
+ <message>
<source>N/A</source>
<translation>nie je k dispozícii</translation>
</message>
@@ -1253,6 +1443,10 @@
<translation>Aktuálny počet blokov</translation>
</message>
<message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Otvoriť Bitcoin log súbor pre ladenie z aktuálneho dátového adresára. Toto môže trvať niekoľko sekúnd pre veľké súbory.</translation>
+ </message>
+ <message>
<source>Received</source>
<translation>Prijaté</translation>
</message>
@@ -1261,6 +1455,10 @@
<translation>Odoslané</translation>
</message>
<message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Partneri</translation>
+ </message>
+ <message>
<source>Select a peer to view detailed information.</source>
<translation>Vyberte počítač pre zobrazenie podrobností.</translation>
</message>
@@ -1285,10 +1483,26 @@
<translation>Počiatočná výška</translation>
</message>
<message>
+ <source>Sync Height</source>
+ <translation>Synchronizovaná výška</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Skóre zákazu</translation>
+ </message>
+ <message>
<source>Connection Time</source>
<translation>Dĺžka spojenia</translation>
</message>
<message>
+ <source>Last Send</source>
+ <translation>Posledné odoslanie</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Posledné prijatie</translation>
+ </message>
+ <message>
<source>Bytes Sent</source>
<translation>Odoslaných bajtov</translation>
</message>
@@ -1301,6 +1515,10 @@
<translation>Čas odozvy</translation>
</message>
<message>
+ <source>Time Offset</source>
+ <translation>Časový posun</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Čas posledného bloku</translation>
</message>
@@ -1345,6 +1563,10 @@
<translation>Vymazať konzolu</translation>
</message>
<message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Vitajte v RPC konzole pre Jadro Bitcoin.</translation>
+ </message>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
<translation>Použi šípky hore a dolu pre navigáciu históriou a &lt;b&gt;Ctrl-L&lt;/b&gt; pre vyčistenie obrazovky.</translation>
</message>
@@ -1369,6 +1591,14 @@
<translation>%1 GB</translation>
</message>
<message>
+ <source>via %1</source>
+ <translation>cez %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>nikdy</translation>
+ </message>
+ <message>
<source>Inbound</source>
<translation>Prichádzajúce</translation>
</message>
@@ -1377,6 +1607,10 @@
<translation>Odchádzajúce</translation>
</message>
<message>
+ <source>Unknown</source>
+ <translation>neznámy</translation>
+ </message>
+ <message>
<source>Fetching...</source>
<translation>Získava sa...</translation>
</message>
@@ -1613,6 +1847,10 @@
<translation>Poplatok za transakciu:</translation>
</message>
<message>
+ <source>Choose...</source>
+ <translation>Zvoliť...</translation>
+ </message>
+ <message>
<source>collapse fee-settings</source>
<translation>zbaliť nastavenia poplatkov</translation>
</message>
@@ -1625,6 +1863,10 @@
<translation>Ak je poplatok nastavený na 1000 satoshi a transakcia je veľká len 250 bajtov, potom "za kilobajt" zaplatí poplatok 250 satoshi, ale "spolu aspoň" zaplatí 1000 satoshi. Pre transakcie väčšie ako kilobajt platia oba spôsoby za každý kilobajt.</translation>
</message>
<message>
+ <source>Hide</source>
+ <translation>Skryť</translation>
+ </message>
+ <message>
<source>total at least</source>
<translation>spolu aspoň</translation>
</message>
@@ -1686,7 +1928,7 @@
</message>
<message>
<source>Clear &amp;All</source>
- <translation>Zmazať &amp;všetko</translation>
+ <translation>&amp;Zmazať všetko</translation>
</message>
<message>
<source>Balance:</source>
@@ -1765,10 +2007,26 @@
<translation>Transakcia bola zamietnutá! Toto sa môže stať ak niektoré coins vo vašej peňaženke už boli minuté, ako keď použijete kópiu wallet.dat a coins boli minuté z kópie ale neoznačené ako minuté tu.</translation>
</message>
<message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Poplatok vyšší ako %1 je považovaný za šialene vysoký.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Vypršala platnosť požiadavky na platbu.</translation>
+ </message>
+ <message>
<source>Pay only the minimum fee of %1</source>
<translation>Zaplatiť minimálny poplatok %1</translation>
</message>
<message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Adresa príjemcu je neplatná. Prosím, overte ju.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Našla sa duplicitná adresa: každú adresu je možné použiť len raz.</translation>
+ </message>
+ <message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Varovanie: Nesprávna Bitcoin adresa</translation>
</message>
@@ -1820,6 +2078,10 @@
<translation>Toto je normálna platba.</translation>
</message>
<message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Zvoľte adresu kam poslať platbu</translation>
+ </message>
+ <message>
<source>Alt+A</source>
<translation>Alt+A</translation>
</message>
@@ -1836,10 +2098,22 @@
<translation>Odstrániť túto položku</translation>
</message>
<message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>Odpočítať poplatok od s&amp;umy</translation>
+ </message>
+ <message>
<source>Message:</source>
<translation>Správa:</translation>
</message>
<message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Toto je neoverená výzva k platbe.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Toto je overená výzva k platbe.</translation>
+ </message>
+ <message>
<source>Enter a label for this address to add it to the list of used addresses</source>
<translation>Vložte popis pre túto adresu aby sa uložila do zoznamu použitých adries</translation>
</message>
@@ -1919,11 +2193,15 @@
</message>
<message>
<source>Clear &amp;All</source>
- <translation>Zmazať &amp;všetko</translation>
+ <translation>&amp;Zmazať všetko</translation>
</message>
<message>
<source>&amp;Verify Message</source>
- <translation>Overiť správu...</translation>
+ <translation>O&amp;veriť správu...</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Adresa Bitcoin, ktorou bola podpísaná správa</translation>
</message>
<message>
<source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
@@ -1931,7 +2209,7 @@
</message>
<message>
<source>Verify &amp;Message</source>
- <translation>Overiť správu</translation>
+ <translation>&amp;Overiť správu</translation>
</message>
<message>
<source>Reset all verify message fields</source>
@@ -2038,6 +2316,10 @@
<source>Status</source>
<translation>Stav</translation>
</message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, vysielať cez %n uzol</numerusform><numerusform>, vysielať cez %n uzle</numerusform><numerusform>, vysielať cez %n uzolov</numerusform></translation>
+ </message>
<message>
<source>Date</source>
<translation>Dátum</translation>
@@ -2063,6 +2345,10 @@
<translation>vlastná adresa</translation>
</message>
<message>
+ <source>watch-only</source>
+ <translation>Iba sledovanie</translation>
+ </message>
+ <message>
<source>label</source>
<translation>popis</translation>
</message>
@@ -2079,6 +2365,14 @@
<translation>Debet</translation>
</message>
<message>
+ <source>Total debit</source>
+ <translation>Debit spolu</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Kredit spolu</translation>
+ </message>
+ <message>
<source>Transaction fee</source>
<translation>Transakčný poplatok</translation>
</message>
@@ -2104,7 +2398,7 @@
</message>
<message>
<source>Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source>
- <translation>Vytvorené coins musia dospieť %1 blokov kým môžu byť minuté. Keď vytvoríte tento blok, bude rozoslaný do siete aby bol akceptovaný do reťaze blokov. Ak sa nedostane reťaze, jeho stav sa zmení na "zamietnutý" a nebude sa dať minúť. Toto sa môže občas stať ak iná nóda vytvorí blok približne v tom istom čase.</translation>
+ <translation>Vygenerované mince musia dospieť %1 blokov kým môžu byť minuté. Keď vytvoríte tento blok, bude rozoslaný do siete aby bol akceptovaný do reťaze blokov. Ak sa nedostane do reťazca, jeho stav sa zmení na "zamietnutý" a nebude sa dať minúť. Toto sa môže občas stať ak iný uzol vytvorí blok približne v rovnakom čase.</translation>
</message>
<message>
<source>Debug information</source>
@@ -2134,6 +2428,10 @@
<source>, has not been successfully broadcast yet</source>
<translation>, ešte nebola úspešne odoslaná</translation>
</message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Otvorené pre %n ďalší blok</numerusform><numerusform>Otvorené pre %n ďalšie bloky</numerusform><numerusform>Otvorené pre %n ďalších blokov</numerusform></translation>
+ </message>
<message>
<source>unknown</source>
<translation>neznámy</translation>
@@ -2164,6 +2462,10 @@
<source>Immature (%1 confirmations, will be available after %2)</source>
<translation>Nezrelé (%1 potvrdení, bude k dispozícii po %2)</translation>
</message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Otvorené pre %n ďalší blok</numerusform><numerusform>Otvorené pre %n ďalšie bloky</numerusform><numerusform>Otvorené pre %n ďalších blokov</numerusform></translation>
+ </message>
<message>
<source>Open until %1</source>
<translation>Otvorené do %1</translation>
@@ -2178,7 +2480,7 @@
</message>
<message>
<source>Generated but not accepted</source>
- <translation>Vypočítané ale neakceptované</translation>
+ <translation>Vygenerované ale neakceptované</translation>
</message>
<message>
<source>Offline</source>
@@ -2218,7 +2520,11 @@
</message>
<message>
<source>Mined</source>
- <translation>Vyfárané</translation>
+ <translation>Vyťažené</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>Iba sledovanie</translation>
</message>
<message>
<source>(n/a)</source>
@@ -2237,6 +2543,10 @@
<translation>Typ transakcie.</translation>
</message>
<message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Či sú ale nie sú, adresy iba na sledovanie zahrnuté v tejto transakcii.</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
<translation>Suma pridaná alebo odobraná k zostatku.</translation>
</message>
@@ -2285,7 +2595,7 @@
</message>
<message>
<source>Mined</source>
- <translation>Vyfárané</translation>
+ <translation>Vyťažené</translation>
</message>
<message>
<source>Other</source>
@@ -2328,6 +2638,10 @@
<translation>Exportovať históriu transakcií</translation>
</message>
<message>
+ <source>Watch-only</source>
+ <translation>Iba sledovanie</translation>
+ </message>
+ <message>
<source>Exporting Failed</source>
<translation>Export zlyhal</translation>
</message>
@@ -2382,7 +2696,11 @@
</context>
<context>
<name>UnitDisplayStatusBarControl</name>
- </context>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Jednotka pre zobrazovanie súm. Kliknite pre zvolenie inej jednotky.</translation>
+ </message>
+</context>
<context>
<name>WalletFrame</name>
<message>
@@ -2471,16 +2789,16 @@
<translation>Spojiť s danou adresou a vždy na nej počúvať. Použite zápis [host]:port pre IPv6</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Vojsť do režimu regresného testovania, ktorý používa špeciálnu reťaz v ktorej môžu byť bloky v okamihu vyriešené.</translation>
+ <source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
+ <translation>Vymazať všetky transakcie z peňaženky a pri spustení znova získať z reťazca blokov iba tie získané pomocou -rescan</translation>
</message>
<message>
- <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
- <translation>Vykonaj príkaz keď sa zmení transakcia peňaženky (%s v príkaze je nahradená TxID)</translation>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuované pod softvérovou licenciou MIT, viď sprievodný súbor COPYING alebo &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>V tomto režime -getproclimit kontroluje koľko blokov sa vytvorí okamžite.</translation>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Vykonaj príkaz keď sa zmení transakcia peňaženky (%s v príkaze je nahradená TxID)</translation>
</message>
<message>
<source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
@@ -2517,6 +2835,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin
<translation>Varovanie: wallet.dat je poškodený, údaje úspešne získané! Pôvodný wallet.dat uložený ako wallet.{timestamp}.bak v %s; ak váš zostatok alebo transakcie niesu správne, mali by ste súbor obnoviť zo zálohy.</translation>
</message>
<message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Uzle na zoznam povolených, ktoré sa pripájajú z danej netmask alebo IP adresy. Môže byť zadané viac krát.</translation>
+ </message>
+ <message>
<source>(default: 1)</source>
<translation>(predvolené: 1)</translation>
</message>
@@ -2573,6 +2895,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin
<translation>Chyba otvárania databázy blokov</translation>
</message>
<message>
+ <source>Error: A fatal internal error occured, see debug.log for details</source>
+ <translation>Chyba: Nastala fatálna interná chyba. Pre podrobnosti pozrite debug.log</translation>
+ </message>
+ <message>
<source>Error: Disk space is low!</source>
<translation>Chyba: Málo miesta na disku!</translation>
</message>
@@ -2601,6 +2927,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin
<translation>Nedostatok kľúčových slov súboru.</translation>
</message>
<message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Pripojiť iba k uzlom v sieti &lt;net&gt; (ipv4, ipv6, alebo onion)</translation>
+ </message>
+ <message>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation>Nastaviť veľkosť pomocnej pamäti databázy v megabajtoch (%d do %d, prednastavené: %d)</translation>
</message>
@@ -2613,8 +2943,8 @@ The network does not appear to fully agree! Some miners appear to be experiencin
<translation>Označ súbor peňaženky (v priečinku s dátami)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Toto je mienené nástrojom pre regresné testovania a vývoj programu.</translation>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Použiť UPnP pre mapovanie počúvajúceho portu (predvolené: %u)</translation>
</message>
<message>
<source>Verifying blocks...</source>
@@ -2641,14 +2971,38 @@ The network does not appear to fully agree! Some miners appear to be experiencin
<translation>Importuje bloky z externého súboru blk000??.dat</translation>
</message>
<message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; 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 &lt;ip&gt; sú platné jednoduché IP (napr. 1.2.3.4), sieť/netmask (napr. 1.2.3.4/255.255.255.0) alebo sieť/CIDR (napr. 1.2.3.4/24). Táto možnosť môže byť zadaná niekoľko krát</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Pri nastavovaní RPC adresy %s na porte %u pre počúvanie došlo k chybe: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Spojiť s danou adresou a povolenými partnerskými zariadeniami ktoré sa tam pripájajú. Použite zápis [host]:port pre IPv6</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Spojiť s danou adresou pre počúvanie JSON-RPC spojení. Použite zápis [host]:port pre IPv6. Táto možnosť môže byt zadaná niekoľko krát (predvolené: spojiť so všetkými rozhraniami)</translation>
+ </message>
+ <message>
<source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
<translation>Neviem uzamknúť data adresár %s. Jadro Bitcoin je pravdepodobne už spustené.</translation>
</message>
<message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Vytvoriť nové súbory z predvolenými systémovými právami, namiesto umask 077 (funguje iba z vypnutou funkcionalitou peňaženky)</translation>
+ </message>
+ <message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Chyba: Počúvanie prichádzajúcich spojení zlyhalo (vrátená chyba je %s)</translation>
</message>
<message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Chyba: Nájdený nepodporovaný argument -socks. Nastavenie SOCKS verzie nie je už možné, podporované sú už iba proxy SOCKS5.</translation>
+ </message>
+ <message>
<source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
<translation>Vykonať príkaz po prijatí patričného varovania alebo uvidíme veľmi dlhé rozdvojenie siete (%s v cmd je nahradené správou)</translation>
</message>
@@ -2657,14 +3011,54 @@ The network does not appear to fully agree! Some miners appear to be experiencin
<translation>Poplatky (v BTC/Kb) nižšie ako toľkoto sa považujú za nulové pri postupovaní transakcií (predvolené: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Poplatky (v BTC/Kb) nižšie ako toľkoto sa považujú za nulové pri vytváraní transakcií (predvolené: %s)</translation>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Ak nie je nastavené paytxfee, pridať dostatočný poplatok aby sa transakcia začala potvrdzovať priemerne v rámci bloku (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Neplatná suma pre -maxtxfee=&lt;amount&gt;: '%s' (aby sa transakcia nezasekla, minimálny prenosový poplatok musí byť aspoň %s)</translation>
+ </message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maximálna veľkosť dát v transakciách nosných dát, ktoré prenášame a ťažíme (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Dotaz na partnerské adresy pomocou vyhľadávania DNS v prípade nedostatku adries (predvolené: 1, pokiaľ -connect)</translation>
</message>
<message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Nastaviť najväčšiu veľkosť vysoká-dôležitosť/nízke-poplatky transakcií v bajtoch (prednastavené: %d)</translation>
</message>
<message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Nastaviť počet vlákien pre generáciu mincí (-1 = všetky jadrá, predvolené: %d)</translation>
+ </message>
+ <message>
+ <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
+ <translation>Tento produkt obsahuje softvér vyvinutý projektom OpenSSL pre použitie sady nástrojov OpenSSL &lt;https://www.openssl.org/&gt; a kryptografického softvéru napísaného Eric Young a UPnP softvér napísaný Thomas Bernard.</translation>
+ </message>
+ <message>
+ <source>Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
+ <translation>Upozornenie: -maxtxfee je nastavené príliš vysoko! Takto vysoké poplatky by mali byť zaplatené za jednu transakciu.</translation>
+ </message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>Uzle na zoznam povolených nemôžu byť DoS zakázané a ich transakcie vždy postúpené ďalej, aj v prípade, ak sú už pamäťovej fronte. Užitočné napr. pre brány</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Accept public REST requests (default: %u)</source>
+ <translation>Akceptovať verejné REST žiadosti (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Nedá sa vyriešiť -whitebind adresa: '%s'</translation>
+ </message>
+ <message>
<source>Choose data directory on startup (default: 0)</source>
<translation>Zvoľte dátový priečinok pri štarte (prednastavené: 0)</translation>
</message>
@@ -2673,10 +3067,26 @@ The network does not appear to fully agree! Some miners appear to be experiencin
<translation>Pripojiť cez proxy server SOCKS5</translation>
</message>
<message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Autorské práva (C) 2009-%i Vývojári jadra Bitcoin</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Nedá sa analyzovať -rpcbind hodnota %s ako sieťová adresa</translation>
+ </message>
+ <message>
<source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
<translation>Chyba pri čítaní wallet.dat: Peňaženka vyžaduje vyššiu verziu Jadra Bitcoin</translation>
</message>
<message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Chyba pri načítaní z databázy, ukončuje sa.</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Chyba: nájdený nepodporovaný argument -tor, použite -onion.</translation>
+ </message>
+ <message>
<source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
<translation>Poplatok (v BTC/kB), ktorý sa pridá k transakciám, ktoré odosielate (predvolený: %s)</translation>
</message>
@@ -2685,6 +3095,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin
<translation>Informácia</translation>
</message>
<message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
+ <translation>Neplatná suma pre -maxtxfee=&lt;amount&gt;: '%s'</translation>
+ </message>
+ <message>
<source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
<translation>Neplatná suma pre -minrelaytxfee=&lt;amount&gt;: '%s'</translation>
</message>
@@ -2693,6 +3107,26 @@ The network does not appear to fully agree! Some miners appear to be experiencin
<translation>Neplatná suma pre -mintxfee=&lt;amount&gt;: '%s'</translation>
</message>
<message>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s' (must be at least %s)</source>
+ <translation>Neplatná suma pre -paytxfee=&lt;amount&gt;: '%s' (musí byť aspoň %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Nadaná neplatná netmask vo -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation>V pamäti udržiavať najviac &lt;n&gt; nepotvrdených transakcií (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Je potrebné zadať port s -whitebind: '%s'</translation>
+ </message>
+ <message>
+ <source>Node relay options:</source>
+ <translation>Prenosové možnosti uzla:</translation>
+ </message>
+ <message>
<source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
<translation>Možnosti RPC SSL: (Pozri v Bitcoin Wiki pokyny pre SSL nastavenie)</translation>
</message>
@@ -2701,12 +3135,12 @@ The network does not appear to fully agree! Some miners appear to be experiencin
<translation>Možnosti servra RPC:</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Náhodne zahadzuj 1 z každých &lt;n&gt; sieťových správ</translation>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Podpora RPC pre trvalé HTTP spojenia (predvolené: %d)</translation>
</message>
<message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Náhodne premiešaj 1 z každých &lt;n&gt; sieťových správ</translation>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Obdržať a zobraziť sieťové P2P varovania (predvolené: %u)</translation>
</message>
<message>
<source>Send trace/debug info to console instead of debug.log file</source>
@@ -2765,6 +3199,14 @@ The network does not appear to fully agree! Some miners appear to be experiencin
<translation>Transakcia príliš veľká</translation>
</message>
<message>
+ <source>UI Options:</source>
+ <translation>Možnosti používateľského rozhrania:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Na tomto počítači sa nedá vytvoriť väzba %s (vytvorenie väzby vrátilo chybu %s)</translation>
+ </message>
+ <message>
<source>Use UPnP to map the listening port (default: 1 when listening)</source>
<translation>Skúsiť použiť UPnP pre mapovanie počúvajúceho portu (default: 1 when listening)</translation>
</message>
@@ -2777,6 +3219,14 @@ 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>
@@ -2825,26 +3275,130 @@ The network does not appear to fully agree! Some miners appear to be experiencin
<translation>Chyba načítania wallet.dat: Peňaženka je poškodená</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Zaznamenať prioritu transakcie a poplatok za kB pri ťažení blokov (predvolené: %u)</translation>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = zachovať metaúdaje tx napr. vlastníka účtu a informácie o platobných príkazoch, 2 = zahodiť metaúdaje tx)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Ako dôkladné je -checkblocks overenie blokov (0-4, predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Udržiavať kompletný transakčný index, využíva getrawtransaction rpc volanie (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Počet sekúnd, počas ktorých nepripájať zle správajúce sa uzle (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying &lt;category&gt; is optional)</source>
+ <translation>Výstupné ladiace informácie (predvolené: %u, dodanie &lt;category&gt; je voliteľné)</translation>
</message>
<message>
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
<translation>Použiť samostatný SOCKS5 proxy server na dosiahnutie počítačov cez skryté služby Tor (predvolené: %s)</translation>
</message>
<message>
+ <source>(default: %s)</source>
+ <translation>(predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Prijateľné šifry (predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Vždy sa dotazovať adresy partnerských uzlov cez vyhľadávanie DNS (predvolené: %u)</translation>
+ </message>
+ <message>
<source>Error loading wallet.dat</source>
<translation>Chyba načítania wallet.dat</translation>
</message>
<message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Koľko blokov overiť pri spustení (predvolené: %u, 0 = všetky)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Zahrnúť IP adresy v ladiacom výstupe (predvolené: %u)</translation>
+ </message>
+ <message>
<source>Invalid -proxy address: '%s'</source>
<translation>Neplatná adresa proxy: '%s'</translation>
</message>
<message>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Počúvať JSON-RPC pripojenia na &lt;port&gt; (predvolené: %u alebo testovacia sieť: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on &lt;port&gt; (default: %u or testnet: %u)</source>
+ <translation>Počúvať pripojenia na &lt;port&gt; (predvolené: %u alebo testovacia sieť: %u)</translation>
+ </message>
+ <message>
<source>Maintain at most &lt;n&gt; connections to peers (default: %u)</source>
<translation>Udržiavať najviac &lt;n&gt; spojení s inými počítačmi (predvolené: %u)</translation>
</message>
<message>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximálna prijímajúca medzipamäť pre pripojenie, &lt;n&gt;*1000 bajtov (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
+ <translation>Maximálna odosielajúca medzipamäť pre pripojenie, &lt;n&gt;*1000 bajtov (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Na začiatok pripojiť časovú známku k ladiacemu výstupu (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Prenášať a ťažiť transakcie nosných dát (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Prenášať non-P2SH multi-podpis (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Certifikačný súbor servera (predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Privátny kľúč servera (predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to &lt;n&gt; (default: %u)</source>
+ <translation>Nastaviť veľkosť kľúča fronty na &lt;n&gt; (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Nastaviť minimálnu veľkosť bloku v bajtoch (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Nastaviť počet vlákien na obsluhu RPC volaní (predvolené: %d)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Zadať konfiguračný súbor (predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Zadajte časový limit pripojenia v milisekundách (minimum: 1, predvolené: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Zadať pid súbor (predvolené: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Minúť nepotvrdené zmenu pri posielaní transakcií (predvolené: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Hranica pre odpájanie zle sa správajúcim partnerským uzlom (predvolené: %u)</translation>
+ </message>
+ <message>
<source>Unknown network specified in -onlynet: '%s'</source>
<translation>Neznáma sieť upresnená v -onlynet: '%s'</translation>
</message>
diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts
index abbdba3760..39dcb6e997 100644
--- a/src/qt/locale/bitcoin_sl_SI.ts
+++ b/src/qt/locale/bitcoin_sl_SI.ts
@@ -1,7 +1,11 @@
-<TS language="sl_SI" version="2.1">
+<TS language="sl_SI" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
+ <source>Right-click to edit address or label</source>
+ <translation>Desni klik za urejanje naslovov ali oznak</translation>
+ </message>
+ <message>
<source>Create a new address</source>
<translation>Ustvari nov naslov</translation>
</message>
@@ -19,7 +23,7 @@
</message>
<message>
<source>C&amp;lose</source>
- <translation>&amp;Zapri (close)</translation>
+ <translation>&amp;Zapri</translation>
</message>
<message>
<source>&amp;Copy Address</source>
@@ -31,7 +35,7 @@
</message>
<message>
<source>Export the data in the current tab to a file</source>
- <translation>Izvozi podatke v trenutni zavih v datoteko</translation>
+ <translation>Izvozi podatke v trenutnem zavihku v datoteko</translation>
</message>
<message>
<source>&amp;Export</source>
@@ -39,15 +43,15 @@
</message>
<message>
<source>&amp;Delete</source>
- <translation>&amp;Zbriši</translation>
+ <translation>I&amp;zbriši</translation>
</message>
<message>
<source>Choose the address to send coins to</source>
- <translation>Izberi naslov prejemnika kovancev</translation>
+ <translation>Izbira naslova, na katerega pošiljate plačilo</translation>
</message>
<message>
<source>Choose the address to receive coins with</source>
- <translation>Izberi naslov pošiljatelja kovancev</translation>
+ <translation>Izbira naslova za prejem plačila</translation>
</message>
<message>
<source>C&amp;hoose</source>
@@ -55,19 +59,19 @@
</message>
<message>
<source>Sending addresses</source>
- <translation>Naslovi za pošiljanje</translation>
+ <translation>Imenik naslovov za pošiljanje</translation>
</message>
<message>
<source>Receiving addresses</source>
- <translation>Naslovi za prejemanje</translation>
+ <translation>Imenik naslovov za prejemanje</translation>
</message>
<message>
<source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
- <translation>To so tvoji Bitcoin naslovi za pošiljanje plačil. Vedno preveri znesek in prejemnikov naslov pred pošiljanjem kovancev.</translation>
+ <translation>To je vaš imenik shranjenih naslovov Bitcoin, na katere lahko pošiljate plačila. Pred vsakim odlivom vedno preverite, če sta znesek in prejemnikov naslov pravilna.</translation>
</message>
<message>
<source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
- <translation>To so tvoji Bitcoin naslovi za prejemanje plačil. Priporočljivo je uporabljati nov prejemni naslov za vsako izmed transakcij.</translation>
+ <translation>To je imenik vaših ustvarjenih naslovov Bitcoin, na katere lahko prejemate plačila. Priporočljivo je, da za vsak nov priliv ustvarite nov prejemni naslov.</translation>
</message>
<message>
<source>Copy &amp;Label</source>
@@ -87,9 +91,13 @@
</message>
<message>
<source>Exporting Failed</source>
- <translation>Neuspešen izvoz</translation>
+ <translation>Seznama naslovov ni bilo mogoče izvoziti.</translation>
</message>
- </context>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Napaka pri shranjevanju seznama naslovov v datoteko %1. Prosimo, poskusite znova.</translation>
+ </message>
+</context>
<context>
<name>AddressTableModel</name>
<message>
@@ -102,14 +110,14 @@
</message>
<message>
<source>(no label)</source>
- <translation>(ni oznake)</translation>
+ <translation>(brez oznake)</translation>
</message>
</context>
<context>
<name>AskPassphraseDialog</name>
<message>
<source>Passphrase Dialog</source>
- <translation>Poziv gesla</translation>
+ <translation>Vnos gesla</translation>
</message>
<message>
<source>Enter passphrase</source>
@@ -149,49 +157,69 @@
</message>
<message>
<source>Confirm wallet encryption</source>
- <translation>Potrdi šifriranje denarnice</translation>
+ <translation>Potrditev šifriranja denarnice</translation>
</message>
<message>
<source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
- <translation>Opozorilo: V primeru izgube gesla kriptirane denarnice, boš &lt;b&gt;IZGUBIL VSE SVOJE BITCOINE&lt;/b&gt;!</translation>
+ <translation>Opozorilo: V primeru izgube gesla šifrirane denarnice, boste &lt;b&gt;IZGUBILI VSE BITCOINE V DENARNICI&lt;/b&gt;!</translation>
</message>
<message>
<source>Are you sure you wish to encrypt your wallet?</source>
<translation>Ali ste prepričani, da želite šifrirati vašo denarnico?</translation>
</message>
<message>
+ <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>Program se bo zaprl, da dokonča proces šifriranja. Zapomnite si, da šifriranje ne more popolnoma zaščititi vaše denarnice pred krajami in zlonamernimi programi, ki bi lahko bili nameščeni na vašem računalniku.</translation>
+ </message>
+ <message>
+ <source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
+ <translation>POMEMBNO: Vse starejše obstoječe varnostne kopije denarnice je potrebno zamenjati s to novo, šifrirano varnostno kopijo. Iz varnostnih razlogov bodo stare varnostne kopije postale neuporabne takoj, ko začnete uporabljati novo, šifrirano denarnico.</translation>
+ </message>
+ <message>
<source>Warning: The Caps Lock key is on!</source>
- <translation>Opozorilo: imate prižgan Cap Lock</translation>
+ <translation>Opozorilo: imate vklopljene velike črke (Caps Lock)</translation>
</message>
<message>
<source>Wallet encrypted</source>
- <translation>Denarnica šifrirana</translation>
+ <translation>Denarnica je šifrirana</translation>
+ </message>
+ <message>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Vnesite novo geslo. Prosimo, da uporabite geslo sestavljeno iz &lt;b&gt;deset ali več&lt;/b&gt; naključnih znakov, ali &lt;b&gt;osem ali več&lt;/b&gt; besed.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Vnesite staro in novo geslo denarnice.</translation>
</message>
<message>
<source>Wallet encryption failed</source>
- <translation>Šifriranje denarnice spodletelo</translation>
+ <translation>Denarnice ni bilo mogoče šifrirati.</translation>
</message>
<message>
<source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
- <translation>Šifriranje denarnice spodletelo zaradi notranje napake. Vaša denarnica ni šifrirana.</translation>
+ <translation>Prišlo je do napake. Denarnice ni bilo mogoče šifrirati.</translation>
</message>
<message>
<source>The supplied passphrases do not match.</source>
- <translation>Vnešeno geslo se ne ujema</translation>
+ <translation>Vnešeni gesli se ne ujemata</translation>
</message>
<message>
<source>Wallet unlock failed</source>
- <translation>Odklep denarnice spodletel</translation>
+ <translation>Denarnice ni bilo mogoče odkleniti.</translation>
</message>
<message>
<source>The passphrase entered for the wallet decryption was incorrect.</source>
- <translation>Geslo za dešifriranje denarnice, ki ste ga vnesli, ni pravilno.</translation>
+ <translation>Vnesli ste napačno geslo za dešifriranje denarnice.</translation>
</message>
<message>
<source>Wallet decryption failed</source>
- <translation>Dešifriranje denarnice spodletelo</translation>
+ <translation>Denarnice ni bilo mogoče dešifrirati.</translation>
</message>
- </context>
+ <message>
+ <source>Wallet passphrase was successfully changed.</source>
+ <translation>Geslo za dostop do denarnice je bilo uspešno zamenjano.</translation>
+ </message>
+</context>
<context>
<name>BitcoinGUI</name>
<message>
@@ -200,11 +228,11 @@
</message>
<message>
<source>Synchronizing with network...</source>
- <translation>Sinhroniziranje z omrežjem ...</translation>
+ <translation>Dohitevam omrežje ...</translation>
</message>
<message>
<source>&amp;Overview</source>
- <translation>&amp;Pregled</translation>
+ <translation>Pre&amp;gled</translation>
</message>
<message>
<source>Node</source>
@@ -212,7 +240,7 @@
</message>
<message>
<source>Show general overview of wallet</source>
- <translation>Pokaži splošen pregled denarnice</translation>
+ <translation>Oglejte si splošne informacije o vaši denarnici</translation>
</message>
<message>
<source>&amp;Transactions</source>
@@ -220,7 +248,7 @@
</message>
<message>
<source>Browse transaction history</source>
- <translation>Brskaj po zgodovini transakcij</translation>
+ <translation>Brskajte po zgodovini transakcij</translation>
</message>
<message>
<source>E&amp;xit</source>
@@ -228,7 +256,7 @@
</message>
<message>
<source>Quit application</source>
- <translation>Izhod iz aplikacije</translation>
+ <translation>Ustavite program</translation>
</message>
<message>
<source>About &amp;Qt</source>
@@ -236,7 +264,7 @@
</message>
<message>
<source>Show information about Qt</source>
- <translation>Prikaži informacije o Qt</translation>
+ <translation>Oglejte si informacije o Qt</translation>
</message>
<message>
<source>&amp;Options...</source>
@@ -248,7 +276,7 @@
</message>
<message>
<source>&amp;Backup Wallet...</source>
- <translation>&amp;Napravi varnostno kopijo denarnice ...</translation>
+ <translation>Shrani &amp;varnostno kopijo denarnice ...</translation>
</message>
<message>
<source>&amp;Change Passphrase...</source>
@@ -256,15 +284,15 @@
</message>
<message>
<source>&amp;Sending addresses...</source>
- <translation>&amp;Pošiljanje naslovov...</translation>
+ <translation>Naslovi za po&amp;šiljanje ...</translation>
</message>
<message>
<source>&amp;Receiving addresses...</source>
- <translation>&amp;Prejemanje naslovov...</translation>
+ <translation>Naslovi za &amp;prejemanje...</translation>
</message>
<message>
<source>Open &amp;URI...</source>
- <translation>Odpri &amp;URI...</translation>
+ <translation>Odpri &amp;URI ...</translation>
</message>
<message>
<source>Bitcoin Core client</source>
@@ -272,23 +300,23 @@
</message>
<message>
<source>Importing blocks from disk...</source>
- <translation>Uvažam bloke z diska...</translation>
+ <translation>Uvažam bloke z diska ...</translation>
</message>
<message>
<source>Reindexing blocks on disk...</source>
- <translation>Poustvarjam kazalo blokov na disku...</translation>
+ <translation>Poustvarjam kazalo blokov na disku ...</translation>
</message>
<message>
<source>Send coins to a Bitcoin address</source>
- <translation>Pošlji kovance na Bitcoin naslov</translation>
+ <translation>Izvedite plačilo na naslov Bitcoin</translation>
</message>
<message>
<source>Backup wallet to another location</source>
- <translation>Napravi varnostno kopijo denarnice na drugo lokacijo</translation>
+ <translation>Shranite varnostno kopijo svoje denarnice na drugo lokacijo</translation>
</message>
<message>
<source>Change the passphrase used for wallet encryption</source>
- <translation>Spremeni šifrirno geslo denarnice</translation>
+ <translation>Spremenite geslo za šifriranje denarnice</translation>
</message>
<message>
<source>&amp;Debug window</source>
@@ -296,7 +324,11 @@
</message>
<message>
<source>Open debugging and diagnostic console</source>
- <translation>Odpri razhroščevalno in diagnostično konzolo</translation>
+ <translation>Odprite razhroščevalno in diagnostično konzolo</translation>
+ </message>
+ <message>
+ <source>&amp;Verify message...</source>
+ <translation>&amp;Preveri sporočilo ...</translation>
</message>
<message>
<source>Bitcoin</source>
@@ -312,11 +344,11 @@
</message>
<message>
<source>&amp;Receive</source>
- <translation>&amp;Sprejmi</translation>
+ <translation>P&amp;rejmi</translation>
</message>
<message>
<source>Show information about Bitcoin Core</source>
- <translation>Pokaži informacije o Bitcoin Core</translation>
+ <translation>Oglejte si informacije o programu</translation>
</message>
<message>
<source>&amp;Show / Hide</source>
@@ -328,11 +360,15 @@
</message>
<message>
<source>Encrypt the private keys that belong to your wallet</source>
- <translation>Šifiraj zasebne ključe v moji denarnici</translation>
+ <translation>Šifrirajte zasebne ključe, ki se nahajajo v denarnici</translation>
</message>
<message>
<source>Sign messages with your Bitcoin addresses to prove you own them</source>
- <translation>Za dokaz, da ste lastniki sporočil, se podpišite z Bitcoin naslovom</translation>
+ <translation>Podpišite poljubno sporočilo z enim svojih naslovov Bitcoin, da prejemniku sporočila dokažete, da je ta naslov v vaši lasti.</translation>
+ </message>
+ <message>
+ <source>Verify messages to ensure they were signed with specified Bitcoin addresses</source>
+ <translation>Preverite, če je bilo prejeto sporočilo podpisano z določenim naslovom Bitcoin</translation>
</message>
<message>
<source>&amp;File</source>
@@ -352,35 +388,83 @@
</message>
<message>
<source>Bitcoin Core</source>
- <translation>Jedro Bitcoina</translation>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>Zahtevajte plačilo (ustvarite zahtevek s kodo QR in URI tipa bitcoin:)</translation>
</message>
<message>
<source>&amp;About Bitcoin Core</source>
- <translation>&amp;O jedru Bitcoina</translation>
+ <translation>&amp;O programu</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Spremenite programske nastavitve</translation>
</message>
<message>
<source>Show the list of used sending addresses and labels</source>
- <translation>Prikaži seznam uporabljenih naslovov za pošiljanje in oznak</translation>
+ <translation>Preglejte in uredite seznam naslovov, na katere ste kdaj poslali plačila</translation>
</message>
<message>
<source>Show the list of used receiving addresses and labels</source>
- <translation>Prikaži seznam uporabljenih sprejemnih naslovov in oznak</translation>
+ <translation>Preglejte in uredite seznam naslovov, na katere ste kdaj prejeli plačila</translation>
</message>
<message>
<source>Open a bitcoin: URI or payment request</source>
- <translation>Odpri Bitcoin: URI ali zahteva o plačilu</translation>
+ <translation>Izvedite plačilo iz zahtevka v datoteki ali iz URI tipa bitcoin:</translation>
+ </message>
+ <message>
+ <source>&amp;Command-line options</source>
+ <translation>Opcije &amp;ukazne vrstice</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Oglejte si seznam in kratek opis vseh opcij pri zagonu programa iz ukazne vrstice</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktivna povezava v bitcoin omrežje</numerusform><numerusform>%n aktivni povezavi v bitcoin omrežje</numerusform><numerusform>%n aktivne povezave v bitcoin omrežje</numerusform><numerusform>%n aktivnih povezav v bitcoin omrežje</numerusform></translation>
+ </message>
+ <message>
+ <source>No block source available...</source>
+ <translation>Ni virov za prenos blokov ...</translation>
+ </message>
+ <message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>%n obdelan blok zgodovine transakcij.</numerusform><numerusform>%n obdelana bloka zgodovine transakcij.</numerusform><numerusform>%n obdelani bloki zgodovine transakcij.</numerusform><numerusform>%n obdelanih blokov zgodovine transakcij.</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n ura</numerusform><numerusform>%n uri</numerusform><numerusform>%n ure</numerusform><numerusform>%n ur</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n dan</numerusform><numerusform>%n dneva</numerusform><numerusform>%n dni</numerusform><numerusform>%n dni</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n teden</numerusform><numerusform>%n tedna</numerusform><numerusform>%n tedne</numerusform><numerusform>%n tednov</numerusform></translation>
</message>
<message>
<source>%1 and %2</source>
<translation>%1 in %2</translation>
</message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n leto</numerusform><numerusform>%n leti</numerusform><numerusform>%n leta</numerusform><numerusform>%n let</numerusform></translation>
+ </message>
<message>
<source>%1 behind</source>
- <translation>%1 odzadaj</translation>
+ <translation>imam še %1 zaostanka</translation>
+ </message>
+ <message>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Zadnji prejeti blok je bil ustvarjen %1 nazaj.</translation>
</message>
<message>
<source>Transactions after this will not yet be visible.</source>
- <translation>Transkacija za tem ne bo bila še na voljo.</translation>
+ <translation>Novejše transakcije še ne bodo vidne.</translation>
</message>
<message>
<source>Error</source>
@@ -400,7 +484,37 @@
</message>
<message>
<source>Catching up...</source>
- <translation>Pridobivanje ...</translation>
+ <translation>Dohitevam omrežje ...</translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Datum: %1
+</translation>
+ </message>
+ <message>
+ <source>Amount: %1
+</source>
+ <translation>Znesek: %1
+</translation>
+ </message>
+ <message>
+ <source>Type: %1
+</source>
+ <translation>Vrsta: %1
+</translation>
+ </message>
+ <message>
+ <source>Label: %1
+</source>
+ <translation>Oznaka: %1
+</translation>
+ </message>
+ <message>
+ <source>Address: %1
+</source>
+ <translation>Naslov: %1
+</translation>
</message>
<message>
<source>Sent transaction</source>
@@ -423,18 +537,22 @@
<name>ClientModel</name>
<message>
<source>Network Alert</source>
- <translation>Omrežno Opozorilo</translation>
+ <translation>Omrežno opozorilo</translation>
</message>
</context>
<context>
<name>CoinControlDialog</name>
<message>
+ <source>Coin Selection</source>
+ <translation>Izbira vhodnih kovancev</translation>
+ </message>
+ <message>
<source>Quantity:</source>
- <translation>Količina:</translation>
+ <translation>Št.vhodov:</translation>
</message>
<message>
<source>Bytes:</source>
- <translation>Biti:</translation>
+ <translation>Št.bajtov:</translation>
</message>
<message>
<source>Amount:</source>
@@ -442,7 +560,7 @@
</message>
<message>
<source>Priority:</source>
- <translation>Prednostno mesto:</translation>
+ <translation>Prioriteta:</translation>
</message>
<message>
<source>Fee:</source>
@@ -453,16 +571,20 @@
<translation>Prah:</translation>
</message>
<message>
+ <source>After Fee:</source>
+ <translation>Po proviziji:</translation>
+ </message>
+ <message>
<source>Change:</source>
- <translation>Sprememba:</translation>
+ <translation>Vračilo:</translation>
</message>
<message>
<source>(un)select all</source>
- <translation>(ne)izberi vse</translation>
+ <translation>izberi vse/nič</translation>
</message>
<message>
<source>Tree mode</source>
- <translation>Drevo</translation>
+ <translation>Drevesni prikaz</translation>
</message>
<message>
<source>List mode</source>
@@ -470,7 +592,15 @@
</message>
<message>
<source>Amount</source>
- <translation>Količina</translation>
+ <translation>Znesek</translation>
+ </message>
+ <message>
+ <source>Received with label</source>
+ <translation>Oznaka priliva</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Naslov priliva</translation>
</message>
<message>
<source>Date</source>
@@ -478,7 +608,7 @@
</message>
<message>
<source>Confirmations</source>
- <translation>Potrdila</translation>
+ <translation>Potrditve</translation>
</message>
<message>
<source>Confirmed</source>
@@ -486,7 +616,7 @@
</message>
<message>
<source>Priority</source>
- <translation>Prednostno mesto</translation>
+ <translation>Prioriteta</translation>
</message>
<message>
<source>Copy address</source>
@@ -498,7 +628,7 @@
</message>
<message>
<source>Copy amount</source>
- <translation>Kopiraj količino</translation>
+ <translation>Kopiraj znesek</translation>
</message>
<message>
<source>Copy transaction ID</source>
@@ -514,19 +644,23 @@
</message>
<message>
<source>Copy quantity</source>
- <translation>Kopiraj količino</translation>
+ <translation>Kopiraj število vhodov</translation>
</message>
<message>
<source>Copy fee</source>
- <translation>Kopiraj provizijo</translation>
+ <translation>Kopiraj znesek provizije</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Kopiraj končni znesek</translation>
</message>
<message>
<source>Copy bytes</source>
- <translation>Kopiraj bite</translation>
+ <translation>Kopiraj število bajtov</translation>
</message>
<message>
<source>Copy priority</source>
- <translation>Kopiraj prednostno mesto</translation>
+ <translation>Kopiraj prioriteto</translation>
</message>
<message>
<source>Copy dust</source>
@@ -534,7 +668,7 @@
</message>
<message>
<source>Copy change</source>
- <translation>Kopiraj drobiž</translation>
+ <translation>Kopiraj znesek vračila</translation>
</message>
<message>
<source>highest</source>
@@ -554,7 +688,7 @@
</message>
<message>
<source>medium</source>
- <translation>srednje</translation>
+ <translation>srednja</translation>
</message>
<message>
<source>low-medium</source>
@@ -578,11 +712,23 @@
</message>
<message>
<source>none</source>
- <translation>Nič</translation>
+ <translation>nič</translation>
+ </message>
+ <message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Oznaka postane rdeča, če je transakcije večja od 1000 bajtov.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Oznaka postane rdeča, če je prioriteta transakcije manjša kot "srednja".</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Oznaka postane rdeča, če je znesek manjši od %1.</translation>
</message>
<message>
<source>Can vary +/- %1 satoshi(s) per input.</source>
- <translation>Se lahko razlikuje +/- %1 satošijev na vnos.</translation>
+ <translation>Lahko variira +/- %1 satoshijev na vhod.</translation>
</message>
<message>
<source>yes</source>
@@ -593,8 +739,12 @@
<translation>ne</translation>
</message>
<message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>To pomeni, da je zahtevana provizija v višini vsaj %1 na KiB.</translation>
+ </message>
+ <message>
<source>Can vary +/- 1 byte per input.</source>
- <translation>Se lahko razlikuje +/- 1 byte na vnos.</translation>
+ <translation>Lahko variira +/-1 bajt na vhod.</translation>
</message>
<message>
<source>Transactions with higher priority are more likely to get included into a block.</source>
@@ -602,15 +752,15 @@
</message>
<message>
<source>(no label)</source>
- <translation>(ni oznake)</translation>
+ <translation>(brez oznake)</translation>
</message>
<message>
<source>change from %1 (%2)</source>
- <translation>drobiž od %1 (%2)</translation>
+ <translation>vračilo od %1 (%2)</translation>
</message>
<message>
<source>(change)</source>
- <translation>(drobiž)</translation>
+ <translation>(vračilo)</translation>
</message>
</context>
<context>
@@ -625,11 +775,11 @@
</message>
<message>
<source>The label associated with this address list entry</source>
- <translation>Oznaka je povezana s tem vnosom seznama naslovov</translation>
+ <translation>Oznaka, pod katero je spodnji naslov naveden v vašem imeniku naslovov.</translation>
</message>
<message>
<source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
- <translation>Naslov povezan s tem vnosom seznama naslovov. Sprememba je mogoča le za naslove namenjene pošiljanju.</translation>
+ <translation>Naslov tega vnosa v imeniku. Spremeniti ga je mogoče le pri vnosih iz imenika naslovov za pošiljanje.</translation>
</message>
<message>
<source>&amp;Address</source>
@@ -652,23 +802,27 @@
<translation>Uredi naslov za odlive</translation>
</message>
<message>
+ <source>The entered address "%1" is already in the address book.</source>
+ <translation>Vnešeni naslov %1 je že v imeniku.</translation>
+ </message>
+ <message>
<source>The entered address "%1" is not a valid Bitcoin address.</source>
- <translation>Vnešeni naslov "%1" ni veljaven Bitcoin naslov.</translation>
+ <translation>Vnešeni naslov %1 ni veljaven naslov Bitcoin.</translation>
</message>
<message>
<source>Could not unlock wallet.</source>
- <translation>Ni bilo moč odkleniti denarnice.</translation>
+ <translation>Denarnice ni bilo mogoče odkleniti.</translation>
</message>
<message>
<source>New key generation failed.</source>
- <translation>Generiranje novega ključa je spodletelo.</translation>
+ <translation>Novega ključa ni bilo mogoče ustvariti.</translation>
</message>
</context>
<context>
<name>FreespaceChecker</name>
<message>
<source>A new data directory will be created.</source>
- <translation>Ustvarjena bo nova mapa za shranjevanje podatkov.</translation>
+ <translation>Ustvarjena bo nova podatkovna mapa.</translation>
</message>
<message>
<source>name</source>
@@ -676,7 +830,7 @@
</message>
<message>
<source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
- <translation>Mapa že obstaja. Dodaj %1, če tu želiš ustvariti novo mapo.</translation>
+ <translation>Mapa že obstaja. Dodajte %1, če tu želite ustvariti novo mapo.</translation>
</message>
<message>
<source>Path already exists, and is not a directory.</source>
@@ -684,14 +838,14 @@
</message>
<message>
<source>Cannot create data directory here.</source>
- <translation>Na tem mestu ne moreš ustvariti nove mape.</translation>
+ <translation>Na tem mestu ni mogoče ustvariti nove mape.</translation>
</message>
</context>
<context>
<name>HelpMessageDialog</name>
<message>
<source>Bitcoin Core</source>
- <translation>Jedro Bitcoina</translation>
+ <translation>Bitcoin Core</translation>
</message>
<message>
<source>version</source>
@@ -703,7 +857,7 @@
</message>
<message>
<source>About Bitcoin Core</source>
- <translation>O jedru Bitcoina</translation>
+ <translation>O programu Bitcoin Core</translation>
</message>
<message>
<source>Command-line options</source>
@@ -726,36 +880,40 @@
</message>
<message>
<source>Welcome to Bitcoin Core.</source>
- <translation>Dobrodošli v jedru Bitcoina</translation>
+ <translation>Dobrodošli v programu Bitcoin Core.</translation>
</message>
<message>
<source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
- <translation>Program poganjaš prvič. Izberi kje bo Bitcoin Core shranjeval svoje podatke.</translation>
+ <translation>To je prvi zagon programa, zato lahko izberete mapo, v katero bo program shranjeval podatke.</translation>
</message>
<message>
<source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
- <translation>Bitcoin Core bo prenesel in shranil kopijo Bitcoin verige blokov. V izbrano mapo bo shranjenih vsaj %1 GB podatkov, ta količina pa bo sčasoma še naraščala. Denarnica bo prav tako shranjena v to mapo.</translation>
+ <translation>Program bo prenesel in shranil kopijo verige blokov. V izbrani podatkovni mapi bo shranjenih vsaj %1 GiB podatkov, ta količina pa bo sčasoma še naraščala. V tej mapi bo shranjena tudi denarnica.</translation>
</message>
<message>
<source>Use the default data directory</source>
- <translation>Uporabi privzeto mapo za shranjevanje podatkov.</translation>
+ <translation>Uporabi privzeto podatkovno mapo</translation>
</message>
<message>
<source>Use a custom data directory:</source>
- <translation>Uporabi to mapo za shranjevanje podatkov:</translation>
+ <translation>Uporabi to podatkovno mapo:</translation>
</message>
<message>
<source>Bitcoin Core</source>
- <translation>Jedro Bitcoina</translation>
+ <translation>Bitcoin Core</translation>
</message>
<message>
<source>Error: Specified data directory "%1" cannot be created.</source>
- <translation>Napaka: Ne morem ustvariti mape "%1".</translation>
+ <translation>Napaka: Ni mogoče ustvariti mape "%1".</translation>
</message>
<message>
<source>Error</source>
<translation>Napaka</translation>
</message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform><numerusform>%n GiB prostega prostora na voljo</numerusform></translation>
+ </message>
</context>
<context>
<name>OpenURIDialog</name>
@@ -765,7 +923,7 @@
</message>
<message>
<source>Open payment request from URI or file</source>
- <translation>Odpri zahtevo o plačilo od ORI ali datoteke</translation>
+ <translation>Vnesite zahtevek za plačilo iz URI ali pa ga naložite iz datoteke</translation>
</message>
<message>
<source>URI:</source>
@@ -773,11 +931,11 @@
</message>
<message>
<source>Select payment request file</source>
- <translation>Izberi datoteko plačilnega zahtevka</translation>
+ <translation>Izbiranje datoteke z zahtevkom za plačilo</translation>
</message>
<message>
<source>Select payment request file to open</source>
- <translation>Izberi datoteko plačilnega zahtevka</translation>
+ <translation>Izberite datoteko, ki vsebuje zahtevek za plačilo</translation>
</message>
</context>
<context>
@@ -792,55 +950,111 @@
</message>
<message>
<source>Size of &amp;database cache</source>
- <translation>Velikost lokalne zbirke &amp;podatkovne baze</translation>
+ <translation>Velikost &amp;predpomnilnika podatkovne baze</translation>
</message>
<message>
<source>MB</source>
- <translation>megabite</translation>
+ <translation>MiB</translation>
+ </message>
+ <message>
+ <source>Number of script &amp;verification threads</source>
+ <translation>Število programskih &amp;niti za preverjanje</translation>
</message>
<message>
<source>Accept connections from outside</source>
- <translation>Sprejmi povezave od zunaj</translation>
+ <translation>Sprejemaj zunanje povezave</translation>
</message>
<message>
<source>Allow incoming connections</source>
- <translation>Dovoli prihajajoče povezave</translation>
+ <translation>Dovoli dohodne povezave</translation>
</message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
- <translation>IP naslov proxy strežnika (npr. IPv4: 127.0.0.1 ali IPv6: ::1)</translation>
+ <translation>Naslov IP posredniškega strežnika (npr. IPv4: 127.0.0.1 ali IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Ko zaprete glavno okno programa, bo program tekel še naprej, okno pa bo zgolj minimirano. Program v tem primeru ustavite tako, da v meniju izberete ukaz Izhod.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Nastavitev jezika uporabniškega vmesnika programa. Nova nastavitev jezika bo uporabljena šele, ko boste znova zagnali program.</translation>
+ </message>
+ <message>
+ <source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
+ <translation>Naslovi URL tretjih oseb (npr. raziskovalec blokov), ki bodo navedeni v kontekstnem meniju seznama transakcij. Niz %s iz naslova URL je nadomeščen s hash vrednostjo transakcije. Več zaporednih naslovov URL je med seboj ločenih z znakom |.</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Zunanje povezave za transakcije</translation>
+ </message>
+ <message>
+ <source>Active command-line options that override above options:</source>
+ <translation>Aktivne opcije iz ukazne vrstice, ki preglasijo zgornje opcije:</translation>
+ </message>
+ <message>
+ <source>Reset all client options to default.</source>
+ <translation>Ponastavi vse nastavitve programa na privzete vrednosti.</translation>
</message>
<message>
<source>&amp;Reset Options</source>
- <translation>&amp;Opcije resetiranja</translation>
+ <translation>&amp;Ponastavi nastavitve</translation>
</message>
<message>
<source>&amp;Network</source>
<translation>&amp;Omrežje</translation>
</message>
<message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Ob uporabnikovi prijavi v sistem se bo program samodejno zagnal</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Zaženi program ob prijavi v sistem</translation>
+ </message>
+ <message>
+ <source>(0 = auto, &lt;0 = leave that many cores free)</source>
+ <translation>(0 = samodejno, &lt;0 = toliko procesorskih jeder naj ostane prostih)</translation>
+ </message>
+ <message>
<source>W&amp;allet</source>
<translation>&amp;Denarnica</translation>
</message>
<message>
<source>Expert</source>
- <translation>Poznavalec</translation>
+ <translation>Napredne možnosti</translation>
</message>
<message>
<source>Enable coin &amp;control features</source>
- <translation>Omogoči Coin &amp; Control funkcijo</translation>
+ <translation>Omogoči upravljanje s kovanci</translation>
+ </message>
+ <message>
+ <source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
+ <translation>Če onemogočite trošenje drobiža iz še nepotrjenih transakcij, potem vrnjenega drobiža ne morete uporabiti, dokler plačilo ni vsaj enkrat potrjeno. Ta opcija vpliva tudi na izračun stanja sredstev.</translation>
+ </message>
+ <message>
+ <source>&amp;Spend unconfirmed change</source>
+ <translation>Omogoči &amp;trošenje drobiža iz še nepotrjenih plačil</translation>
</message>
<message>
<source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
- <translation>Avtomatično odpri vrata Bitcoin odjemalca na usmerjevalniku. To deluje samo, če vaš usmerjevalnik podpira UPnP in je omogočen.</translation>
+ <translation>Program samodejno odpre ustrezna vrata na usmerjevalniku. To deluje samo, če vaš usmerjevalnik podpira in ima omogočen UPnP.</translation>
</message>
<message>
<source>Map port using &amp;UPnP</source>
- <translation>Naslavljanje vrat z uporabo &amp;UPnP</translation>
+ <translation>Preslikaj vrata z uporabo &amp;UPnP</translation>
+ </message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Poveži se v omrežje Bitcoin preko posredniškega strežnika SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&amp;Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&amp;Poveži se preko posredniškega strežnika SOCKS5 (privzeti strežnik):</translation>
</message>
<message>
<source>Proxy &amp;IP:</source>
- <translation>IP posredniškega strežnika:</translation>
+ <translation>Naslov &amp;IP posredniškega strežnika:</translation>
</message>
<message>
<source>&amp;Port:</source>
@@ -848,15 +1062,15 @@
</message>
<message>
<source>Port of the proxy (e.g. 9050)</source>
- <translation>Vrata strežnika (npr.: 9050)</translation>
+ <translation>Vrata posredniškega strežnika (npr. 9050)</translation>
</message>
<message>
<source>&amp;Window</source>
- <translation>&amp;Okno</translation>
+ <translation>O&amp;kno</translation>
</message>
<message>
<source>Show only a tray icon after minimizing the window.</source>
- <translation>Prikaži samo pomanjšano ikono programa po pomanjšitvi okna.</translation>
+ <translation>Po minimiranju okna samo prikaži ikono programa v pladnju.</translation>
</message>
<message>
<source>&amp;Minimize to the tray instead of the taskbar</source>
@@ -864,7 +1078,7 @@
</message>
<message>
<source>M&amp;inimize on close</source>
- <translation>&amp;Minimiziraj na ukaz zapri</translation>
+ <translation>Ob zapiranju okno zgolj m&amp;inimiraj</translation>
</message>
<message>
<source>&amp;Display</source>
@@ -872,11 +1086,19 @@
</message>
<message>
<source>User Interface &amp;language:</source>
- <translation>Vmesnik uporabnika &amp;jezik:</translation>
+ <translation>&amp;Jezik uporabniškega vmesnika:</translation>
</message>
<message>
<source>&amp;Unit to show amounts in:</source>
- <translation>&amp;</translation>
+ <translation>&amp;Enota za prikaz zneskov:</translation>
+ </message>
+ <message>
+ <source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
+ <translation>Izberite privzeto mersko enoto za prikaz v uporabniškem vmesniku in pri pošiljanju kovancev.</translation>
+ </message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Omogoči dodatno možnost podrobnega nadzora nad posameznimi kovanci v transakcijah.</translation>
</message>
<message>
<source>&amp;OK</source>
@@ -884,7 +1106,7 @@
</message>
<message>
<source>&amp;Cancel</source>
- <translation>&amp;Prekini</translation>
+ <translation>&amp;Prekliči</translation>
</message>
<message>
<source>default</source>
@@ -892,9 +1114,29 @@
</message>
<message>
<source>none</source>
- <translation>Nič</translation>
+ <translation>nič</translation>
</message>
- </context>
+ <message>
+ <source>Confirm options reset</source>
+ <translation>Potrditev ponastavitve</translation>
+ </message>
+ <message>
+ <source>Client restart required to activate changes.</source>
+ <translation>Za uveljavitev sprememb je potreben ponoven zagon programa.</translation>
+ </message>
+ <message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Program bo zaustavljen. Želite nadaljevati z izhodom?</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Ta sprememba zahteva ponoven zagon programa.</translation>
+ </message>
+ <message>
+ <source>The supplied proxy address is invalid.</source>
+ <translation>Vnešeni naslov posredniškega strežnika ni veljaven.</translation>
+ </message>
+</context>
<context>
<name>OverviewPage</name>
<message>
@@ -903,23 +1145,39 @@
</message>
<message>
<source>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source>
- <translation>Prikazanim podatkom je lahko potekel rok. Vaša denarnica bo po vzpostavitvi povezave samodejno sinhronizirana z Bitcoin omrežjem, ampak ta proces še ni bil zaključen.</translation>
+ <translation>Prikazani podatki so morda zastareli. Program ob vzpostavitvi povezave samodejno sinhronizira denarnico z omrežjem Bitcoin, a trenutno ta proces še ni zaključen.</translation>
</message>
<message>
<source>Watch-only:</source>
- <translation>Samo gledanje</translation>
+ <translation>Opazovano:</translation>
</message>
<message>
<source>Available:</source>
- <translation>Razpoložljivost:</translation>
+ <translation>Na voljo:</translation>
</message>
<message>
<source>Your current spendable balance</source>
- <translation>Vaše trenutno razpoložljivo stanje</translation>
+ <translation>Skupni znesek vaših sredstev, s katerimi lahko prosto razpolagate</translation>
+ </message>
+ <message>
+ <source>Pending:</source>
+ <translation>Nepotrjeno:</translation>
</message>
<message>
<source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
- <translation>Skupno število potrjenih transakcij, ki sicer niso bile prištete k razpoložljivem stanju</translation>
+ <translation>Skupni znesek sredstev s katerimi še ne razpolagate prosto, ker so del še nepotrjenih transakcij.</translation>
+ </message>
+ <message>
+ <source>Immature:</source>
+ <translation>Nedozorelo:</translation>
+ </message>
+ <message>
+ <source>Mined balance that has not yet matured</source>
+ <translation>Nedozorel narudarjeni znesek</translation>
+ </message>
+ <message>
+ <source>Balances</source>
+ <translation>Stanje sredstev</translation>
</message>
<message>
<source>Total:</source>
@@ -927,9 +1185,33 @@
</message>
<message>
<source>Your current total balance</source>
- <translation>Vaše trenutno skupno stanje</translation>
+ <translation>Trenutna vsota vseh vaših sredstev</translation>
</message>
- </context>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Trenutno stanje vaših sredstev na opazovanih naslovih</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Na voljo:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Nedavne transakcije</translation>
+ </message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Nepotrjene transakcije na opazovanih naslovih</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Nedozoreli narudarjeni znesek na opazovanih naslovih</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Trenutno skupno stanje sredstev na opazovanih naslovih</translation>
+ </message>
+</context>
<context>
<name>PaymentServer</name>
<message>
@@ -941,16 +1223,80 @@
<translation>Neveljaven naslov plačila %1</translation>
</message>
<message>
+ <source>Payment request rejected</source>
+ <translation>Zahtevek za plačilo je bil zavrnjen.</translation>
+ </message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Zahtevek za plačilo in vaš odjemalec se nahajata na dveh različnih omrežjih.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Zahtevek za plačilo ni inicializiran.</translation>
+ </message>
+ <message>
+ <source>Requested payment amount of %1 is too small (considered dust).</source>
+ <translation>Znesek %1 v zahtevku za plačilo je prenizek (smatran za prah.)</translation>
+ </message>
+ <message>
<source>Payment request error</source>
- <translation>Napaka pri zahtevi plačila</translation>
+ <translation>Napaka pri zahtevku za plačilo</translation>
+ </message>
+ <message>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Ni mogoče zagnati rokovalca plačilnih povezav tipa bitcoin:.</translation>
+ </message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>Naslov URL za pridobitev zahtevka za plačilo ni veljaven: %1</translation>
+ </message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI je neprepoznaven! Možno je, da je naslov Bitcoin neveljaven, ali da so parametri v URI napačno oblikovani.</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Rokovanje z datoteko z zahtevkom za plačilo</translation>
+ </message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Datoteke z zahtevkom za plačilo ni mogoče prebrati! Možno je, da datoteka ni veljavna.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Zahtevek za plačilo je potekel.</translation>
+ </message>
+ <message>
+ <source>Unverified payment requests to custom payment scripts are unsupported.</source>
+ <translation>Nepreverjeni zahtevki za plačilo, namenjeni plačilni skripti po meri, niso podprti.</translation>
+ </message>
+ <message>
+ <source>Invalid payment request.</source>
+ <translation>Neveljaven zahtevek za plačilo.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Povračilo od %1</translation>
+ </message>
+ <message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Zahtevek za plačilo %1 je prevelik (%2 bajtov, dovoljenih je %3 bajtov.)</translation>
+ </message>
+ <message>
+ <source>Payment request DoS protection</source>
+ <translation>Zaščita pred napadom denial-of-service zahtevka za plačilo</translation>
</message>
<message>
<source>Error communicating with %1: %2</source>
<translation>Napaka pri povezavi z %1: %2</translation>
</message>
<message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Zahtevek za plačilo je neprepoznaven!</translation>
+ </message>
+ <message>
<source>Bad response from server %1</source>
- <translation>Slab odziv strežnika %1</translation>
+ <translation>Napačen odziv strežnika %1</translation>
</message>
<message>
<source>Payment acknowledged</source>
@@ -964,6 +1310,14 @@
<context>
<name>PeerTableModel</name>
<message>
+ <source>User Agent</source>
+ <translation>Ime agenta</translation>
+ </message>
+ <message>
+ <source>Node/Service</source>
+ <translation>Vozlišče/Storitev</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Odzivni čas</translation>
</message>
@@ -972,26 +1326,46 @@
<name>QObject</name>
<message>
<source>Amount</source>
- <translation>Količina</translation>
+ <translation>Znesek</translation>
+ </message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Vnesite naslov Bitcoin (npr. %1):</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
</message>
<message>
<source>%1 h</source>
- <translation>%1 ur</translation>
+ <translation>%1 h</translation>
</message>
<message>
<source>%1 m</source>
- <translation>%1 minut</translation>
+ <translation>%1 m</translation>
+ </message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Nič</translation>
</message>
<message>
<source>N/A</source>
<translation>Neznano</translation>
</message>
- </context>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
<context>
<name>QRImageWidget</name>
<message>
<source>&amp;Save Image...</source>
- <translation>&amp;Shrani sliko..</translation>
+ <translation>&amp;Shrani sliko ...</translation>
</message>
<message>
<source>&amp;Copy Image</source>
@@ -999,7 +1373,7 @@
</message>
<message>
<source>Save QR Code</source>
- <translation>Shrani QR kodo</translation>
+ <translation>Shrani kodo QR</translation>
</message>
<message>
<source>PNG Image (*.png)</source>
@@ -1025,6 +1399,14 @@
<translation>&amp;Informacije</translation>
</message>
<message>
+ <source>Debug window</source>
+ <translation>Razhroščevalno okno</translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation>Splošno</translation>
+ </message>
+ <message>
<source>Using OpenSSL version</source>
<translation>OpenSSL različica v rabi</translation>
</message>
@@ -1041,6 +1423,10 @@
<translation>Omrežje</translation>
</message>
<message>
+ <source>Name</source>
+ <translation>Ime</translation>
+ </message>
+ <message>
<source>Number of connections</source>
<translation>Število povezav</translation>
</message>
@@ -1053,26 +1439,82 @@
<translation>Trenutno število blokov</translation>
</message>
<message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Odpre razhroščevalni dnevnik debug.log, ki se nahaja v trenutni podatkovni mapi. Če je datoteka velika, lahko postopek traja nekaj sekund.</translation>
+ </message>
+ <message>
<source>Received</source>
<translation>Prejeto</translation>
</message>
<message>
<source>Sent</source>
- <translation>Poslano</translation>
+ <translation>Oddano</translation>
+ </message>
+ <message>
+ <source>&amp;Peers</source>
+ <translation>&amp;Soležniki</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Izberite soležnika, o katerem si želite ogledati podrobnejše informacije.</translation>
+ </message>
+ <message>
+ <source>Direction</source>
+ <translation>Smer povezave</translation>
</message>
<message>
<source>Version</source>
<translation>Različica</translation>
</message>
<message>
+ <source>User Agent</source>
+ <translation>Ime agenta</translation>
+ </message>
+ <message>
<source>Services</source>
<translation>Storitve</translation>
</message>
<message>
+ <source>Starting Height</source>
+ <translation>Začetna višina</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Trenutna višina</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Kazenske točke</translation>
+ </message>
+ <message>
+ <source>Connection Time</source>
+ <translation>Trajanje povezave</translation>
+ </message>
+ <message>
+ <source>Last Send</source>
+ <translation>Nazadje oddano</translation>
+ </message>
+ <message>
+ <source>Last Receive</source>
+ <translation>Nazadnje prejeto</translation>
+ </message>
+ <message>
+ <source>Bytes Sent</source>
+ <translation>Oddanih bajtov</translation>
+ </message>
+ <message>
+ <source>Bytes Received</source>
+ <translation>Prejetih bajtov</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Odzivni čas</translation>
</message>
<message>
+ <source>Time Offset</source>
+ <translation>Časovni odklon</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Čas zadnjega bloka</translation>
</message>
@@ -1090,11 +1532,19 @@
</message>
<message>
<source>&amp;Clear</source>
- <translation>&amp;Pošisti</translation>
+ <translation>&amp;Počisti</translation>
</message>
<message>
<source>Totals</source>
- <translation>Vsote</translation>
+ <translation>Promet</translation>
+ </message>
+ <message>
+ <source>In:</source>
+ <translation>Dohodnih:</translation>
+ </message>
+ <message>
+ <source>Out:</source>
+ <translation>Odhodnih:</translation>
</message>
<message>
<source>Build date</source>
@@ -1102,54 +1552,70 @@
</message>
<message>
<source>Debug log file</source>
- <translation>Razhroščevalna dnevniška datoteka</translation>
+ <translation>Razhroščevalni dnevnik</translation>
</message>
<message>
<source>Clear console</source>
<translation>Počisti konzolo</translation>
</message>
<message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Dobrodošli v konzoli RPC programa Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
- <translation>Uporabi puščice za gor in dol za navigacijo po zgodovini in &lt;b&gt;Ctrl-L&lt;/b&gt; za izbris izpisa na ekranu.</translation>
+ <translation>Uporabite tipki gor in dol za navigacijo po zgodovini ukazov. Uporabite &lt;b&gt;Ctrl-L&lt;/b&gt; za izbris zaslona in zgodovine ukazov.</translation>
</message>
<message>
<source>Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
- <translation>Vtipkaj &lt;b&gt;pomoč&lt;/b&gt; za vpogled v razpožljive ukaze.</translation>
+ <translation>Vtipkajte &lt;b&gt;help&lt;/b&gt; za pregled razpoložljivih ukazov.</translation>
</message>
<message>
<source>%1 B</source>
- <translation>%1 bitov</translation>
+ <translation>%1 B</translation>
</message>
<message>
<source>%1 KB</source>
- <translation>%1 kilobitov</translation>
+ <translation>%1 KiB</translation>
</message>
<message>
<source>%1 MB</source>
- <translation>%1 megabitov</translation>
+ <translation>%1 MiB</translation>
</message>
<message>
<source>%1 GB</source>
- <translation>%1 gigabitov</translation>
+ <translation>%1 GiB</translation>
+ </message>
+ <message>
+ <source>via %1</source>
+ <translation>preko %1</translation>
</message>
<message>
<source>never</source>
<translation>nikoli</translation>
</message>
<message>
+ <source>Inbound</source>
+ <translation>Dohodna</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Odhodna</translation>
+ </message>
+ <message>
<source>Unknown</source>
<translation>Neznano</translation>
</message>
<message>
<source>Fetching...</source>
- <translation>Pridobivam...</translation>
+ <translation>Pridobivam ...</translation>
</message>
</context>
<context>
<name>ReceiveCoinsDialog</name>
<message>
<source>&amp;Amount:</source>
- <translation>&amp;Količina:</translation>
+ <translation>&amp;Znesek:</translation>
</message>
<message>
<source>&amp;Label:</source>
@@ -1160,18 +1626,50 @@
<translation>&amp;Sporočilo:</translation>
</message>
<message>
+ <source>Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before.</source>
+ <translation>Ponovno uporabite enega od že uporabljenih naslovov za prejemanje. Večkratna uporaba istih naslovov za prejemanje negativno vpliva na varnost in zasebnost. To opcijo uporabite samo v primeru, da poustvarjate obstoječ zahtevek za plačilo.</translation>
+ </message>
+ <message>
+ <source>R&amp;euse an existing receiving address (not recommended)</source>
+ <translation>P&amp;onovno uporabite obstoječ naslov za prejemanje. (Ni priporočeno.)</translation>
+ </message>
+ <message>
+ <source>An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
+ <translation>Neobvezno sporočilo kot priponka zahtevku za plačilo, ki bo prikazano, ko bo zahtevek odprt. Opomba: Opravljeno plačilo.prek omrežja Bitcoin tega sporočila ne bo vsebovalo.</translation>
+ </message>
+ <message>
<source>An optional label to associate with the new receiving address.</source>
- <translation>Pomožna oznaka je povezana z novim sprejemnim naslovom.</translation>
+ <translation>Oznaka novega sprejemnega naslova.</translation>
+ </message>
+ <message>
+ <source>Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
+ <translation>S tem obrazcem ustvarite nov zahtevek za plačilo. Vsa polja so &lt;b&gt;neobvezna&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
+ <translation>Zahtevani znesek. Če ne zahtevate določenega zneska, pustite prazno ali nastavite vrednost na 0.</translation>
+ </message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>Počisti vsa polja.</translation>
</message>
<message>
<source>Clear</source>
<translation>Počisti</translation>
</message>
<message>
+ <source>Requested payments history</source>
+ <translation>Zgodovina zahtevkov za plačilo</translation>
+ </message>
+ <message>
<source>&amp;Request payment</source>
<translation>&amp;Zahtevaj plačilo</translation>
</message>
<message>
+ <source>Show the selected request (does the same as double clicking an entry)</source>
+ <translation>Prikaz izbranega zahtevka. (Isto funkcijo opravi dvojni klik na zapis.)</translation>
+ </message>
+ <message>
<source>Show</source>
<translation>Pokaži</translation>
</message>
@@ -1193,7 +1691,7 @@
</message>
<message>
<source>Copy amount</source>
- <translation>Kopiraj količino</translation>
+ <translation>Kopiraj znesek</translation>
</message>
</context>
<context>
@@ -1204,19 +1702,23 @@
</message>
<message>
<source>Copy &amp;URI</source>
- <translation>Kopraj &amp;URl</translation>
+ <translation>Kopiraj &amp;URl</translation>
</message>
<message>
<source>Copy &amp;Address</source>
- <translation>Kopiraj &amp;Naslov</translation>
+ <translation>Kopiraj &amp;naslov</translation>
</message>
<message>
<source>&amp;Save Image...</source>
- <translation>&amp;Shrani sliko..</translation>
+ <translation>&amp;Shrani sliko ...</translation>
+ </message>
+ <message>
+ <source>Request payment to %1</source>
+ <translation>Zahtevek za plačilo z oznako: %1</translation>
</message>
<message>
<source>Payment information</source>
- <translation>Informacija o plačilu</translation>
+ <translation>Informacije o plačilu</translation>
</message>
<message>
<source>URI</source>
@@ -1228,7 +1730,7 @@
</message>
<message>
<source>Amount</source>
- <translation>Količina</translation>
+ <translation>Znesek</translation>
</message>
<message>
<source>Label</source>
@@ -1240,11 +1742,11 @@
</message>
<message>
<source>Resulting URI too long, try to reduce the text for label / message.</source>
- <translation>URI predolg, skušajte zmanjšati besedilo oznake/sporočila.</translation>
+ <translation>Nastali URI je predolg. Skušajte skrajšati besedilo v oznaki/sporočilu.</translation>
</message>
<message>
<source>Error encoding URI into QR Code.</source>
- <translation>Napaka pri kodiranju URIja v QR kodo.</translation>
+ <translation>Napaka pri pretvorbi URI v kodo QR.</translation>
</message>
</context>
<context>
@@ -1263,34 +1765,38 @@
</message>
<message>
<source>Amount</source>
- <translation>Količina</translation>
+ <translation>Znesek</translation>
</message>
<message>
<source>(no label)</source>
- <translation>(ni oznake)</translation>
+ <translation>(brez oznake)</translation>
</message>
<message>
<source>(no message)</source>
- <translation>(ni sporočila)</translation>
+ <translation>(brez sporočila)</translation>
</message>
<message>
<source>(no amount)</source>
- <translation>(brez količine)</translation>
+ <translation>(brez zneska)</translation>
</message>
</context>
<context>
<name>SendCoinsDialog</name>
<message>
<source>Send Coins</source>
- <translation>Pošlji kovance</translation>
+ <translation>Pošlji</translation>
+ </message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Upravljanje s kovanci</translation>
</message>
<message>
<source>Inputs...</source>
- <translation>Vnosi...</translation>
+ <translation>Vhodi ...</translation>
</message>
<message>
<source>automatically selected</source>
- <translation>samodejno izbran</translation>
+ <translation>samodejno izbrani</translation>
</message>
<message>
<source>Insufficient funds!</source>
@@ -1298,11 +1804,11 @@
</message>
<message>
<source>Quantity:</source>
- <translation>Količina:</translation>
+ <translation>Št.vhodov:</translation>
</message>
<message>
<source>Bytes:</source>
- <translation>Biti:</translation>
+ <translation>Št.bajtov:</translation>
</message>
<message>
<source>Amount:</source>
@@ -1310,15 +1816,95 @@
</message>
<message>
<source>Priority:</source>
- <translation>Prednostno mesto:</translation>
+ <translation>Prioriteta:</translation>
</message>
<message>
<source>Fee:</source>
<translation>Provizija:</translation>
</message>
<message>
+ <source>After Fee:</source>
+ <translation>Po proviziji:</translation>
+ </message>
+ <message>
<source>Change:</source>
- <translation>Sprememba:</translation>
+ <translation>Vračilo:</translation>
+ </message>
+ <message>
+ <source>If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
+ <translation>Če to vključite, nato pa vnesete neveljaven naslov, ali pa pustite polje prazno, bo vrnjen drobiž poslan na novo ustvarjen naslov.</translation>
+ </message>
+ <message>
+ <source>Custom change address</source>
+ <translation>Naslov za vračilo drobiža po meri</translation>
+ </message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Provizija:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Izberi ...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>Skrije nastavitve provizije</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>na KiB</translation>
+ </message>
+ <message>
+ <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
+ <translation>Če je nastavitev zneska provizije po meri enaka 1000 satoshijev, transakcija pa je velika samo 250 bajtov, je obračunani znesek provizije pri nastavitvi "za KiB" samo 250 satoshijev, medtem ko je pri nastavitvi "skupno vsaj" ta znesek 1000 satoshijev. Za transakcije, večje od 1 KiB, se končni znesek pri obeh nastavitvah obračuna na KiB.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Skrij</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>skupno vsaj</translation>
+ </message>
+ <message>
+ <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
+ <translation>Dokler bo v blokih še dovolj prostora za vse nastajajoče transakcije, zadostuje, če plačate samo minimalno provizijo. Ko pa se bo količina vseh transakcij povečala do meja zmogljivosti omrežja, se lahko zgodi, da vaša transakcija brez večje provizije nikoli ne bo potrjena.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(oglejte si namig)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Priporočena:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Po meri:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Samodejni obračun provizije še ni pripravljen. Po navadi izračun traja nekaj blokov ...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Čas do potrditve:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>navadno</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>hitro</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Pošlji brez provizije, če je mogoče</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(čas do potrditve je lahko daljši)</translation>
</message>
<message>
<source>Send to multiple recipients at once</source>
@@ -1329,6 +1915,10 @@
<translation>Dodaj &amp;prejemnika</translation>
</message>
<message>
+ <source>Clear all fields of the form.</source>
+ <translation>Počisti vsa polja.</translation>
+ </message>
+ <message>
<source>Dust:</source>
<translation>Prah:</translation>
</message>
@@ -1338,43 +1928,55 @@
</message>
<message>
<source>Balance:</source>
- <translation>Dobroimetje:</translation>
+ <translation>Stanje:</translation>
</message>
<message>
<source>Confirm the send action</source>
- <translation>Potrdi odlivno dejanje</translation>
+ <translation>Potrdi pošiljanje</translation>
</message>
<message>
<source>S&amp;end</source>
- <translation>P&amp;ošlji</translation>
+ <translation>&amp;Pošlji</translation>
</message>
<message>
<source>Confirm send coins</source>
- <translation>Potrdi odliv kovancev </translation>
+ <translation>Potrdi pošiljanje</translation>
+ </message>
+ <message>
+ <source>%1 to %2</source>
+ <translation>%1 na %2</translation>
</message>
<message>
<source>Copy quantity</source>
- <translation>Kopiraj količino</translation>
+ <translation>Kopiraj število vhodov</translation>
</message>
<message>
<source>Copy amount</source>
- <translation>Kopiraj količino</translation>
+ <translation>Kopiraj znesek</translation>
</message>
<message>
<source>Copy fee</source>
<translation>Kopiraj provizijo</translation>
</message>
<message>
+ <source>Copy after fee</source>
+ <translation>Kopiraj Po proviziji</translation>
+ </message>
+ <message>
<source>Copy bytes</source>
- <translation>Kopiraj bite</translation>
+ <translation>Kopiraj bajte</translation>
</message>
<message>
<source>Copy priority</source>
- <translation>Kopiraj prednostno mesto</translation>
+ <translation>Kopiraj prioriteto</translation>
</message>
<message>
<source>Copy change</source>
- <translation>Kopiraj drobiž</translation>
+ <translation>Kopiraj vračilo</translation>
+ </message>
+ <message>
+ <source>Total Amount %1 (= %2)</source>
+ <translation>Skupni znesek %1 (= %2)</translation>
</message>
<message>
<source>or</source>
@@ -1382,19 +1984,59 @@
</message>
<message>
<source>The amount to pay must be larger than 0.</source>
- <translation>Količina za plačilo mora biti večja od 0.</translation>
+ <translation>Znesek za plačilo mora biti večji od 0.</translation>
</message>
<message>
<source>The amount exceeds your balance.</source>
- <translation>Količina presega vaše dobroimetje</translation>
+ <translation>Znesek je večji od stanja sredstev, s katerimi razpolagate.</translation>
+ </message>
+ <message>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
+ <translation>Celotni znesek z vključeno provizijo %1 je večji od stanja sredstev, s katerimi razpolagate.</translation>
+ </message>
+ <message>
+ <source>Transaction creation failed!</source>
+ <translation>Transakcije ni bilo mogoče ustvariti!</translation>
+ </message>
+ <message>
+ <source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
+ <translation>Transakcija je bila zavrnjena! To se lahko zgodi, če so bili kateri od kovancev iz denarnice že porabljeni, kot v primeru, da ste kje uporabili kopijo datoteke wallet.dat in kovance tam že porabili, lokalno pa ti še niso bili označeni kot porabljeni.</translation>
+ </message>
+ <message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>Provizija, višja od %1, velja za nesmiselno visoko.</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>Zahtevek za plačilo je potekel.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Predviden začetek potrditev po %n najdenem bloku.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform><numerusform>Predviden začetek potrditev po %n najdenih blokih.</numerusform></translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Plačilo samo minimalne provizije v znesku %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Naslov prejemnika je neveljaven. Prosimo, preverite.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Naslov je že bil uporabljen. Vsak naslov naj bi se uporabil samo enkrat.</translation>
</message>
<message>
<source>Warning: Invalid Bitcoin address</source>
- <translation>Opozorilo: Neveljaven Bitcoin naslov</translation>
+ <translation>Opozorilo: Neveljaven bitcoin naslov</translation>
</message>
<message>
<source>(no label)</source>
- <translation>(ni oznake)</translation>
+ <translation>(brez oznake)</translation>
+ </message>
+ <message>
+ <source>Warning: Unknown change address</source>
+ <translation>Opozorilo: Neznan naslov za vračilo drobiža</translation>
</message>
<message>
<source>Copy dust</source>
@@ -1402,7 +2044,7 @@
</message>
<message>
<source>Are you sure you want to send?</source>
- <translation>Ali ste prepričani, da želite poslati?</translation>
+ <translation>Ali ste prepričani, da želite izvesti plačilo?</translation>
</message>
<message>
<source>added as transaction fee</source>
@@ -1413,7 +2055,7 @@
<name>SendCoinsEntry</name>
<message>
<source>A&amp;mount:</source>
- <translation>K&amp;oličina:</translation>
+ <translation>&amp;Znesek:</translation>
</message>
<message>
<source>Pay &amp;To:</source>
@@ -1421,7 +2063,7 @@
</message>
<message>
<source>Enter a label for this address to add it to your address book</source>
- <translation>Vnesite oznako za ta naslov, ki bo shranjena v imenik</translation>
+ <translation>Vnesite oznako, pod katero bo zgornji naslov shranjen v imenik</translation>
</message>
<message>
<source>&amp;Label:</source>
@@ -1429,7 +2071,15 @@
</message>
<message>
<source>Choose previously used address</source>
- <translation>Izberi zadnje uporabljen naslov</translation>
+ <translation>Izberite enega od že uporabljenih naslovov</translation>
+ </message>
+ <message>
+ <source>This is a normal payment.</source>
+ <translation>Plačilo je navadne vrste.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Naslov Bitcoin, na katerega bo plačilo poslano</translation>
</message>
<message>
<source>Alt+A</source>
@@ -1437,41 +2087,85 @@
</message>
<message>
<source>Paste address from clipboard</source>
- <translation>Prilepi naslov iz odložišča</translation>
+ <translation>Prilepite naslov iz odložišča</translation>
</message>
<message>
<source>Alt+P</source>
<translation>Alt+P</translation>
</message>
<message>
+ <source>Remove this entry</source>
+ <translation>Izpraznite vsebino polja</translation>
+ </message>
+ <message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Znesek plačila bo zmanjšan za znesek provizije. Prejemnik bo prejel manjše število kovancev, kot je bil vnešeni znesek. Če je prejemnikov več, bo provizija med njih enakomerno porazdeljena.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>O&amp;dštej provizijo od zneska</translation>
+ </message>
+ <message>
<source>Message:</source>
<translation>Sporočilo:</translation>
</message>
<message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Zahtevek za plačilo je neoverjen.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Zahtevek za plačilo je overjen.</translation>
+ </message>
+ <message>
<source>Enter a label for this address to add it to the list of used addresses</source>
- <translation>Vnesite oznako za ta naslov, ki bo shranjena v seznam uporabljenih naslovov</translation>
+ <translation>Če vnesete oznako za zgornji naslov, se bo skupaj z naslovom shranila v imenk že uporabljenih naslovov</translation>
</message>
- </context>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>Sporočilo, ki ste ga pripeli na URI tipa bitcoin:. Shranjeno bo skupaj s podatki o transakciji. Opomba: Sporočilo ne bo poslano preko omrežja Bitcoin.</translation>
+ </message>
+ <message>
+ <source>Pay To:</source>
+ <translation>Prejemnik:</translation>
+ </message>
+ <message>
+ <source>Memo:</source>
+ <translation>Opomba:</translation>
+ </message>
+</context>
<context>
<name>ShutdownWindow</name>
<message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Program se ustavlja ...</translation>
+ </message>
+ <message>
<source>Do not shut down the computer until this window disappears.</source>
- <translation>Ne zaustavite računalnika dokler to okno ne izgine.</translation>
+ <translation>Dokler to okno ne izgine, ne zaustavljajte računalnika.</translation>
</message>
</context>
<context>
<name>SignVerifyMessageDialog</name>
<message>
<source>Signatures - Sign / Verify a Message</source>
- <translation>Podpisi - Podpiši/preveri sporočilo</translation>
+ <translation>Podpiši / preveri sporočilo</translation>
</message>
<message>
<source>&amp;Sign Message</source>
<translation>&amp;Podpiši sporočilo</translation>
</message>
<message>
+ <source>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>S svojimi naslovi lahko podpisujete sporočila ali pogodbe in s tem dokazujete, da na teh naslovih lahko prejemate kovance. Bodite previdni in ne podpisujte ničesar nejasnega ali naključnega, ker vas zlikovci preko ribarjenja (phishing) lahko prelisičijo, da na njih prepišete svojo identiteto. Podpisujte samo podrobno opisane izjave, s katerimi se strinjate.</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Naslov Bitcoin, s katerim podpisujete sporočilo</translation>
+ </message>
+ <message>
<source>Choose previously used address</source>
- <translation>Izberi zadnje uporabljen naslov</translation>
+ <translation>Izberite enega od že uporabljenih naslovov</translation>
</message>
<message>
<source>Alt+A</source>
@@ -1479,21 +2173,37 @@
</message>
<message>
<source>Paste address from clipboard</source>
- <translation>Prilepi naslov iz odložišča</translation>
+ <translation>Prilepite naslov iz odložišča</translation>
</message>
<message>
<source>Alt+P</source>
<translation>Alt+P</translation>
</message>
<message>
+ <source>Enter the message you want to sign here</source>
+ <translation>Vnesite sporočilo, ki ga želite podpisati</translation>
+ </message>
+ <message>
<source>Signature</source>
<translation>Podpis</translation>
</message>
<message>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Kopiranje trenutnega podpisa na sistemsko odložišče.</translation>
+ </message>
+ <message>
+ <source>Sign the message to prove you own this Bitcoin address</source>
+ <translation>Podpišite sporočilo, da dokažete lastništvo nad zgornjim naslovom.</translation>
+ </message>
+ <message>
<source>Sign &amp;Message</source>
<translation>Podpiši &amp;sporočilo</translation>
</message>
<message>
+ <source>Reset all sign message fields</source>
+ <translation>Počisti vsa polja za vnos v oknu za podpisovanje</translation>
+ </message>
+ <message>
<source>Clear &amp;All</source>
<translation>Počisti &amp;vse </translation>
</message>
@@ -1502,12 +2212,28 @@
<translation>&amp;Preveri sporočilo</translation>
</message>
<message>
+ <source>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
+ <translation>Da preverite verodostojnost sporočila, spodaj vnesite: prejemnikov naslov, prejeto sporočilo (pazljivo skopirajte vse prelome vrstic, presledke, tabulatorje ipd.,) in prejeti podpis. Da se izognete napadom tipa man-in-the-middle, vedite, da iz veljavnega podpisa ne sledi nič drugega, kot tisto, kar je navedeno v sporočilu. Podpis samo potrjuje dejstvo, da ima podpisnik v lasti prejemni naslov, ne more pa dokazati vira nobene transakcije!</translation>
+ </message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Naslov Bitcoin, s katerim je bilo sporočilo podpisano</translation>
+ </message>
+ <message>
+ <source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
+ <translation>Preverite, ali je bilo sporočilo v resnici podpisano z navedenim naslovom Bitcoin.</translation>
+ </message>
+ <message>
<source>Verify &amp;Message</source>
- <translation>Preveri &amp;Sporočilo</translation>
+ <translation>Preveri &amp;sporočilo</translation>
+ </message>
+ <message>
+ <source>Reset all verify message fields</source>
+ <translation>Počisti vsa polja za vnos v oknu za preverjanje</translation>
</message>
<message>
<source>Click "Sign Message" to generate signature</source>
- <translation>Kliknite "Podpiši sporočilo" za ustvaritev podpisa</translation>
+ <translation>Kliknite "Podpiši sporočilo" da ustvarite podpis</translation>
</message>
<message>
<source>The entered address is invalid.</source>
@@ -1515,46 +2241,58 @@
</message>
<message>
<source>Please check the address and try again.</source>
- <translation>Prosimo preverite naslov in poizkusite znova.</translation>
+ <translation>Prosimo preverite naslov in poskusite znova.</translation>
+ </message>
+ <message>
+ <source>The entered address does not refer to a key.</source>
+ <translation>Vnešeni naslov se ne nanaša na noben ključ.</translation>
</message>
<message>
<source>Wallet unlock was cancelled.</source>
- <translation>Odklepanje denarnice je bilo prekinjeno.</translation>
+ <translation>Odklepanje denarnice je bilo preklicano.</translation>
</message>
<message>
<source>Private key for the entered address is not available.</source>
- <translation>Zasebni ključ vnešenega naslov ni na voljo.</translation>
+ <translation>Zasebni ključ vnešenega naslova ni na voljo.</translation>
</message>
<message>
<source>Message signing failed.</source>
- <translation>Podpisovanje sporočila spodletelo.</translation>
+ <translation>Podpisa ni bilo mogoče ustvariti.</translation>
</message>
<message>
<source>Message signed.</source>
- <translation>Sporočilo podpisano.</translation>
+ <translation>Podpis je bil ustvarjen.</translation>
</message>
<message>
<source>The signature could not be decoded.</source>
- <translation>Ni bilo mogoče dešifrirati podpisa.</translation>
+ <translation>Podpisa ni bilo mogoče razbrati.</translation>
</message>
<message>
<source>Please check the signature and try again.</source>
- <translation>Prosimo preverite podpis in poizkusite znova.</translation>
+ <translation>Prosimo preverite podpis in poskusite znova.</translation>
+ </message>
+ <message>
+ <source>The signature did not match the message digest.</source>
+ <translation>Podpis se ne ujema z rezultatom funkcije preverjanja.</translation>
</message>
<message>
<source>Message verification failed.</source>
- <translation>Pregledovanje sporočila spodletelo.</translation>
+ <translation>Podpis ni veljaven za to sporočilo.</translation>
</message>
<message>
<source>Message verified.</source>
- <translation>Sporočilo pregledano.</translation>
+ <translation>Podpis sporočila je veljaven.</translation>
</message>
</context>
<context>
<name>SplashScreen</name>
<message>
<source>Bitcoin Core</source>
- <translation>Jedro Bitcoina</translation>
+ <translation>Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>The Bitcoin Core developers</source>
+ <translation>Bitcoin Core razvijalci</translation>
</message>
<message>
<source>[testnet]</source>
@@ -1563,12 +2301,24 @@
</context>
<context>
<name>TrafficGraphWidget</name>
- </context>
+ <message>
+ <source>KB/s</source>
+ <translation>KiB/s</translation>
+ </message>
+</context>
<context>
<name>TransactionDesc</name>
<message>
<source>Open until %1</source>
- <translation>Odpri enoto %1</translation>
+ <translation>Odprto do %1</translation>
+ </message>
+ <message>
+ <source>conflicted</source>
+ <translation>v konfliktu</translation>
+ </message>
+ <message>
+ <source>%1/offline</source>
+ <translation>%1/brez povezave</translation>
</message>
<message>
<source>%1/unconfirmed</source>
@@ -1580,7 +2330,11 @@
</message>
<message>
<source>Status</source>
- <translation>Stanje</translation>
+ <translation>Status</translation>
+ </message>
+ <message numerus="yes">
+ <source>, broadcast through %n node(s)</source>
+ <translation><numerusform>, posredovano %n vozlišču</numerusform><numerusform>, posredovano %n vozliščema</numerusform><numerusform>, posredovano %n vozliščem</numerusform><numerusform>, posredovano %n vozliščem</numerusform></translation>
</message>
<message>
<source>Date</source>
@@ -1607,16 +2361,36 @@
<translation>lasten naslov</translation>
</message>
<message>
+ <source>watch-only</source>
+ <translation>opazovano</translation>
+ </message>
+ <message>
<source>label</source>
<translation>oznaka</translation>
</message>
<message>
+ <source>Credit</source>
+ <translation>V dobro</translation>
+ </message>
+ <message numerus="yes">
+ <source>matures in %n more block(s)</source>
+ <translation><numerusform>dozori po %n najdenem bloku</numerusform><numerusform>dozori po %n najdenih blokih</numerusform><numerusform>dozori po %n najdenih blokih</numerusform><numerusform>dozori po %n najdenih blokih</numerusform></translation>
+ </message>
+ <message>
<source>not accepted</source>
<translation>ni bilo sprejeto</translation>
</message>
<message>
<source>Debit</source>
- <translation>Dolg</translation>
+ <translation>Debit</translation>
+ </message>
+ <message>
+ <source>Total debit</source>
+ <translation>Skupaj v breme</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Skupaj v dobro</translation>
</message>
<message>
<source>Transaction fee</source>
@@ -1624,7 +2398,7 @@
</message>
<message>
<source>Net amount</source>
- <translation>Neto količina</translation>
+ <translation>Neto znesek</translation>
</message>
<message>
<source>Message</source>
@@ -1643,8 +2417,12 @@
<translation>Trgovec</translation>
</message>
<message>
+ <source>Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source>
+ <translation>Ustvarjeni kovanci morajo zoreti %1 blokov, preden jih lahko porabite. Ko ste ta blok zgenerirali, je bil posredovan v omrežje, da bo dodan v verigo. Če se bloku ni uspelo uvrstiti v verigo, se bo njegovo stanje spremenilo v "ni bilo sprejeto" in kovancev ne bo mogoče porabiti. To se včasih zgodi, če kak drug rudar v roku nekaj sekund hkrati z vami odkrije drug blok.</translation>
+ </message>
+ <message>
<source>Debug information</source>
- <translation>Razhroščevalna informacija</translation>
+ <translation>Razhroščevalne informacije</translation>
</message>
<message>
<source>Transaction</source>
@@ -1652,11 +2430,11 @@
</message>
<message>
<source>Inputs</source>
- <translation>Vnosi</translation>
+ <translation>Vhodi</translation>
</message>
<message>
<source>Amount</source>
- <translation>Količina</translation>
+ <translation>Znesek</translation>
</message>
<message>
<source>true</source>
@@ -1670,6 +2448,10 @@
<source>, has not been successfully broadcast yet</source>
<translation>, še ni bila uspešno raznešena</translation>
</message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Odprto še %n blok</numerusform><numerusform>Odprto še %n bloka</numerusform><numerusform>Odprto še %n bloke</numerusform><numerusform>Odprto še %n blokov</numerusform></translation>
+ </message>
<message>
<source>unknown</source>
<translation>neznano</translation>
@@ -1683,7 +2465,7 @@
</message>
<message>
<source>This pane shows a detailed description of the transaction</source>
- <translation>To podokno prikazuje podroben opis transakcije</translation>
+ <translation>V tem podoknu so prikazane podrobnosti o transakciji</translation>
</message>
</context>
<context>
@@ -1697,8 +2479,16 @@
<translation>Vrsta</translation>
</message>
<message>
+ <source>Immature (%1 confirmations, will be available after %2)</source>
+ <translation>Nedozorelo (št. potrditev: %1, na voljo šele po: %2)</translation>
+ </message>
+ <message numerus="yes">
+ <source>Open for %n more block(s)</source>
+ <translation><numerusform>Odprto še %n blok</numerusform><numerusform>Odprto še %n bloka</numerusform><numerusform>Odprto še %n bloke</numerusform><numerusform>Odprto še %n blokov</numerusform></translation>
+ </message>
+ <message>
<source>Open until %1</source>
- <translation>Odpri enoto %1</translation>
+ <translation>Odprto do %1</translation>
</message>
<message>
<source>Confirmed (%1 confirmations)</source>
@@ -1713,6 +2503,10 @@
<translation>Generirano, toda ne sprejeto</translation>
</message>
<message>
+ <source>Offline</source>
+ <translation>Brez povezave</translation>
+ </message>
+ <message>
<source>Label</source>
<translation>Oznaka</translation>
</message>
@@ -1721,24 +2515,36 @@
<translation>Nepotrjeno</translation>
</message>
<message>
+ <source>Confirming (%1 of %2 recommended confirmations)</source>
+ <translation>V potrjevanju (št. potrditev: %1 od priporočenih %2)</translation>
+ </message>
+ <message>
+ <source>Conflicted</source>
+ <translation>V konfliktu</translation>
+ </message>
+ <message>
<source>Received with</source>
- <translation>Prejeto z</translation>
+ <translation>Prejemek</translation>
</message>
<message>
<source>Received from</source>
- <translation>Prejeto od</translation>
+ <translation>Prejemek</translation>
</message>
<message>
<source>Sent to</source>
- <translation>Poslano</translation>
+ <translation>Izdatek</translation>
</message>
<message>
<source>Payment to yourself</source>
- <translation>Izplačilo sebi</translation>
+ <translation>Nakazilo sebi</translation>
</message>
<message>
<source>Mined</source>
- <translation>Minirano</translation>
+ <translation>Narudarjeno</translation>
+ </message>
+ <message>
+ <source>watch-only</source>
+ <translation>opazovano</translation>
</message>
<message>
<source>(n/a)</source>
@@ -1757,8 +2563,16 @@
<translation>Vrsta transakcije.</translation>
</message>
<message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Ali je v transakciji udeležen kateri od opazovanih naslovov.</translation>
+ </message>
+ <message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Uporabniško določen namen transakcije.</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
- <translation>Količina odlita ali prilita dobroimetju.</translation>
+ <translation>Znesek spremembe stanja sredstev.</translation>
</message>
</context>
<context>
@@ -1793,19 +2607,19 @@
</message>
<message>
<source>Received with</source>
- <translation>Prejeto z</translation>
+ <translation>Prejemek</translation>
</message>
<message>
<source>Sent to</source>
- <translation>Poslano</translation>
+ <translation>Izdatek</translation>
</message>
<message>
<source>To yourself</source>
- <translation>Samemu sebi</translation>
+ <translation>Nakazilo sebi</translation>
</message>
<message>
<source>Mined</source>
- <translation>Minirano</translation>
+ <translation>Narudarjeno</translation>
</message>
<message>
<source>Other</source>
@@ -1813,11 +2627,11 @@
</message>
<message>
<source>Enter address or label to search</source>
- <translation>Vnesite naslov ali oznako za iskanje</translation>
+ <translation>Iščite po naslovu ali oznaki</translation>
</message>
<message>
<source>Min amount</source>
- <translation>Minimalna količina</translation>
+ <translation>Minimalni znesek</translation>
</message>
<message>
<source>Copy address</source>
@@ -1829,7 +2643,7 @@
</message>
<message>
<source>Copy amount</source>
- <translation>Kopiraj količino</translation>
+ <translation>Kopiraj znesek</translation>
</message>
<message>
<source>Copy transaction ID</source>
@@ -1844,8 +2658,20 @@
<translation>Prikaži podrobnosti transakcije</translation>
</message>
<message>
+ <source>Export Transaction History</source>
+ <translation>Izvoz zgodovine transakcij</translation>
+ </message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Opazovano</translation>
+ </message>
+ <message>
<source>Exporting Failed</source>
- <translation>Neuspešen izvoz</translation>
+ <translation>Seznama transakcij ni bilo mogoče izvoziti.</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the transaction history to %1.</source>
+ <translation>Prišlo je do napake med shranjevanjem zgodovine transakcij v datoteko %1.</translation>
</message>
<message>
<source>Exporting Successful</source>
@@ -1853,7 +2679,7 @@
</message>
<message>
<source>The transaction history was successfully saved to %1.</source>
- <translation>Zgodovina poteklih transakcij je bila uspešno shranjena na %1.</translation>
+ <translation>Zgodovina poteklih transakcij je bila uspešno shranjena v datoteko %1.</translation>
</message>
<message>
<source>Comma separated file (*.csv)</source>
@@ -1894,15 +2720,23 @@
</context>
<context>
<name>UnitDisplayStatusBarControl</name>
- </context>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Merska enota za prikaz zneskov. Kliknite za izbiro druge enote.</translation>
+ </message>
+</context>
<context>
<name>WalletFrame</name>
- </context>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>Denarnica ni bila naložena.</translation>
+ </message>
+</context>
<context>
<name>WalletModel</name>
<message>
<source>Send Coins</source>
- <translation>Pošlji kovance</translation>
+ <translation>Pošlji</translation>
</message>
</context>
<context>
@@ -1913,11 +2747,11 @@
</message>
<message>
<source>Export the data in the current tab to a file</source>
- <translation>Izvozi podatke v trenutni zavih v datoteko</translation>
+ <translation>Izvozi podatke iz trenutnega zavihka v datoteko</translation>
</message>
<message>
<source>Backup Wallet</source>
- <translation>Napravi varnostno kopijo denarnice</translation>
+ <translation>Izdelava varnostne kopije denarnice</translation>
</message>
<message>
<source>Wallet Data (*.dat)</source>
@@ -1925,19 +2759,19 @@
</message>
<message>
<source>Backup Failed</source>
- <translation>Varnostna kopijo neuspešna</translation>
+ <translation>Varnostne kopije ni bilo mogoče izdelati.</translation>
</message>
<message>
<source>There was an error trying to save the wallet data to %1.</source>
- <translation>Prišlo je do napake pri shranjevanju podatkov denarnice na %1.</translation>
+ <translation>Prišlo je do napake pri shranjevanju podatkov denarnice v datoteko %1.</translation>
</message>
<message>
<source>The wallet data was successfully saved to %1.</source>
- <translation>Podatki denarnice so bili uspešno shranjena na %1.</translation>
+ <translation>Podatki iz denarnice so bili uspešno shranjeni v datoteko %1.</translation>
</message>
<message>
<source>Backup Successful</source>
- <translation>Varnostna kopija uspešna</translation>
+ <translation>Varnostna kopija je bila uspešno izdelana</translation>
</message>
</context>
<context>
@@ -1948,11 +2782,11 @@
</message>
<message>
<source>Specify data directory</source>
- <translation>Določi podatkovni imenik</translation>
+ <translation>Izberite podatkovno mapo</translation>
</message>
<message>
<source>Connect to a node to retrieve peer addresses, and disconnect</source>
- <translation>Povežite se z vozliščem za pridobitev naslovov uporabnikov in nato prekinite povezavo.</translation>
+ <translation>Povežite se z vozliščem za pridobitev naslovov soležnikov in nato prekinite povezavo.</translation>
</message>
<message>
<source>Specify your own public address</source>
@@ -1960,7 +2794,7 @@
</message>
<message>
<source>Accept command line and JSON-RPC commands</source>
- <translation>Sprejmi ukaze iz ukazne vrstice in JSON-RPC</translation>
+ <translation>Sprejemaj ukaze iz ukazne vrstice in preko JSON-RPC</translation>
</message>
<message>
<source>Run in the background as a daemon and accept commands</source>
@@ -1971,16 +2805,72 @@
<translation>Uporabi testno omrežje</translation>
</message>
<message>
+ <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
+ <translation>Sprejemaj zunanje povezave (privzeto: 1, razen če ste vklopili opciji -proxy ali -connect)</translation>
+ </message>
+ <message>
+ <source>Bind to given address and always listen on it. Use [host]:port notation for IPv6</source>
+ <translation>Veži dani naslov in tam vedno poslušaj. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata.</translation>
+ </message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</source>
+ <translation>Distribuirano v okviru programske licence MIT. Podrobnosti so navedene v priloženi datoteki COPYING ali na naslovu &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
+ </message>
+ <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Izvedi ukaz, ko bo transakcija denarnice se spremenila (V cmd je bil TxID zamenjan za %s)</translation>
</message>
<message>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Največji še veljavni skupni znesek provizij pri transakcijah z uporabo ene denarnice. Prenizka nastavitev lahko povzroči izločitev večjih transakcij (privzeto %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%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, &gt;%u = ciljna velikost datotek blokov v MiB)</translation>
+ </message>
+ <message>
+ <source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
+ <translation>Nastavi število niti za preverjanje skript (%u do %d, 0 = samodejno, &lt;0 toliko procesorskih jeder naj ostane prostih, privzeto: %d)</translation>
+ </message>
+ <message>
<source>This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
- <translation>To je pred izdana poizkusna verzija - uporaba na lastno odgovornost - ne uporabljajte je za rudarstvo ali trgovske aplikacije</translation>
+ <translation>To je preizkusna različica še neizdanega programa. Uporabljate jo na lastno odgovornost. Programa ne uporabljajte je za rudarjenje ali trgovske aplikacije.</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer. Bitcoin Core is probably already running.</source>
+ <translation>Na tem računalniku ni bilo mogoče vezati naslova %s. Odjemalec Bitcoin Core je verjetno že zagnan.</translation>
+ </message>
+ <message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>OPOZORILO: Generirano je bilo nenavadno veliko število blokov. Št. prejetih blokov: %d v št. ur: %d (pričakovanih je %d blokov)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>OPOZORILO: Preverite vašo omrežno povezavo. Št. prejetih blokov: %d v št. ur: %d (pričakovanih je %d blokov)</translation>
+ </message>
+ <message>
+ <source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Opozorilo: Vrednost opcije -paytxfee je zelo visoka. To je provizija, ki jo boste plačali, če izvedete plačilo.</translation>
+ </message>
+ <message>
+ <source>Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues.</source>
+ <translation>Opozorilo: Trenutno na omrežju ni videti konsenza! Videti je, kot da bi imeli nekateri rudarji težave.</translation>
+ </message>
+ <message>
+ <source>Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
+ <translation>Opozorilo: Trenutno se s soležniki ne strinjam v popolnosti! Mogoče bi morali vi ali drugi udeleženci posodobiti odjemalce.</translation>
</message>
<message>
<source>Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
- <translation>Opozorilo: napaka pri branju wallet.dat! Vsi ključi so bili pravilno prebrani, podatki o transakciji ali imenik vnešenih naslovov so morda izgubljeni ali nepravilni.</translation>
+ <translation>Opozorilo: napaka pri branju datoteke wallet.dat! Vsi ključi so bili pravilno prebrani, podatki o transakciji ali imenik vnešenih naslovov so morda izgubljeni ali nepravilni.</translation>
+ </message>
+ <message>
+ <source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
+ <translation>Opozorilo: Datoteka wallet.dat je bila okvarjena, podatki pa so bili kljub temu rešeni! Originalna datoteka je bila shranjena kot wallet.{čas.oznaka}.bak v mapo %s. Če sta skupno stanje ali seznam transakcij napačna, morate datoteko restavrirati iz varnostne kopije.</translation>
+ </message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Sprejemaj povezave samo od soležnikov, ki so na naslovih, ki ustrezajo navedeni omrežni maski ali naslovu. Opcijo lahko navedete večkrat.</translation>
</message>
<message>
<source>(default: 1)</source>
@@ -1991,92 +2881,328 @@
<translation>&lt;category&gt; je lahko:</translation>
</message>
<message>
+ <source>Attempt to recover private keys from a corrupt wallet.dat</source>
+ <translation>Skušaj obnoviti zasebne ključe iz okvarjene datoteke wallet.dat</translation>
+ </message>
+ <message>
<source>Block creation options:</source>
<translation>Možnosti ustvarjanja blokov:</translation>
</message>
<message>
+ <source>Connect only to the specified node(s)</source>
+ <translation>Poveži se samo z (enim ali več) navedenimi vozlišči</translation>
+ </message>
+ <message>
+ <source>Connection options:</source>
+ <translation>Izbire povezave:</translation>
+ </message>
+ <message>
+ <source>Corrupted block database detected</source>
+ <translation>Podatkovna baza blokov je okvarjena</translation>
+ </message>
+ <message>
+ <source>Debugging/Testing options:</source>
+ <translation>Možnosti razhroščevanja in testiranja:</translation>
+ </message>
+ <message>
+ <source>Do not load the wallet and disable wallet RPC calls</source>
+ <translation>Ne naloži denarnice in onemogoči s tem povezane klice RPC</translation>
+ </message>
+ <message>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Želite zdaj obnoviti podatkovno bazo blokov?</translation>
+ </message>
+ <message>
+ <source>Error initializing block database</source>
+ <translation>Napaka pri inicializaciji podatkovne baze blokov</translation>
+ </message>
+ <message>
+ <source>Error initializing wallet database environment %s!</source>
+ <translation>Napaka pri inicializaciji okolja podatkovne baze denarnice %s!</translation>
+ </message>
+ <message>
+ <source>Error loading block database</source>
+ <translation>Napaka pri nalaganju podatkovne baze blokov</translation>
+ </message>
+ <message>
+ <source>Error opening block database</source>
+ <translation>Napaka pri odpiranju podatkovne baze blokov</translation>
+ </message>
+ <message>
+ <source>Error: A fatal internal error occured, see debug.log for details</source>
+ <translation>Napaka: Med izvajanjem je prišlo do nepopravljive napake. Podrobnosti so v datoteki debug.log</translation>
+ </message>
+ <message>
<source>Error: Disk space is low!</source>
<translation>Opozorilo: Premalo prostora na disku!</translation>
</message>
<message>
+ <source>Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <translation>Ni mogoče poslušati na nobenih vratih. Če to zares želite, uporabite opcijo -listen=0.</translation>
+ </message>
+ <message>
+ <source>If &lt;category&gt; is not supplied, output all debugging information.</source>
+ <translation>Če element &lt;category&gt; ni naveden, izpisuje vse informacije za razhroščevanje.</translation>
+ </message>
+ <message>
<source>Importing...</source>
- <translation>Uvažam...</translation>
+ <translation>Uvažam ...</translation>
+ </message>
+ <message>
+ <source>Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <translation>Izvornega bloka ni mogoče najti ali pa je neveljaven. Preverite, če ste izbrali pravo podatkovno mapo za izbrano omrežje.</translation>
+ </message>
+ <message>
+ <source>Invalid -onion address: '%s'</source>
+ <translation>Neveljaven naslov tipa -onion: '%s'</translation>
+ </message>
+ <message>
+ <source>Not enough file descriptors available.</source>
+ <translation>Na voljo ni dovolj deskriptorjev datotek.</translation>
+ </message>
+ <message>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation>Povezuj se samo z vozlišči na omrežju tipa &lt;net&gt; (IPv4, IPv6 ali onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Negativne vrednosti parametra funkcije obrezovanja niso sprejemljive.</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Funkcija obrezovanja ni združljiva z opcijo -txindex.</translation>
+ </message>
+ <message>
+ <source>Set database cache size in megabytes (%d to %d, default: %d)</source>
+ <translation>Nastavitev velikosti predpomnilnik podatkovne baze v MiB (%d do %d, privzeto: %d)</translation>
+ </message>
+ <message>
+ <source>Set maximum block size in bytes (default: %d)</source>
+ <translation>Nastavitev maksimalne velikosti bloka v bajtih (privzeto: %d)</translation>
+ </message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Ime datoteke z denarnico (znotraj podatkovne mape)</translation>
+ </message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Uporabi protokol UPnP za preslikavo vrat za poslušanje (privzeto: %u)</translation>
+ </message>
+ <message>
+ <source>Verifying blocks...</source>
+ <translation>Preverjam celovitost blokov ...</translation>
+ </message>
+ <message>
+ <source>Verifying wallet...</source>
+ <translation>Preverjam celovitost denarnice ...</translation>
+ </message>
+ <message>
+ <source>Wallet %s resides outside data directory %s</source>
+ <translation>Datoteka %s z denarnico se nahaja izven podatkovne mape %s</translation>
+ </message>
+ <message>
+ <source>Wallet options:</source>
+ <translation>Izbire denarnice:</translation>
+ </message>
+ <message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Opozorilo: Različica vašega odjemalca je zastarela. Potrebna je nadgradnja!</translation>
+ </message>
+ <message>
+ <source>You need to rebuild the database using -reindex to change -txindex</source>
+ <translation>Ob spremembi vrednosti opcije -txindex boste morali obnoviti bazo podatkov z uporabo opcije -reindex</translation>
+ </message>
+ <message>
+ <source>Imports blocks from external blk000??.dat file</source>
+ <translation>Uvozi bloke iz zunanje datoteke blk000??.dat</translation>
+ </message>
+ <message>
+ <source>Allow JSON-RPC connections from specified source. Valid for &lt;ip&gt; 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 &lt;ip&gt; so: edinstven naslov IP (npr.: 1.2.3.4), kombinacija omrežje/netmask (npr.: 1.2.3.4/255.255.255.0), ali pa kombinacija omrežje/CIDR (1.2.3.4/24). To opcijo lahko navedete večkrat.</translation>
+ </message>
+ <message>
+ <source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
+ <translation>Prišlo je do napake med zagonom poslušalca RPC na naslovu %s in vratih %u: %s</translation>
+ </message>
+ <message>
+ <source>Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6</source>
+ <translation>Veži dani naslov in sprejemaj povezave samo od navedenih soležnikov. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata.</translation>
+ </message>
+ <message>
+ <source>Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)</source>
+ <translation>Veži dani naslov in sprejemaj povezave na JSON-RPC. Za naslove protokola IPv6 uporabite zapis [gostitelj]:vrata. To opcijo lahko navedete večkrat. (privzeto: veži vse omrežne vmesnike)</translation>
+ </message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Ne morem zakleniti podatkovne mape %s. Bitcoin Core je verjetno že zagnan.</translation>
+ </message>
+ <message>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Ustvarjaj nove datoteke s privzetimi sistemskimi dovoljenji, namesto z umask 077. (To pride v poštev samo, kadar imate izklopljeno funkcijo denarnice.)</translation>
+ </message>
+ <message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Odkrij svoj naslov IP (privzeto: 1, če poslušate in sta opciji -externalip in -proxy neaktivni)</translation>
+ </message>
+ <message>
+ <source>Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <translation>Napaka: Ni mogoče sprejemati dohodnih povezav (vrnjena napaka: %s)</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Napaka: Navedli ste nepodprto vrednost opcije -socks. Različice protokola SOCKS ni več mogoče navesti, podprti so samo posredniški strežniki tipa SOCKS5.</translation>
+ </message>
+ <message>
+ <source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
+ <translation>Ko bo prejeto ustrezno opozorilo, ali ko bo opažena zelo dolga razvejitev, izvedi navedeni ukazni niz. (Niz %s bo nadomeščen z vsebino sporočila.)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Provizije (v BTC/KiB), ki so manjše od te vrednosti, se pri posredovanju smatrajo za nične (privzeto: %s)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
+ <translation>Če opcija -paytxfee ni nastavljena, nastavi znesek provizije tako visoko, da bodo transakcije potrjene v povprečno n blokih. (privzeto: %u)</translation>
+ </message>
+ <message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Na vsak posredniški strežnik se prijavi z drugimi naključnimi podatki. Tako je omogočena osamitev tokov v omrežju Tor (privzeto: %u)</translation>
+ </message>
+ <message>
+ <source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
+ <translation>Opozorilo: Preverite, če sta datum in ura na vašem računalniku točna! Bitcoin Core ne bo dobro deloval, če je nastavljeni čas nepravilen.</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(privzeto: %u)</translation>
+ </message>
+ <message>
+ <source>Activating best chain...</source>
+ <translation>Preklapljam na najboljšo verigo ...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Če je omogočena funkcija obrezovanja, ni mogoče uporabljati denarnice.</translation>
+ </message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Naslova %s, podanega pri opciji -whitebind ni mogoče razrešiti.</translation>
</message>
<message>
<source>Choose data directory on startup (default: 0)</source>
- <translation>Ob zagonu izberi mapo za shranjevanje podatkov (privzeto: 0)</translation>
+ <translation>Ob zagonu pozovi uporabnika, naj izbere podatkovno mapo (privzeto: 0)</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Poveži se preko posredniškega strežnika SOCKS5</translation>
+ </message>
+ <message>
+ <source>Copyright (C) 2009-%i The Bitcoin Core Developers</source>
+ <translation>Copyright (C) 2009-%i The Bitcoin Core Developers</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Vrednost %s opcije -rpcbind ni prepoznaven omrežni naslov</translation>
</message>
<message>
<source>Information</source>
<translation>Informacije</translation>
</message>
<message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Pri opciji -whitebind morate navesti vrata: %s</translation>
+ </message>
+ <message>
<source>Send trace/debug info to console instead of debug.log file</source>
- <translation>Pošlji sledilne/razhroščevalne informacije v konzolo namesto jih shraniti v debug.log datoteko</translation>
+ <translation>Pošilja sledilne/razhroščevalne informacije na konzolo namesto v datoteko debug.log</translation>
</message>
<message>
<source>Set SSL root certificates for payment request (default: -system-)</source>
- <translation>Nastavi korenske SSL certifikate za plačilni zahtevek (privzeto: -system-)</translation>
+ <translation>Nastavi korenske certifikate SSL za preverjanje zahtevkov za plačilo (privzeto: -system-)</translation>
</message>
<message>
<source>Set language, for example "de_DE" (default: system locale)</source>
- <translation>Nastavi jezik, npr. "sl_SI" (privzeto: jezikovna oznaka sistema)</translation>
+ <translation>Nastavi jezik, npr. "sl_SI" (privzeto: jezik sistema)</translation>
</message>
<message>
<source>Show splash screen on startup (default: 1)</source>
<translation>Ob zagonu prikaži uvodni zaslon (privzeto: 1)</translation>
</message>
<message>
+ <source>Shrink debug.log file on client startup (default: 1 when no -debug)</source>
+ <translation>Ob zagonu skrajšaj datoteko debug.log (privzeto: 1, če ni vklopljena opcija -debug)</translation>
+ </message>
+ <message>
<source>Signing transaction failed</source>
- <translation>Podpisovanje transakcije spodletelo</translation>
+ <translation>Transakcije ni bilo mogoče podpisati.</translation>
</message>
<message>
<source>Start minimized</source>
- <translation>Zaženi pomanjšano</translation>
+ <translation>Zaženi v minimiranem oknu</translation>
+ </message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Program je eksperimentalne narave.</translation>
</message>
<message>
<source>Transaction amount too small</source>
- <translation>Količina transakcije je pramajhna</translation>
+ <translation>Znesek je pramajhen</translation>
</message>
<message>
<source>Transaction amounts must be positive</source>
- <translation>Količina transkacije mora biti pozitivna</translation>
+ <translation>Znesek mora biti pozitiven</translation>
</message>
<message>
<source>Transaction too large</source>
<translation>Transkacija je prevelika</translation>
</message>
<message>
+ <source>UI Options:</source>
+ <translation>Možnosti uporabniškega vmesnika:</translation>
+ </message>
+ <message>
+ <source>Unable to bind to %s on this computer (bind returned error %s)</source>
+ <translation>Na tem računalniku ni bilo mogoče vezati naslova %s (vrnjena napaka: %s)</translation>
+ </message>
+ <message>
<source>Username for JSON-RPC connections</source>
- <translation>Uporabniško ime za JSON-RPC povezave</translation>
+ <translation>Uporabniško ime za povezave na JSON-RPC</translation>
</message>
<message>
<source>Warning</source>
<translation>Opozorilo</translation>
</message>
<message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Brišem vse transakcije iz denarnice ...</translation>
+ </message>
+ <message>
+ <source>on startup</source>
+ <translation>ob zagonu</translation>
+ </message>
+ <message>
<source>wallet.dat corrupt, salvage failed</source>
- <translation>wallet.dat poškodovana, neuspešna obnova</translation>
+ <translation>Datoteka wallet.dat je poškodovana in je ni bilo mogoče obnoviti.</translation>
</message>
<message>
<source>Password for JSON-RPC connections</source>
- <translation>Geslo za JSON-RPC povezave</translation>
+ <translation>Geslo za povezave na JSON-RPC</translation>
</message>
<message>
<source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
- <translation>Izvedi ukaz, ko je najboljši blok spremenjen (%s je v cmd zamenjan za iskalnik blokov)</translation>
+ <translation>Izvedi ukaz, ko je najden najboljši blok (niz %s v ukazu bo zamenjan s hash vrednostjo bloka)</translation>
</message>
<message>
<source>Upgrade wallet to latest format</source>
- <translation>Posodobi denarnico v najnovejši zapis</translation>
+ <translation>Nadgradi denarnico na najnovejšo različico</translation>
</message>
<message>
<source>Rescan the block chain for missing wallet transactions</source>
- <translation>Ponovno preglej verigo blokov za manjkajoče transakcije denarnice</translation>
+ <translation>S ponovnim pregledom verige blokov poišči manjkajoče transakcije iz denarnice</translation>
</message>
<message>
<source>Use OpenSSL (https) for JSON-RPC connections</source>
- <translation>Uporabi OpenSSL (https) za JSON-RPC povezave</translation>
+ <translation>Uporabi OpenSSL (https) za povezave na JSON-RPC</translation>
</message>
<message>
<source>This help message</source>
@@ -2084,23 +3210,59 @@
</message>
<message>
<source>Allow DNS lookups for -addnode, -seednode and -connect</source>
- <translation>Omogoči DNS poizvedbe za -addnode, -seednode in -connect.</translation>
+ <translation>Omogoči poizvedbe DNS za opcije -addnode, -seednode in -connect.</translation>
</message>
<message>
<source>Loading addresses...</source>
- <translation>Nalaganje naslovov ...</translation>
+ <translation>Nalagam naslove ...</translation>
</message>
<message>
<source>Error loading wallet.dat: Wallet corrupted</source>
<translation>Napaka pri nalaganju wallet.dat: denarnica pokvarjena</translation>
</message>
<message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Za dostop do soležnikov preko skritih storitev Tor uporabi drug posredniški strežnik SOCKS5 (privzeto: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(privzeto: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Sprejemljivi tipi šifriranja (privzeto: %s)</translation>
+ </message>
+ <message>
<source>Error loading wallet.dat</source>
<translation>Napaka pri nalaganju wallet.dat</translation>
</message>
<message>
<source>Invalid -proxy address: '%s'</source>
- <translation>Neveljaven -proxy naslov: '%s'</translation>
+ <translation>Neveljaven naslov -proxy: '%s'</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Posreduj transakcije tipa multisig, ki niso hkrati tipa P2SH. (privzeto: %u)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Za shranjevanje konfiguracije uporabi navedeno datoteko. (privzeto: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Vzpostavljanje nove povezave poteče po navedenem št. pretečenih milisekund. (najmanj: 1, privzeto: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Za shranjevanje PID uporabi navedeno datoteko. (privzeto: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Pri odlivnih transakcijah omogoči trošenje drobiža iz še nepotrjenih plačil (privzeto: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Prekini povezavo s soležnikom, ko št. njegovih kazenskih točk preseže navedeni prag. (privzeto: %u)</translation>
</message>
<message>
<source>Unknown network specified in -onlynet: '%s'</source>
@@ -2108,11 +3270,11 @@
</message>
<message>
<source>Cannot resolve -bind address: '%s'</source>
- <translation>Nemogoče rešiti -bind naslova: '%s'</translation>
+ <translation>Naslova %s, podanega pri opciji -bind ni mogoče razrešiti.</translation>
</message>
<message>
<source>Cannot resolve -externalip address: '%s'</source>
- <translation>Nemogoče rešiti -externalip naslova: '%s'</translation>
+ <translation>Naslova "%s", podanega pri opciji -externalip ni mogoče razrešiti.</translation>
</message>
<message>
<source>Invalid amount for -paytxfee=&lt;amount&gt;: '%s'</source>
@@ -2124,15 +3286,15 @@
</message>
<message>
<source>Loading block index...</source>
- <translation>Nalaganje indeksa blokov ...</translation>
+ <translation>Nalagam kazalo blokov ...</translation>
</message>
<message>
<source>Add a node to connect to and attempt to keep the connection open</source>
- <translation>Dodaj vozlišče za povezavo nanj in skušaj le to obdržati odprto</translation>
+ <translation>Dodaj povezavo na vozlišče in jo skušaj držati odprto</translation>
</message>
<message>
<source>Loading wallet...</source>
- <translation>Nalaganje denarnice ...</translation>
+ <translation>Nalagam denarnico ...</translation>
</message>
<message>
<source>Cannot downgrade wallet</source>
@@ -2144,7 +3306,7 @@
</message>
<message>
<source>Rescanning...</source>
- <translation>Ponovno pregledovanje ...</translation>
+ <translation>Ponovno pregledujem verigo ...</translation>
</message>
<message>
<source>Done loading</source>
diff --git a/src/qt/locale/bitcoin_sq.ts b/src/qt/locale/bitcoin_sq.ts
index 2e345e85cb..6ed9856889 100644
--- a/src/qt/locale/bitcoin_sq.ts
+++ b/src/qt/locale/bitcoin_sq.ts
@@ -1,4 +1,4 @@
-<TS language="sq" version="2.1">
+<TS language="sq" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -46,14 +46,38 @@
<translation>Duke marr adresen</translation>
</message>
<message>
+ <source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
+ <translation>Këto janë Bitcoin adresat e juaja për të dërguar pagesa. Gjithmon kontrolloni shumën dhe adresën pranuese para se të dërgoni monedha.</translation>
+ </message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Këto janë Bitcoin adresat e juaja për të pranuar pagesa. Rekomandohet që gjithmon të përdorni një adresë të re për çdo transaksion.</translation>
+ </message>
+ <message>
+ <source>Copy &amp;Label</source>
+ <translation>Kopjo &amp;Etiketë</translation>
+ </message>
+ <message>
<source>&amp;Edit</source>
<translation>&amp;Ndrysho</translation>
</message>
<message>
+ <source>Export Address List</source>
+ <translation>Eksporto listën e adresave</translation>
+ </message>
+ <message>
<source>Comma separated file (*.csv)</source>
<translation>Skedar i ndarë me pikëpresje(*.csv)</translation>
</message>
- </context>
+ <message>
+ <source>Exporting Failed</source>
+ <translation>Eksportimi dështoj</translation>
+ </message>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Gabim gjatë ruajtjes së listës së adresave në %1. Ju lutem provoni prapë.</translation>
+ </message>
+</context>
<context>
<name>AddressTableModel</name>
<message>
@@ -688,6 +712,10 @@
<translation>Kopjo adresën</translation>
</message>
<message>
+ <source>Exporting Failed</source>
+ <translation>Eksportimi dështoj</translation>
+ </message>
+ <message>
<source>Comma separated file (*.csv)</source>
<translation>Skedar i ndarë me pikëpresje(*.csv)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts
index 83e6e2f29e..ddaab9ab2b 100644
--- a/src/qt/locale/bitcoin_sr.ts
+++ b/src/qt/locale/bitcoin_sr.ts
@@ -1,4 +1,4 @@
-<TS language="sr" version="2.1">
+<TS language="sr" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts
index 289074f134..0139154019 100644
--- a/src/qt/locale/bitcoin_sv.ts
+++ b/src/qt/locale/bitcoin_sv.ts
@@ -1,4 +1,4 @@
-<TS language="sv" version="2.1">
+<TS language="sv" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -67,11 +67,11 @@
</message>
<message>
<source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
- <translation>Detta är dina Bitcoin adresser för att skicka betalningar. Kolla alltid summan och den mottagande adressen innan du skickar Bitcoins.</translation>
+ <translation>Detta är dina Bitcoin-adresser för att skicka betalningar. Kolla alltid summan och den mottagande adressen innan du skickar Bitcoins.</translation>
</message>
<message>
<source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
- <translation>Detta är dina Bitcoin adresser för att ta emot betalningar. Det rekommenderas att använda en ny mottagningsadress för varje transaktion.</translation>
+ <translation>Detta är dina Bitcoin-adresser för att ta emot betalningar. Det rekommenderas att använda en ny mottagningsadress för varje transaktion.</translation>
</message>
<message>
<source>Copy &amp;Label</source>
@@ -111,14 +111,14 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>(no label)</source>
- <translation>(Ingen etikett)</translation>
+ <translation>(ingen etikett)</translation>
</message>
</context>
<context>
<name>AskPassphraseDialog</name>
<message>
<source>Passphrase Dialog</source>
- <translation>Lösenords Dialog</translation>
+ <translation>Lösenordsdialog</translation>
</message>
<message>
<source>Enter passphrase</source>
@@ -281,7 +281,7 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>&amp;Change Passphrase...</source>
- <translation>&amp;Byt Lösenord...</translation>
+ <translation>&amp;Byt lösenord...</translation>
</message>
<message>
<source>&amp;Sending addresses...</source>
@@ -297,7 +297,7 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>Bitcoin Core client</source>
- <translation>Bitcoin Core klient</translation>
+ <translation>Bitcoin Core-klient</translation>
</message>
<message>
<source>Importing blocks from disk...</source>
@@ -321,7 +321,7 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>&amp;Debug window</source>
- <translation>&amp;Debug fönster</translation>
+ <translation>&amp;Debug-fönster</translation>
</message>
<message>
<source>Open debugging and diagnostic console</source>
@@ -385,11 +385,11 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>Tabs toolbar</source>
- <translation>Verktygsfält för Tabbar</translation>
+ <translation>Verktygsfält för tabbar</translation>
</message>
<message>
<source>Bitcoin Core</source>
- <translation>Bitcoin Kärna</translation>
+ <translation>Bitcoin Core</translation>
</message>
<message>
<source>Request payments (generates QR codes and bitcoin: URIs)</source>
@@ -421,7 +421,7 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
- <translation>Visa Bitcoin Core hjälpmeddelande för att få en lista med möjliga Bitcoin kommandoradsalternativ.</translation>
+ <translation>Visa Bitcoin Cores hjälpmeddelande för att få en lista med möjliga Bitcoin-kommandoradsalternativ.</translation>
</message>
<message numerus="yes">
<source>%n active connection(s) to Bitcoin network</source>
@@ -461,7 +461,7 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>Last received block was generated %1 ago.</source>
- <translation>Senast mottagna block genererades %1 sen.</translation>
+ <translation>Senast mottagna block genererades för %1 sen.</translation>
</message>
<message>
<source>Transactions after this will not yet be visible.</source>
@@ -553,7 +553,7 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>Bytes:</source>
- <translation>Antal Byte:</translation>
+ <translation>Antal byte:</translation>
</message>
<message>
<source>Amount:</source>
@@ -581,15 +581,15 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>(un)select all</source>
- <translation>(av)välj allt</translation>
+ <translation>(av)markera allt</translation>
</message>
<message>
<source>Tree mode</source>
- <translation>Trädmetod</translation>
+ <translation>Trädvy</translation>
</message>
<message>
<source>List mode</source>
- <translation>Listmetod</translation>
+ <translation>Listvy</translation>
</message>
<message>
<source>Amount</source>
@@ -609,7 +609,7 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>Confirmations</source>
- <translation>Konfirmationer</translation>
+ <translation>Bekräftelser</translation>
</message>
<message>
<source>Confirmed</source>
@@ -764,7 +764,7 @@ Var vänlig och försök igen.</translation>
<name>EditAddressDialog</name>
<message>
<source>Edit Address</source>
- <translation>Redigera Adress</translation>
+ <translation>Redigera adress</translation>
</message>
<message>
<source>&amp;Label</source>
@@ -842,7 +842,7 @@ Var vänlig och försök igen.</translation>
<name>HelpMessageDialog</name>
<message>
<source>Bitcoin Core</source>
- <translation>Bitcoin Kärna</translation>
+ <translation>Bitcoin Core</translation>
</message>
<message>
<source>version</source>
@@ -881,11 +881,11 @@ Var vänlig och försök igen.</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>Eftersom detta är första gången programmet startas får du välja var Bitcoin Core skall lagra sitt data.</translation>
+ <translation>Eftersom detta är första gången programmet startas får du välja var Bitcoin Core skall lagra sina data.</translation>
</message>
<message>
<source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
- <translation>Bitcoin Core kommer att ladda ner och spara en kopia av Bitcoin blockkedjan. Åtminstone %1GB av data kommer att sparas i denna katalog, och den kommer att växa över tiden. Plånboken kommer också att sparas i denna katalog.</translation>
+ <translation>Bitcoin Core kommer att ladda ner och spara en kopia av Bitcoin-blockkedjan. Åtminstone %1GB av data kommer att sparas i denna katalog, och den kommer att växa över tiden. Plånboken kommer också att sparas i denna katalog.</translation>
</message>
<message>
<source>Use the default data directory</source>
@@ -897,7 +897,7 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>Bitcoin Core</source>
- <translation>Bitcoin Kärna</translation>
+ <translation>Bitcoin Core</translation>
</message>
<message>
<source>Error: Specified data directory "%1" cannot be created.</source>
@@ -959,7 +959,7 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>Number of script &amp;verification threads</source>
- <translation>Antalet skript &amp; verifikationstrådar</translation>
+ <translation>Antalet skript&amp;verifikationstrådar</translation>
</message>
<message>
<source>Accept connections from outside</source>
@@ -983,7 +983,7 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
- <translation>Tredjeparts URL:er (t.ex. en block utforskare) som finns i transaktionstabben som ett menyval i sammanhanget. %s i URL:en ersätts med tansaktionshashen. Flera URL:er är separerade med vertikala streck |.</translation>
+ <translation>Tredjeparts URL:er (t.ex. en blockutforskare) som finns i transaktionstabben som ett menyval i sammanhanget. %s i URL:en ersätts med tansaktionshashen. Flera URL:er är separerade med vertikala streck |.</translation>
</message>
<message>
<source>Third party transaction URLs</source>
@@ -991,15 +991,15 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>Active command-line options that override above options:</source>
- <translation>Aktiva kommandoradsalternativ som överrider alternativen ovan:</translation>
+ <translation>Aktiva kommandoradsalternativ som ersätter alternativen ovan:</translation>
</message>
<message>
<source>Reset all client options to default.</source>
- <translation>Återställ alla klient inställningar till förvalen.</translation>
+ <translation>Återställ alla klientinställningar till förvalen.</translation>
</message>
<message>
<source>&amp;Reset Options</source>
- <translation>&amp;Återställ Alternativ</translation>
+ <translation>&amp;Återställ alternativ</translation>
</message>
<message>
<source>&amp;Network</source>
@@ -1027,15 +1027,15 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>Enable coin &amp;control features</source>
- <translation>Aktivera mynt och kontrollfunktioner</translation>
+ <translation>Aktivera mynt&amp;kontrollfunktioner</translation>
</message>
<message>
<source>If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
- <translation>Om du avaktiverar betalning med okonfirmerade växel, kan inte växeln från en transaktion användas förrän den transaktionen har minst en konfirmation.</translation>
+ <translation>Om du avaktiverar betalning med obekräftad växel, kan inte växeln från en transaktion användas förrän den transaktionen har minst en bekräftelse.</translation>
</message>
<message>
<source>&amp;Spend unconfirmed change</source>
- <translation>&amp;Spendera okonfirmerad växel</translation>
+ <translation>&amp;Spendera obekräftad växel</translation>
</message>
<message>
<source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
@@ -1095,7 +1095,7 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
- <translation>Välj en måttenhet att visa när du skickar mynt.</translation>
+ <translation>Välj en måttenhet att visa i gränssnittet och när du skickar mynt.</translation>
</message>
<message>
<source>Whether to show coin control features or not.</source>
@@ -1135,7 +1135,7 @@ Var vänlig och försök igen.</translation>
</message>
<message>
<source>The supplied proxy address is invalid.</source>
- <translation>Den medföljande proxy adressen är ogiltig.</translation>
+ <translation>Den angivna proxy-adressen är ogiltig.</translation>
</message>
</context>
<context>
@@ -2806,10 +2806,6 @@ Var vänlig och försök igen.</translation>
<translation>Bind till given adress och lyssna alltid på den. Använd [värd]:port notation för IPv6</translation>
</message>
<message>
- <source>Continuously rate-limit free transactions to &lt;n&gt;*1000 bytes per minute (default: %u)</source>
- <translation>Hastighetsbegränsa avgiftsfria transaktionerna till &lt;n&gt;*1000 bytes per minut (förvalt: %u)</translation>
- </message>
- <message>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Ta bort alla plånbokstransaktioner och återskapa bara dom som är en del av blockkedjan genom att ange -rescan vid uppstart</translation>
</message>
@@ -2818,18 +2814,10 @@ Var vänlig och försök igen.</translation>
<translation>Distribuerad under MIT mjukvarulicens, se den bifogade filen COPYING eller &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Ange regressiontestläge, som använder en speciell kedja i vilka block kan lösas omedelbart.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Exekvera kommando när en plånbokstransaktion ändras (%s i cmd är ersatt av TxID)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>I denna mode kontrollerar -genproclimit hur många block som genereras på en gång.</translation>
- </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>
@@ -2850,6 +2838,14 @@ 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>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>Varning: Onormalt antal block block genererade. %d block mottagna senaste %d timmarna (%d förväntade)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>Varning: Kontrollera din närverksanslutning. %d block mottagna senaste %d timmarna, (%d förväntade)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Varning: -paytxfee är satt väldigt hög! Detta är avgiften du kommer betala för varje transaktion.</translation>
</message>
@@ -2986,10 +2982,6 @@ Var vänlig och försök igen.</translation>
<translation>Ange plånboksfil (inom datakatalogen)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Detta är avsett för regressionstestningsverktyg och applikationsutveckling.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Använd UPnP för att mappa den lyssnande porten (förvalt: %u)</translation>
</message>
@@ -3066,10 +3058,6 @@ Var vänlig och försök igen.</translation>
<translation>Avgifter (i BTC/Kb) mindre än detta betraktas som nollavgift för vidarebefodran (förvalt: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Avgifter (i BTC/Kb) mindre än detta betraktas som nollavgift för transaktionsskapande (förvalt: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Om paytxfee inte är satt, inkludera tillräcklig avgift så att transaktionen börjar att konfirmeras inom n blocks (förvalt: %u)</translation>
</message>
@@ -3094,10 +3082,6 @@ Var vänlig och försök igen.</translation>
<translation>Slumpa autentiseringen för varje proxyanslutning. Detta möjliggör Tor ström-isolering (förvalt: %u)</translation>
</message>
<message>
- <source>Require high priority for relaying free or low-fee transactions (default: %u)</source>
- <translation>Begär hög prioritet för att vidarebefodra lågavgiftstransaktioner (förvalt: %u)</translation>
- </message>
- <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Sätt den maximala storleken av hög-prioriterade/låg-avgifts transaktioner i byte (förvalt: %d)</translation>
</message>
@@ -3162,10 +3146,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Aktiverar bästa kedjan...</translation>
</message>
<message>
- <source>Allow self signed root certificates (default: 0)</source>
- <translation>Tillåt självsignerade root-certifikat (förvalt: 0)</translation>
- </message>
- <message>
<source>Can't run with a wallet in prune mode.</source>
<translation>Kan inte köra med en plånbok i beskärningsläge.</translation>
</message>
@@ -3258,18 +3238,14 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>RPC support för HTTP permanent anslutning (förvalt: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Slumpmässigt tappa 1 av varje &lt;n&gt; nåtverksmeddelande</translation>
- </message>
- <message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Slupmässigt brus 1 gång varje &lt;n&gt; nätverksmeddelande</translation>
- </message>
- <message>
<source>Rebuild block chain index from current blk000??.dat files on startup</source>
<translation>Återskapa blockkedjans index från nuvarande blk000??.dat filer under uppstarten</translation>
</message>
<message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Mottag och visa P2P nätverksvarningar (förvalt: %u)</translation>
+ </message>
+ <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Skicka trace-/debuginformation till terminalen istället för till debug.log</translation>
</message>
@@ -3414,18 +3390,10 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>(1 = spara tx metadata t.ex. kontoägare och betalningsbegäransinformation, 2 = släng tx metadata)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Töm databasens minnespool till disk varje &lt;n&gt; megabytes (förvalt: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Hur grundlig blockverifikationen vid -checkblocks är (0-4, förvalt: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Logga transaktionsprioritet och avgift per kB vid blockbrytning (förvalt: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Upprätthåll ett fullständigt transaktionsindex, som används av getrawtransaction rpc-anrop (förval: %u)</translation>
</message>
@@ -3454,18 +3422,10 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Sök alltid efter klientadresser med DNS sökningen (förvalt: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Avaktivera säkert läge. Åsidosätt en riktigt säkert läge händelse (förvalt: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>Fel vid inläsning av plånboksfilen wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Tvångskör i säkert läge (förvalt: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Generera mynt (förvalt: %u)</translation>
</message>
@@ -3482,10 +3442,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Ogiltig -proxy adress: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Begränsa signaturcachestorleken till &lt;n&gt; poster (förvalt: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Lyssna på JSON-RPC-anslutningar på &lt;port&gt; (förval: %u eller testnet: %u)</translation>
</message>
@@ -3510,10 +3466,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Maximal sändningsbuffert per anslutning, &lt;n&gt;*1000 byte (förvalt: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Acceptera bara blockkedjans matchande inbyggda kontrollpunkter (förvalt: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Skriv ut tidsstämpel i avlusningsinformationen (förvalt: %u)</translation>
</message>
@@ -3526,10 +3478,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Reläa icke P2SH multisig (förvalt: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Kör en tråd för att tömma plånboken periodiskt (förvalt: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>Serverns certifikatfil (förvalt: %s)</translation>
</message>
@@ -3550,10 +3498,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Ange antalet trådar för att hantera RPC anrop (förvalt: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Sätt DB_PRIVATE flaggan i plånbokens databasmiljö (förvalt: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Ange konfigurationsfil (förvalt: %s)</translation>
</message>
@@ -3570,10 +3514,6 @@ till exempel: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Spendera okonfirmerad växel när transaktioner sänds (förvalt: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Sluta köra efter importen av block från disk är klar (förvalt: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Tröskelvärde för att koppla ifrån klienter som missköter sig (förvalt: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts
index 7b5d1ae01c..0980502968 100644
--- a/src/qt/locale/bitcoin_th_TH.ts
+++ b/src/qt/locale/bitcoin_th_TH.ts
@@ -1,4 +1,4 @@
-<TS language="th_TH" version="2.1">
+<TS language="th_TH" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts
index bf6f3f2791..dcc82e644d 100644
--- a/src/qt/locale/bitcoin_tr.ts
+++ b/src/qt/locale/bitcoin_tr.ts
@@ -1,9 +1,9 @@
-<TS language="tr" version="2.1">
+<TS language="tr" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Right-click to edit address or label</source>
- <translation>Adresi ya da etiketi düzenlemek için sağ düğme ile tıklayınız.</translation>
+ <translation>Adres veya etiketi düzenlemek için sağ tıklayınız.</translation>
</message>
<message>
<source>Create a new address</source>
@@ -15,7 +15,7 @@
</message>
<message>
<source>Copy the currently selected address to the system clipboard</source>
- <translation>Şu anda seçili olan adresi sistem panosuna kopyala</translation>
+ <translation>Seçili adresi panoya kopyala</translation>
</message>
<message>
<source>&amp;Copy</source>
@@ -35,7 +35,7 @@
</message>
<message>
<source>Export the data in the current tab to a file</source>
- <translation>Güncel sekmedeki verileri bir dosyaya aktar</translation>
+ <translation>Açık olan sekmedeki verileri bir dosyaya aktar</translation>
</message>
<message>
<source>&amp;Export</source>
@@ -67,11 +67,11 @@
</message>
<message>
<source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
- <translation>Bunlar ödeme yapmak için kullanacağınız Bitcoin adreslerinizdir. Bitcoin yollamadan önce meblağı ve alıcı adresini daima kontrol ediniz.</translation>
+ <translation>Bunlar ödemeleri göndermek için kullanacağınız Bitcoin adreslerinizdir. Bitcoin yollamadan önce miktarı ve alıcının alım adresini daima kontrol ediniz.</translation>
</message>
<message>
<source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
- <translation>Bunlar ödeme almak için kullanacağınız Bitcoin adreslerinizdir. Her muamele için yeni bir alım adresi kullanmanız tavsiye edilir.</translation>
+ <translation>Bunlar ödemeleri almak için kullanacağınız Bitcoin adreslerinizdir. Her işlem için yeni bir alım adresi kullanmanız tavsiye edilir.</translation>
</message>
<message>
<source>Copy &amp;Label</source>
@@ -110,7 +110,7 @@
</message>
<message>
<source>(no label)</source>
- <translation>(boş etiket)</translation>
+ <translation>(etiket yok)</translation>
</message>
</context>
<context>
@@ -145,11 +145,11 @@
</message>
<message>
<source>This operation needs your wallet passphrase to decrypt the wallet.</source>
- <translation>Bu işlem, cüzdan şifresini açmak için cüzdan parolasını gerektirir.</translation>
+ <translation>Bu işlem cüzdanın şifrelemesini açmak için cüzdan parolasını gerektirir.</translation>
</message>
<message>
<source>Decrypt wallet</source>
- <translation>Cüzdan şifresini aç</translation>
+ <translation>Cüzdanın şifrelemesini aç</translation>
</message>
<message>
<source>Change passphrase</source>
@@ -157,7 +157,7 @@
</message>
<message>
<source>Confirm wallet encryption</source>
- <translation>Cüzdan şifrelenmesini teyit eder</translation>
+ <translation>Cüzdanın şifrelemesini teyit eder</translation>
</message>
<message>
<source>Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
@@ -1323,7 +1323,7 @@
</message>
<message>
<source>Ping Time</source>
- <translation>Ping Zamanı</translation>
+ <translation>Ping Süresi</translation>
</message>
</context>
<context>
@@ -1492,7 +1492,7 @@
</message>
<message>
<source>Connection Time</source>
- <translation>Bağlantı Zamanı</translation>
+ <translation>Bağlantı Süresi</translation>
</message>
<message>
<source>Last Send</source>
@@ -1512,7 +1512,7 @@
</message>
<message>
<source>Ping Time</source>
- <translation>Ping Zamanı</translation>
+ <translation>Ping Süresi</translation>
</message>
<message>
<source>Time Offset</source>
@@ -2813,10 +2813,6 @@
<translation>Belirtilen adrese bağlan ve daima ondan dinle. IPv6 için [makine]:port yazımını kullanınız</translation>
</message>
<message>
- <source>Continuously rate-limit free transactions to &lt;n&gt;*1000 bytes per minute (default: %u)</source>
- <translation>Devamlı olarak ücretsiz muameleleri dakikada &lt;n&gt;*1000 bayt olarak sınırla (varsayılan: %u)</translation>
- </message>
- <message>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Tüm cüzdan muamelelerini sil ve başlangıçta -rescan ile sadece blok zincirinin parçası olanları geri getir</translation>
</message>
@@ -2825,18 +2821,10 @@
<translation>MIT yazılım lisansı kapsamında yayınlanmıştır, ekteki COPYING dosyasına ya da &lt;http://www.opensource.org/licenses/mit-license.php&gt; adresine bakınız.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Blokların anında çözülebileceği özel bir zincir kullanan regresyon deneme kipine gir.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Bir cüzdan muamelesi değiştiğinde komutu çalıştır (komuttaki %s muamele kimliği ile değiştirilecektir)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>Bu kipte -genproclimit kaç sayıda bloğun anında oluşturulduğunu kontrol eder.</translation>
- </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>
@@ -2857,6 +2845,14 @@
<translation>Bu bilgisayarda %s unsuruna bağlanılamadı. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır.</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>İKAZ: anormal yüksek sayıda blok oluşturulmuştur, %d blok son %d saat içinde alınmıştır (%d bekleniyordu)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>İKAZ: ağ bağlantınızı kontrol ediniz, %d blok son %d saat içinde alınmıştır (%d bekleniyordu)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Uyarı: -paytxfee çok yüksek bir değere ayarlanmış! Bu, muamele gönderirseniz ödeyeceğiniz muamele ücretidir.</translation>
</message>
@@ -2993,10 +2989,6 @@
<translation>Cüzdan dosyası belirtiniz (veri klasörünün içinde)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Bu, regresyon deneme araçları ve uygulama geliştirmesi için tasarlanmıştır. </translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Dinleme portunu haritalamak için UPnP kullan (varsayılan: %u)</translation>
</message>
@@ -3073,10 +3065,6 @@
<translation>Kb başına BTC olarak bundan düşük ücretler aktarım için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Kb başına BTC olarak bundan düşük ücretler muamele oluşturulması için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Eğer paytxfee ayarlanmadıysa kafi derecede ücret ekleyin ki muameleler teyite vasati n blok içinde başlasın (varsayılan: %u)</translation>
</message>
@@ -3101,10 +3089,6 @@
<translation>Her vekil bağlantısı için kimlik verilerini rastgele yap. Bu, Tor akış izolasyonunu etkinleştirir (varsayılan: %u)</translation>
</message>
<message>
- <source>Require high priority for relaying free or low-fee transactions (default: %u)</source>
- <translation>Ücretsiz ya da düşük ücretli muamelelerin geçişi için yüksek öncelik iste (varsayılan: %u)</translation>
- </message>
- <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Yüksek öncelikli/düşük ücretli muamelelerin azami boyutunu bayt olarak ayarla (varsayılan: %d)</translation>
</message>
@@ -3173,10 +3157,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>En iyi zincir etkinleştiriliyor...</translation>
</message>
<message>
- <source>Allow self signed root certificates (default: 0)</source>
- <translation>Kendinden imzalı kök sertifikalara müsaade et (varsayılan: 0)</translation>
- </message>
- <message>
<source>Can't run with a wallet in prune mode.</source>
<translation>Prune kipindeki bir cüzdan ile çalışamaz.</translation>
</message>
@@ -3269,18 +3249,14 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Kalıcı HTTP bağlantıları için RPC desteği (varsayılan: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Her &lt;n&gt; şebeke mesajından rastgele 1 mesajı görmezden gel</translation>
- </message>
- <message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Her &lt;n&gt; şebeke mesajından rastgele birini bulanıklaştır</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>
<message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>P2P ağından gelen önemli uyarıları alın ve gösterin (önseçili değer: %u)</translation>
+ </message>
+ <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Trace/hata ayıklama verilerini debug.log dosyası yerine konsola gönder</translation>
</message>
@@ -3425,18 +3401,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>(1 = tx meta verilerini tut mesela hesap sahibi ve ödeme talebi bilgileri, 2 = tx meta verilerini at)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Veritabanı etkinliğini bellekten disk kütüğüne her &lt;n&gt; megabaytta aktar (varsayılan: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>-checkblocks'un blok kontrolünün ne kadar kapsamlı olacağı (0 ilâ 4, varsayılan: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Blok oluşturulduğunda muamele önceliğini ve kB başı ücreti kütüğe al (varsayılan: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Muamelelerin tamamının indeksini tut, getrawtransaction rpc çağrısı tarafından kullanılır (varsayılan: %u)</translation>
</message>
@@ -3465,18 +3433,10 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Eş adresleri sorgulaması için daima DNS aramasını kullan (varsayılan: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Güvenli kipi devre dışı bırak, gerçek bir güvenli olayı geçersiz kıl (varsayılan: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>wallet.dat dosyasının yüklenmesinde hata oluştu</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Güvenli kipi zorla (varsayılan: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Bitcoin oluştur (varsayılan: %u)</translation>
</message>
@@ -3493,10 +3453,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Geçersiz -proxy adresi: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>İmza arabelleğinin boyutunu &lt;n&gt; unsurla sınırla (varsayılan: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>JSON-RPC bağlantılarını &lt;port&gt; üzerinde dinle (varsayılan: %u veya tesnet: %u)</translation>
</message>
@@ -3521,10 +3477,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Her bağlantı için azami yollama tamponu, &lt;n&gt;*1000 bayt (varsayılan: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Sadece yerleşik kontrol noktalarıyla eşleşen blok zincirini kabul et (varsayılan: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Hata ayıklama verilerinin önüne zaman damgası ekle (varsayılan: %u)</translation>
</message>
@@ -3537,10 +3489,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>P2SH olmayan çoklu imzaları aktar (varsayılan: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Periyodik olarak cüdanı diske yazdırmak için bir iş parçacığı çalıştır (varsayılan: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>Sunucu sertifika dosyası (varsayılan: %s)</translation>
</message>
@@ -3561,10 +3509,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Hizmet RCP aramaları iş parçacığı sayısını belirle (varsayılan: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Cüzdan veritabanı ortamında DB_PRIVATE bayrağını koyar (varsayılan: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Yapılandırma dosyası belirtiniz (varsayılan: %s)</translation>
</message>
@@ -3581,10 +3525,6 @@ mesela: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo.com
<translation>Gönderme muamelelerinde teyit edilmemiş para üstünü harca (varsayılan: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Diskten blokları içeri aktardıktan sonra çalışmayı durdur (varsayılan: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Aksaklık gösteren eşlerle bağlantıyı kesme sınırı (varsayılan: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts
index 92e0cc75c4..21ab4ac191 100644
--- a/src/qt/locale/bitcoin_uk.ts
+++ b/src/qt/locale/bitcoin_uk.ts
@@ -1,9 +1,9 @@
-<TS language="uk" version="2.1">
+<TS language="uk" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Right-click to edit address or label</source>
- <translation>Клік правою кнопкою для редагування адреси або мітки</translation>
+ <translation>Клікніть правою кнопкою для редагування адреси або мітки</translation>
</message>
<message>
<source>Create a new address</source>
@@ -71,7 +71,7 @@
</message>
<message>
<source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
- <translation>Це ваша нова Bitcoin адреса для отримування платежів. Рекомендовано використовувати нову адресу для кожної транзакції.</translation>
+ <translation>Це ваша нова Bitcoin адреса для отримання платежів. Рекомендовано використовувати нову адресу для кожної транзакції.</translation>
</message>
<message>
<source>Copy &amp;Label</source>
@@ -168,8 +168,12 @@
<translation>Ви дійсно хочете зашифрувати свій гаманець?</translation>
</message>
<message>
+ <source>Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>Клієнт «Bitcoin Core» буде закрито для завершення процесу шифрування. Пам'ятайте, що шифрування гаманця не зможе повністю захистити ваші біткоїни від крадіжки якщо ваш комп'ютер буде інфіковано шкідливими програмами.</translation>
+ </message>
+ <message>
<source>IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
- <translation>ВАЖЛИВО: Всі попередні резервні копії, які ви зробили з вашого файлу гаманця повинні бути замінені новоствореним, зашифрованим файлом гаманця. З міркувань безпеки, попередні резервні копії незашифрованого файла гаманця стануть марними одразу ж, як тільки ви почнете використовувати новий, зашифрований гаманець.</translation>
+ <translation>ВАЖЛИВО: Всі попередні резервні копії, які ви зробили з вашого файлу гаманця повинні бути замінені новоствореним, зашифрованим файлом гаманця. З міркувань безпеки, попередні резервні копії незашифрованого файла гаманця стануть непридатними одразу ж, як тільки ви почнете використовувати новий, зашифрований гаманець.</translation>
</message>
<message>
<source>Warning: The Caps Lock key is on!</source>
@@ -181,7 +185,11 @@
</message>
<message>
<source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
- <translation>Введіть нову кодову фразу для гаманця.&lt;br/&gt;Будь ласка, використовуйте кодові фрази що містять &lt;b&gt; як мінімум десять випадкових символів &lt;/b&gt; або &lt;b&gt; як мінімум вісім слів &lt;/b&gt;.</translation>
+ <translation>Введіть нову кодову фразу для гаманця.&lt;br/&gt;Будь ласка, використовуйте кодові фрази що містять &lt;b&gt; щонайменше десять випадкових символів &lt;/b&gt; або &lt;b&gt; щонайменше вісім слів &lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <source>Enter the old passphrase and new passphrase to the wallet.</source>
+ <translation>Введіть старий пароль та новий пароль до гаманця.</translation>
</message>
<message>
<source>Wallet encryption failed</source>
@@ -232,11 +240,11 @@
</message>
<message>
<source>Show general overview of wallet</source>
- <translation>Показати загальний огляд гаманця</translation>
+ <translation>Показати стан гаманця</translation>
</message>
<message>
<source>&amp;Transactions</source>
- <translation>Транзакції</translation>
+ <translation>&amp;Транзакції</translation>
</message>
<message>
<source>Browse transaction history</source>
@@ -312,7 +320,7 @@
</message>
<message>
<source>&amp;Debug window</source>
- <translation>Вікно зневадження</translation>
+ <translation>В&amp;ікно зневадження</translation>
</message>
<message>
<source>Open debugging and diagnostic console</source>
@@ -344,7 +352,7 @@
</message>
<message>
<source>&amp;Show / Hide</source>
- <translation>Показати / Приховати</translation>
+ <translation>Показа&amp;ти / Приховати</translation>
</message>
<message>
<source>Show or hide the main Window</source>
@@ -352,7 +360,7 @@
</message>
<message>
<source>Encrypt the private keys that belong to your wallet</source>
- <translation>Шифрування закритих ключів, які належать вашому гаманці</translation>
+ <translation>Зашифрувати закриті ключі, що знаходяться у вашому гаманці</translation>
</message>
<message>
<source>Sign messages with your Bitcoin addresses to prove you own them</source>
@@ -388,7 +396,11 @@
</message>
<message>
<source>&amp;About Bitcoin Core</source>
- <translation>&amp;Про Bitcoin Core</translation>
+ <translation>П&amp;ро Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>Редагувати параметри Bitcoin Core</translation>
</message>
<message>
<source>Show the list of used sending addresses and labels</source>
@@ -404,7 +416,7 @@
</message>
<message>
<source>&amp;Command-line options</source>
- <translation>Параметри командного рядка</translation>
+ <translation>П&amp;араметри командного рядка</translation>
</message>
<message>
<source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
@@ -412,13 +424,17 @@
</message>
<message numerus="yes">
<source>%n active connection(s) to Bitcoin network</source>
- <translation><numerusform>%n активне з'єднання з мережею</numerusform><numerusform>%n активні з'єднання з мережею</numerusform><numerusform>%n активних з'єднань з мережею Bitcoin</numerusform></translation>
+ <translation><numerusform>%n активне з'єднання з мережею Bitcoin</numerusform><numerusform>%n активні з'єднання з мережею Bitcoin</numerusform><numerusform>%n активних з'єднань з мережею Bitcoin</numerusform></translation>
</message>
<message>
<source>No block source available...</source>
<translation>Недоступно жодного джерела блоків...</translation>
</message>
<message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>Оброблено %n блок історії транзакцій.</numerusform><numerusform>Оброблено %n блоки історії транзакцій.</numerusform><numerusform>Оброблено %n блоків історії транзакцій.</numerusform></translation>
+ </message>
+ <message numerus="yes">
<source>%n hour(s)</source>
<translation><numerusform>%n година</numerusform><numerusform>%n години</numerusform><numerusform>%n годин</numerusform></translation>
</message>
@@ -471,6 +487,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>
@@ -510,7 +556,7 @@
</message>
<message>
<source>Amount:</source>
- <translation>Кількість:</translation>
+ <translation>Сума:</translation>
</message>
<message>
<source>Priority:</source>
@@ -582,11 +628,11 @@
</message>
<message>
<source>Copy amount</source>
- <translation>Копіювати кількість</translation>
+ <translation>Скопіювати суму</translation>
</message>
<message>
<source>Copy transaction ID</source>
- <translation>Копіювати ID транзакції </translation>
+ <translation>Скопіювати ID транзакції </translation>
</message>
<message>
<source>Lock unspent</source>
@@ -598,31 +644,31 @@
</message>
<message>
<source>Copy quantity</source>
- <translation>Копіювати кількість</translation>
+ <translation>Скопіювати кількість</translation>
</message>
<message>
<source>Copy fee</source>
- <translation>Копіювати комісію</translation>
+ <translation>Скопіювати комісію</translation>
</message>
<message>
<source>Copy after fee</source>
- <translation>Копіювати після комісії</translation>
+ <translation>Скопіювати після комісії</translation>
</message>
<message>
<source>Copy bytes</source>
- <translation>Копіювати байти</translation>
+ <translation>Скопіювати байти</translation>
</message>
<message>
<source>Copy priority</source>
- <translation>Копіювати пріорітет</translation>
+ <translation>Скопіювати пріорітет</translation>
</message>
<message>
<source>Copy dust</source>
- <translation>Копіювати пил</translation>
+ <translation>Скопіювати пил</translation>
</message>
<message>
<source>Copy change</source>
- <translation>Копіювати решту</translation>
+ <translation>Скопіювати решту</translation>
</message>
<message>
<source>highest</source>
@@ -669,6 +715,18 @@
<translation>відсутній</translation>
</message>
<message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>Ця позначка стане червоною, якщо розмір транзакції перевищить 1000 байтів.</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>Ця позначка стане червоною, якщо пріоритет транзакції менше, ніж «середній».</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>Ця позначка стане червоною, якщо будь-який отримувач отримає суму, меншу за %1.</translation>
+ </message>
+ <message>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation>Може відрізнятися на +/- %1 сатоші за вхід</translation>
</message>
@@ -764,7 +822,7 @@
<name>FreespaceChecker</name>
<message>
<source>A new data directory will be created.</source>
- <translation>Буде створена новий каталог даних.</translation>
+ <translation>Буде створено новий каталог даних.</translation>
</message>
<message>
<source>name</source>
@@ -904,7 +962,7 @@
</message>
<message>
<source>Number of script &amp;verification threads</source>
- <translation>Кількість потоків сценарію перевірки</translation>
+ <translation>Кількість потоків &amp;сценарію перевірки</translation>
</message>
<message>
<source>Accept connections from outside</source>
@@ -919,6 +977,14 @@
<translation>IP-адреса проксі-сервера (наприклад IPv4: 127.0.0.1 / IPv6: ::1)</translation>
</message>
<message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>Згортати замість закриття. Якщо ця опція включена, програма закриється лише після вибору відповідного пункту в меню.</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>Встановлює мову інтерфейсу. Зміни набудуть чинності після перезапуску Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
<translation>Сторонні URL (наприклад, block explorer), що з'являться на вкладці транзакцій у вигляді пункту контекстного меню. %s в URL буде замінено на хеш транзакції. Для відокремлення URLів використовуйте вертикальну риску |.</translation>
</message>
@@ -936,13 +1002,21 @@
</message>
<message>
<source>&amp;Reset Options</source>
- <translation>Скинути параметри</translation>
+ <translation>С&amp;кинути параметри</translation>
</message>
<message>
<source>&amp;Network</source>
<translation>&amp;Мережа</translation>
</message>
<message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>Автоматично запускати Bitcoin Core при вході до системи.</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>&amp;Запускати Bitcoin Core при вході до системи</translation>
+ </message>
+ <message>
<source>(0 = auto, &lt;0 = leave that many cores free)</source>
<translation>(0 = автоматично, &lt;0 = вказує кількість вільних ядер)</translation>
</message>
@@ -1055,6 +1129,10 @@
<translation>Для застосування змін необхідно перезапустити клієнта.</translation>
</message>
<message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>Клієнт буде вимкнено. Продовжити?</translation>
+ </message>
+ <message>
<source>This change would require a client restart.</source>
<translation>Ця зміна вступить в силу після перезапуску клієнта</translation>
</message>
@@ -1189,14 +1267,26 @@
<translation>Неможливо прочитати файл запиту платежу! Ймовірно, файл пошкоджено.</translation>
</message>
<message>
+ <source>Payment request expired.</source>
+ <translation>Запит платежу прострочено.</translation>
+ </message>
+ <message>
<source>Unverified payment requests to custom payment scripts are unsupported.</source>
<translation>Неперевірені запити платежів з власними платіжними сценаріями не підтримуються.</translation>
</message>
<message>
+ <source>Invalid payment request.</source>
+ <translation>Помилка в запиті платежу.</translation>
+ </message>
+ <message>
<source>Refund from %1</source>
<translation>Відшкодування з %1</translation>
</message>
<message>
+ <source>Payment request %1 is too large (%2 bytes, allowed %3 bytes).</source>
+ <translation>Запит платежу %1 занадто великий (%2 байт, дозволено %3 байт).</translation>
+ </message>
+ <message>
<source>Payment request DoS protection</source>
<translation>Оплата потребує захисту DoS</translation>
</message>
@@ -1228,6 +1318,10 @@
<translation>Клієнт користувача</translation>
</message>
<message>
+ <source>Node/Service</source>
+ <translation>Вузол/Сервіс</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Затримка</translation>
</message>
@@ -1349,6 +1443,10 @@
<translation>Поточне число блоків</translation>
</message>
<message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>Відкрити файл журналу налагодження Bitcoin Core з поточного каталогу даних. Це може зайняти кілька секунд для великих файлів журналів.</translation>
+ </message>
+ <message>
<source>Received</source>
<translation>Отримано</translation>
</message>
@@ -1417,16 +1515,20 @@
<translation>Затримка</translation>
</message>
<message>
+ <source>Time Offset</source>
+ <translation>Різниця часу</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>Час останнього блоку</translation>
</message>
<message>
<source>&amp;Open</source>
- <translation>Відкрити</translation>
+ <translation>&amp;Відкрити</translation>
</message>
<message>
<source>&amp;Console</source>
- <translation>Консоль</translation>
+ <translation>&amp;Консоль</translation>
</message>
<message>
<source>&amp;Network Traffic</source>
@@ -1461,6 +1563,10 @@
<translation>Очистити консоль</translation>
</message>
<message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>Вітаємо у RPC-консолі Bitcoin Core.</translation>
+ </message>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
<translation>Використовуйте стрілки вгору вниз для навігації по історії, і &lt;b&gt;Ctrl-L&lt;/b&gt; для очищення екрана.</translation>
</message>
@@ -1600,11 +1706,11 @@
</message>
<message>
<source>Copy &amp;URI</source>
- <translation>Скопіювати URI</translation>
+ <translation>&amp;Скопіювати URI</translation>
</message>
<message>
<source>Copy &amp;Address</source>
- <translation>Скопіювати адресу</translation>
+ <translation>Скопіювати &amp;адресу</translation>
</message>
<message>
<source>&amp;Save Image...</source>
@@ -1754,7 +1860,11 @@
</message>
<message>
<source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source>
- <translation>Якщо оплата користувача встановлюється в 1000 Satoshi і розмір передачі всього 250 байт, то "за кілобайт" платить тільки 250 Satoshi, в той час як "всього щонайменше" платить 1000 satoshis. Для передач більших, ніж кілобайт обоє платять за кілобайт.</translation>
+ <translation>Якщо комісія встановлюється в 1000 сатоші і розмір транзакції лише 250 байтів, то опція "за кілобайт" встановлює комісію в 250 сатоші, в той час, як "всього щонайменше" - в 1000 сатоші. Для транзакцій більших за кілобайт в обох випадках буде знято комісію за кілобайт.</translation>
+ </message>
+ <message>
+ <source>Hide</source>
+ <translation>Приховати</translation>
</message>
<message>
<source>total at least</source>
@@ -1762,7 +1872,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>Оплата тільки мінімальних зборів є прийнятною до тих пір, як обсяг транзакцій там є меншим аніж простору в блоках. Але майте на увазі, що це може анулювати транзакцію, якщо попит на Bitcoin транзакції стане значно більшим, ніж мережа зможе обробити.</translation>
+ <translation>Оплата тільки мінімальної комісії є прийнятною, допоки обсяг транзакцій є меншим простору в блоках. Але майте на увазі, що це може анулювати транзакцію, якщо попит на Bitcoin транзакції стане більшим, ніж мережа зможе обробити.</translation>
</message>
<message>
<source>(read the tooltip)</source>
@@ -1778,7 +1888,7 @@
</message>
<message>
<source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
- <translation>(Розумна оплата ще не ініціалізована. Це звичайно займає кілька блоків...)</translation>
+ <translation>(Розумну оплату ще не ініціалізовано. Це, зазвичай, триває кілька блоків...)</translation>
</message>
<message>
<source>Confirmation time:</source>
@@ -1846,7 +1956,7 @@
</message>
<message>
<source>Copy amount</source>
- <translation>Копіювати кількість</translation>
+ <translation>Копіювати суму</translation>
</message>
<message>
<source>Copy fee</source>
@@ -1901,8 +2011,24 @@
<translation>Плата вища, ніж %1 вважається шалено високою.</translation>
</message>
<message>
+ <source>Payment request expired.</source>
+ <translation>Запит платежу прострочено.</translation>
+ </message>
+ <message numerus="yes">
+ <source>Estimated to begin confirmation within %n block(s).</source>
+ <translation><numerusform>Перше підтвердження очікується протягом %n блоку.</numerusform><numerusform>Перше підтвердження очікується протягом %n блоків.</numerusform><numerusform>Перше підтвердження очікується протягом %n блоків.</numerusform></translation>
+ </message>
+ <message>
<source>Pay only the minimum fee of %1</source>
- <translation>Платити тільки мінімальний збір у розмірі %1</translation>
+ <translation>Платити тільки мінімальну комісію у розмірі %1</translation>
+ </message>
+ <message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>Адреса отримувача неправильна. Будь ласка, перевірте її.</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>Знайдено адресу, що дублюється: кожна адреса має бути вказана не більше одного разу.</translation>
</message>
<message>
<source>Warning: Invalid Bitcoin address</source>
@@ -1976,10 +2102,26 @@
<translation>Видалити цей запис</translation>
</message>
<message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>Комісію буде знято зі вказаної суми. До отримувача надійде менше біткоінів, ніж було вказано в полі кількості. Якщо ж отримувачів декілька - комісію буде розподілено між ними.</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>В&amp;ідняти комісію від суми</translation>
+ </message>
+ <message>
<source>Message:</source>
<translation>Повідомлення:</translation>
</message>
<message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>Цей запит платежу не є автентифікованим.</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>Цей запит платежу є автентифікованим.</translation>
+ </message>
+ <message>
<source>Enter a label for this address to add it to the list of used addresses</source>
<translation>Введіть мітку для цієї адреси для додавання її в список використаних адрес</translation>
</message>
@@ -2018,6 +2160,10 @@
<translation>&amp;Підписати повідомлення</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>Ви можете підписувати повідомлення/угоди своїми адресами, щоб довести можливість отримання біткоінів, що будуть надіслані на них. Остерігайтеся підписувати будь-що нечітке чи неочікуване, так як за допомогою фішинг-атаки вас можуть спробувати ввести в оману для отримання вашого підпису під чужими словами. Підписуйте лише чіткі твердження, з якими ви повністю згодні.</translation>
+ </message>
+ <message>
<source>The Bitcoin address to sign the message with</source>
<translation>Адреса Bitcoin для підпису цього повідомлення</translation>
</message>
@@ -2067,7 +2213,11 @@
</message>
<message>
<source>&amp;Verify Message</source>
- <translation>Перевірити повідомлення</translation>
+ <translation>П&amp;еревірити повідомлення</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>Введіть нижче адресу отримувача, повідомлення (впевніться, що ви точно скопіювали символи завершення рядка, табуляцію, пробіли тощо) та підпис для перевірки повідомлення. Впевніться, що в підпис не було додано зайвих символів: це допоможе уникнути атак типу «людина посередині». Зауважте, що це лише засвідчує можливість отримання транзакцій підписувачем, але не в стані підтвердити джерело жодної транзакції!</translation>
</message>
<message>
<source>The Bitcoin address the message was signed with</source>
@@ -2079,7 +2229,7 @@
</message>
<message>
<source>Verify &amp;Message</source>
- <translation>Перевірити повідомлення</translation>
+ <translation>Пере&amp;вірити повідомлення</translation>
</message>
<message>
<source>Reset all verify message fields</source>
@@ -2284,7 +2434,7 @@
</message>
<message>
<source>Inputs</source>
- <translation>витрати</translation>
+ <translation>Входи</translation>
</message>
<message>
<source>Amount</source>
@@ -2421,6 +2571,10 @@
<translation>Показує, чи було залучено адресу для спостереження в цій транзакції.</translation>
</message>
<message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>Призначення транзакції (визначається користувачем).</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
<translation>Сума, додана чи знята з балансу.</translation>
</message>
@@ -2493,11 +2647,11 @@
</message>
<message>
<source>Copy amount</source>
- <translation>Копіювати кількість</translation>
+ <translation>Скопіювати суму</translation>
</message>
<message>
<source>Copy transaction ID</source>
- <translation>Копіювати ID транзакції </translation>
+ <translation>Скопіювати ID транзакції </translation>
</message>
<message>
<source>Edit label</source>
@@ -2671,16 +2825,16 @@
<translation>Поширюється за ліцензією MIT, додаткова інформація міститься у файлі COPYING та за адресою &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>Ввійти в режим регресивного тестування, що використовує спеціальний ланцюг з миттєвим знаходженням блоків.</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>Виконати команду, коли транзакція гаманця зміниться (замість %s в команді буде підставлено ідентифікатор транзакції)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>В цьому режимі -genproclimit встановлює кількість блоків, що можуть бути згенеровані негайно.</translation>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>Максимальна загальна комісія за одну транзакцію; занадто низьке значення може скасувати відправку великих транзакцій (типово: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>Зменшити вимоги до наявного простору на носії даних за допомогою скорочення ланцюжка (видалення старих блоків). Цей режим вимикає підтримку гаманця та є несумісним з параметром -txindex. Увага: при поверненні до типового значення видалені частини ланцюжка буде повторно завантажено. (типово: 0 = вимкнути скорочення ланцюжка, &gt;%u = очікуваний розмір файлів блоків в МіБ)</translation>
</message>
<message>
<source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
@@ -2695,6 +2849,14 @@
<translation>Неможливо прив'язатися до %s на цьому комп'ютері. Можливо, Bitcoin Core вже запущено.</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>УВАГА: аномально висока кількість згенерованих блоків, %d блок(ів) було отримано за останні %d годин(и) (має бути %d)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>УВАГА: перевірте ваше мережеве з'єднання, %d блок(ів) було отримано за останні %d годин(и) (має бути %d)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>Увага: встановлено занадто велику комісію (-paytxfee). Комісія зніматиметься кожен раз коли ви проводитимете транзакції.</translation>
</message>
@@ -2736,7 +2898,7 @@
</message>
<message>
<source>Connect only to the specified node(s)</source>
- <translation>Підключитись лише до вказаного вузла</translation>
+ <translation>Підключитись лише до вказаного вузла/вузлів</translation>
</message>
<message>
<source>Connection options:</source>
@@ -2808,7 +2970,15 @@
</message>
<message>
<source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
- <translation>Підключити тільки до вузлів в мережі &lt;net&gt; (ipv4, ipv6 або onion)</translation>
+ <translation>Підключатися тільки до вузлів в мережі &lt;net&gt; (ipv4, ipv6 або onion)</translation>
+ </message>
+ <message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>Розмір скороченого ланцюжка блоків не може бути від'ємним. </translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>Використання скороченого ланцюжка блоків несумісне з параметром -txindex.</translation>
</message>
<message>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
@@ -2823,10 +2993,6 @@
<translation>Вкажіть файл гаманця (в межах каталогу даних)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>Це призначено для інструментів регресивного тестування та розробки додатків.</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>Намагатись використовувати UPnP для відображення порту, що прослуховується, на роутері (типово: %u)</translation>
</message>
@@ -2847,6 +3013,10 @@
<translation>Параметри гаманця:</translation>
</message>
<message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>Увага: Поточна версія застаріла, необхідне оновлення!</translation>
+ </message>
+ <message>
<source>You need to rebuild the database using -reindex to change -txindex</source>
<translation>Вам необхідно перебудувати базу даних з використанням -reindex для того, щоб змінити -txindex</translation>
</message>
@@ -2879,6 +3049,10 @@
<translation>Створювати нові файли з типовими для системи атрибутами доступу замість маски 077 (діє тільки при вимкненому гаманці)</translation>
</message>
<message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>Визначити власні IP-адреси (типово: 1 при прослуховуванні та за відсутності -externalip або -proxy)</translation>
+ </message>
+ <message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Помилка: Не вдалося налаштувати прослуховування вхідних підключень (listen повернув помилку: %s)</translation>
</message>
@@ -2895,22 +3069,30 @@
<translation>Комісії (в BTC/КБ), що менші за вказану, вважатимуться нульовими (для ретрансляції) (типово: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>Комісії (в BTC/КБ), що менші за вказану, вважатимуться нульовими (для створення транзакції) (типово: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>Якщо параметр paytxfee не встановлено, включити комісію для отримання перших підтверджень транзакцій протягом n блоків (типово: %u)</translation>
</message>
<message>
+ <source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
+ <translation>Неприпустима сума для -maxtxfee = &lt;amount&gt;: «%s» ( плата повинна бути, принаймні %s, щоб запобігти зависанню транзакцій)</translation>
+ </message>
+ <message>
<source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
<translation>Максимальний розмір даних в транзакціях носіїв даних, що ми передаємо і добуваємо (за замовчуванням: %u)</translation>
</message>
<message>
+ <source>Prune configured below the minimum of %d MB. Please use a higher number.</source>
+ <translation>Встановлений розмір ланцюжка блоків є замалим (менший за %d МБ). Будь ласка, виберіть більше число.</translation>
+ </message>
+ <message>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation>Дізнаватися адреси учасників через DNS при замалій кількості відомих адрес (типово: 1 за відсутності -connect)</translation>
</message>
<message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>Надавати випадкові дані доступу для кожного проксі-з'єднання. Це дозволяє ввімкнути ізоляцію потоків Tor'у (типово: %u)</translation>
+ </message>
+ <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Встановити максимальний розмір транзакцій з високим пріоритетом та низькою комісією (в байтах) (типово: %d)</translation>
</message>
@@ -2919,6 +3101,10 @@
<translation>Встановити кількість потоків для генерації монет (-1 = кількості ядер, типово: %d)</translation>
</message>
<message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>Залишок від суми транзакції зі сплатою комісії занадто малий </translation>
+ </message>
+ <message>
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
<translation>Цей продукт включає в себе програмне забезпечення, розроблене в рамках проекту OpenSSL &lt;https://www.openssl.org/&gt;, криптографічне програмне забезпечення, написане Еріком Янгом, та функції для роботи з UPnP, написані Томасом Бернардом.</translation>
</message>
@@ -2959,10 +3145,26 @@ rpcpassword=%s
<translation>Учасники, що знаходяться в білому списку, не можуть бути заблоковані за DoS та їхні транзакції завжди ретранслюватимуться (навіть якщо вони є в пам'яті), що може бути корисним, наприклад, для шлюзу</translation>
</message>
<message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>Вам необхідно перебудувати базу даних з використанням -reindex для завантаження повного ланцюжка блоків.</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(типово: %u)</translation>
+ </message>
+ <message>
<source>Accept public REST requests (default: %u)</source>
<translation>Приймати публічні REST-запити (типово: %u)</translation>
</message>
<message>
+ <source>Activating best chain...</source>
+ <translation>Активація найкращого ланцюжка...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>Використання гаманця зі скороченим ланцюжком блоків неможливе.</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>Не вдалося розпізнати адресу для -whitebind: «%s»</translation>
</message>
@@ -2987,6 +3189,10 @@ rpcpassword=%s
<translation>Помилка при завантаженні wallet.dat: Гаманець потребує новішої версії Bitcoin Core</translation>
</message>
<message>
+ <source>Error reading from database, shutting down.</source>
+ <translation>Помилка читання бази даних, припиняю роботу.</translation>
+ </message>
+ <message>
<source>Error: Unsupported argument -tor found, use -onion.</source>
<translation>Помилка: Параметр -tor не підтримується, використовуйте -onion</translation>
</message>
@@ -3004,7 +3210,7 @@ rpcpassword=%s
</message>
<message>
<source>Invalid amount for -maxtxfee=&lt;amount&gt;: '%s'</source>
- <translation>Неприпустима сума для -maxtxfee = &lt;amount&gt;: '%s'</translation>
+ <translation>Неприпустима сума для -maxtxfee = &lt;amount&gt;: «%s»</translation>
</message>
<message>
<source>Invalid amount for -minrelaytxfee=&lt;amount&gt;: '%s'</source>
@@ -3043,12 +3249,16 @@ rpcpassword=%s
<translation>Параметри сервера RPC:</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>Випадковим чином відкидати 1 з &lt;n&gt; мережевих повідомлень</translation>
+ <source>RPC support for HTTP persistent connections (default: %d)</source>
+ <translation>Підтримка RPC для постійних HTTP-з'єднань (типово: %d)</translation>
+ </message>
+ <message>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>При запуску перебудувати індекс ланцюжка блоків з поточних файлів blk000??.dat</translation>
</message>
<message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>Випадковим чином пошкоджувати 1 з &lt;n&gt; мережевих повідомлень</translation>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>Отримувати та відображати попередження з мережі (типово: %u)</translation>
</message>
<message>
<source>Send trace/debug info to console instead of debug.log file</source>
@@ -3087,6 +3297,10 @@ rpcpassword=%s
<translation>Запускати згорнутим</translation>
</message>
<message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>Неможливо сплатити комісію із-за малої суми транзакції</translation>
+ </message>
+ <message>
<source>This is experimental software.</source>
<translation>Це програмне забезпечення є експериментальним.</translation>
</message>
@@ -3107,6 +3321,10 @@ rpcpassword=%s
<translation>Транзакція занадто велика</translation>
</message>
<message>
+ <source>UI Options:</source>
+ <translation>Параметри інтерфейсу:</translation>
+ </message>
+ <message>
<source>Unable to bind to %s on this computer (bind returned error %s)</source>
<translation>Неможливо прив'язатися до %s на цьому комп'ютері (bind повернув помилку: %s)</translation>
</message>
@@ -3187,18 +3405,10 @@ rpcpassword=%s
<translation>(1 = утримувати метадані транзакцій (до яких відноситься інформація про власника рахунку та запити платежів), 2 - відкинути)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Записувати зміни в базі даних до файлу кожні &lt;n&gt; мегабайтів (типово: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Рівень ретельності перевірки блоків (0-4, типово: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>Записувати в лог-файл пріоритет транзакції та комісію за кБ під час добування блоків (типово: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>Утримувати повний індекс транзакцій (використовується RPC-викликом getrawtransaction) (типово: %u)</translation>
</message>
@@ -3227,18 +3437,10 @@ rpcpassword=%s
<translation>Завжди дізнаватися адреси учасників через DNS (типово: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>Вимкнути безпечний режим та ігнорувати події, що здатні ввімкнути його (типово: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>Помилка при завантаженні wallet.dat</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>Ввімкнути безпечний режим (типово: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>Генерація монет (типово: %u)</translation>
</message>
@@ -3255,10 +3457,6 @@ rpcpassword=%s
<translation>Помилка в адресі проксі-сервера: «%s»</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>Обмежити розмір кешу підписів до &lt;n&gt; записів (типово: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>Прослуховувати &lt;port&gt; для JSON-RPC з'єднань (типово: %u, для тестової мережі: %u)</translation>
</message>
@@ -3271,6 +3469,10 @@ rpcpassword=%s
<translation>Підтримувати щонайбільше &lt;n&gt; з'єднань з учасниками (типово: %u)</translation>
</message>
<message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>Дозволити гаманцю розповсюджувати транзакції</translation>
+ </message>
+ <message>
<source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
<translation>Максимальний розмір вхідного буферу на одне з'єднання, &lt;n&gt;*1000 байтів (типово: %u)</translation>
</message>
@@ -3279,10 +3481,6 @@ rpcpassword=%s
<translation>Максимальний розмір вихідного буферу на одне з'єднання, &lt;n&gt;*1000 байтів (типово: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>Приймати тільки той ланцюжок блоків, що не суперечить вбудованим контрольним точкам (типово: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>Доповнювати налагоджувальний вивід відміткою часу (типово: %u)</translation>
</message>
@@ -3295,10 +3493,6 @@ rpcpassword=%s
<translation>Ретранслювати не-P2SH транзакції з мультипідписом (типово: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>Запустити потік для періодичного збереження даних гаманця (типово: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>Файл сертифіката сервера (типово: %s)</translation>
</message>
@@ -3319,10 +3513,6 @@ rpcpassword=%s
<translation>Встановити число потоків для обслуговування викликів RPC (типово: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Встановити прапорець DB_PRIVATE в середовищі бази даних гаманця (типово: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>Вказати файл конфігурації (типово: %s)</translation>
</message>
@@ -3339,10 +3529,6 @@ rpcpassword=%s
<translation>Витрачати непідтверджену решту при відправленні транзакцій (типово: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>Вимкнутися після імпорту блоків з диску (типово: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Поріг відключення учасників з поганою поведінкою (типово: %u)</translation>
</message>
diff --git a/src/qt/locale/bitcoin_ur_PK.ts b/src/qt/locale/bitcoin_ur_PK.ts
index 9148626f57..d4242d5e3c 100644
--- a/src/qt/locale/bitcoin_ur_PK.ts
+++ b/src/qt/locale/bitcoin_ur_PK.ts
@@ -1,7 +1,11 @@
-<TS language="ur_PK" version="2.1">
+<TS language="ur_PK" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
+ <source>Right-click to edit address or label</source>
+ <translation>پتہ تبدیل کرے کے لیے دائیاں کلک کریں</translation>
+ </message>
+ <message>
<source>Create a new address</source>
<translation>نیا ایڈریس بنائیں</translation>
</message>
@@ -10,6 +14,10 @@
<translation>نیا</translation>
</message>
<message>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>سلیکٹڈ پتے کو کمپوٹر کی عارضی جگہ رکھیں</translation>
+ </message>
+ <message>
<source>&amp;Copy</source>
<translation>نقل</translation>
</message>
@@ -22,6 +30,14 @@
<translation>کاپی پتہ</translation>
</message>
<message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>سلیکٹڈ پتے کو مٹائیں</translation>
+ </message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>موجودہ ڈیٹا کو فائیل میں محفوظ کریں</translation>
+ </message>
+ <message>
<source>&amp;Export</source>
<translation>برآمد</translation>
</message>
@@ -30,9 +46,21 @@
<translation>مٹا</translation>
</message>
<message>
+ <source>Choose the address to send coins to</source>
+ <translation>کوئین وصول کرنے والے کا پتہ</translation>
+ </message>
+ <message>
+ <source>Choose the address to receive coins with</source>
+ <translation>کوئین بھیجنے والے کا پتہ</translation>
+ </message>
+ <message>
<source>C&amp;hoose</source>
<translation>چننا</translation>
</message>
+ <message>
+ <source>Sending addresses</source>
+ <translation>جس پتے پر بھیجنے ہیں</translation>
+ </message>
</context>
<context>
<name>AddressTableModel</name>
@@ -315,6 +343,10 @@
<source>&amp;Export</source>
<translation>برآمد</translation>
</message>
+ <message>
+ <source>Export the data in the current tab to a file</source>
+ <translation>موجودہ ڈیٹا کو فائیل میں محفوظ کریں</translation>
+ </message>
</context>
<context>
<name>bitcoin-core</name>
diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts
index b8807afb13..cc0a4bba08 100644
--- a/src/qt/locale/bitcoin_uz@Cyrl.ts
+++ b/src/qt/locale/bitcoin_uz@Cyrl.ts
@@ -1,7 +1,11 @@
-<TS language="uz@Cyrl" version="2.1">
+<TS language="uz@Cyrl" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
+ <source>Right-click to edit address or label</source>
+ <translation>Манзил ёки ёрлиқни таҳрирлаш учун икки марта босинг</translation>
+ </message>
+ <message>
<source>Create a new address</source>
<translation>Янги манзил яратинг</translation>
</message>
diff --git a/src/qt/locale/bitcoin_vi.ts b/src/qt/locale/bitcoin_vi.ts
index 38ebd77b71..64d11d4645 100644
--- a/src/qt/locale/bitcoin_vi.ts
+++ b/src/qt/locale/bitcoin_vi.ts
@@ -1,4 +1,4 @@
-<TS language="vi" version="2.1">
+<TS language="vi" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -6,10 +6,22 @@
<translation>Tạo một địa chỉ mới</translation>
</message>
<message>
+ <source>&amp;New</source>
+ <translation>Tạo mới</translation>
+ </message>
+ <message>
<source>Copy the currently selected address to the system clipboard</source>
<translation>Sao chép các địa chỉ đã được chọn vào bộ nhớ tạm thời của hệ thống</translation>
</message>
<message>
+ <source>&amp;Copy</source>
+ <translation>Sao chép</translation>
+ </message>
+ <message>
+ <source>&amp;Copy Address</source>
+ <translation>Sao chép địa chỉ</translation>
+ </message>
+ <message>
<source>&amp;Delete</source>
<translation>&amp;Xóa</translation>
</message>
diff --git a/src/qt/locale/bitcoin_vi_VN.ts b/src/qt/locale/bitcoin_vi_VN.ts
index 18d1a252e7..7bcded7448 100644
--- a/src/qt/locale/bitcoin_vi_VN.ts
+++ b/src/qt/locale/bitcoin_vi_VN.ts
@@ -1,4 +1,4 @@
-<TS language="vi_VN" version="2.1">
+<TS language="vi_VN" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts
index 3bcce1faab..4470b2601b 100644
--- a/src/qt/locale/bitcoin_zh_CN.ts
+++ b/src/qt/locale/bitcoin_zh_CN.ts
@@ -1,4 +1,4 @@
-<TS language="zh_CN" version="2.1">
+<TS language="zh_CN" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -67,7 +67,7 @@
</message>
<message>
<source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
- <translation>这是您用来付款的比特币地址。在付款前,请总是核实付款金额和收款地址。</translation>
+ <translation>这是您用来付款的比特币地址。在付款前,请仔细核实付款金额和收款地址。</translation>
</message>
<message>
<source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
@@ -2102,6 +2102,10 @@
<translation>移除此项</translation>
</message>
<message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>交易费将从发送总额中扣除。接收人将收到比您在金额框中输入的更少的比特币。如果选中了多个收件人,交易费平分。</translation>
+ </message>
+ <message>
<source>S&amp;ubtract fee from amount</source>
<translation>从金额中减去交易费(&amp;U)</translation>
</message>
@@ -2156,6 +2160,10 @@
<translation>签名消息(&amp;S)</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>您可以用你的地址对消息/协议进行签名,以证明您可以接收发送到该地址的比特币。注意不要对任何模棱两可或者随机的消息进行签名,以免遭受钓鱼式攻击。请确保消息内容准确的表达了您的真实意愿。</translation>
+ </message>
+ <message>
<source>The Bitcoin address to sign the message with</source>
<translation>用来对消息签名的地址 </translation>
</message>
@@ -2815,10 +2823,6 @@
<translation>绑定指定的IP地址开始监听。IPv6地址请使用[host]:port 格式</translation>
</message>
<message>
- <source>Continuously rate-limit free transactions to &lt;n&gt;*1000 bytes per minute (default: %u)</source>
- <translation>自由交易不断的速率限制为&lt;n&gt;*1000 字节每分钟(默认值: %u)</translation>
- </message>
- <message>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>删除钱包的所有交易记录,且只有用 -rescan参数启动客户端才能重新取回交易记录 </translation>
</message>
@@ -2827,18 +2831,10 @@
<translation>Distributed under the MIT software license, see the accompanying file COPYING or &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>进入回归测试模式,它采用一种特殊的可立即解决的区块链模拟情况。</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>当最佳区块变化时执行命令 (命令行中的 %s 会被替换成区块哈希值)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>在-genproclimit这种模式下控制产出多少区块</translation>
- </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>
@@ -2859,6 +2855,14 @@
<translation>无法 %s的绑定到电脑上,比特币核心钱包可能已经在运行。</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>警告:数据块生成数量异常,最近 %d 小时收到了 %d 个数据块(预期为 %d 个)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>警告:请检查您的网络连接,最近 %d 小时收到了 %d 个数据块(预期为 %d 个)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>警告:-paytxfee 交易费设置得太高了!每笔交易都将支付交易费。</translation>
</message>
@@ -2995,10 +2999,6 @@
<translation>指定钱包文件(数据目录内)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>这是用于回归测试和应用开发目的。</translation>
- </message>
- <message>
<source>Use UPnP to map the listening port (default: %u)</source>
<translation>使用UPnp映射监听端口 (默认: %u) </translation>
</message>
@@ -3075,10 +3075,6 @@
<translation>交易费(BTC/kb)比这更小的交易在转发时将被视为零费交易 (默认: %s) </translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>交易费(BTC/kb)比这更小的交易在生成交易时将被视为零费交易 (默认: %s) </translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>如果未设置交易费用,自动添加足够的交易费以确保交易在平均n个数据块内被确认 (默认: %u) </translation>
</message>
@@ -3103,10 +3099,6 @@
<translation>为每个代理连接随机化凭据。这将启用 Tor 流隔离 (默认: %u)</translation>
</message>
<message>
- <source>Require high priority for relaying free or low-fee transactions (default: %u)</source>
- <translation>免费中继和低费率交易需要高优先级 (默认: %u)</translation>
- </message>
- <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>设置 高优先级/低交易费 交易的最大字节 (缺省: %d)</translation>
</message>
@@ -3175,10 +3167,6 @@ rpcpassword=%s
<translation>正在激活最佳数据链...</translation>
</message>
<message>
- <source>Allow self signed root certificates (default: 0)</source>
- <translation>允许自签名根证书 (默认: 0)</translation>
- </message>
- <message>
<source>Can't run with a wallet in prune mode.</source>
<translation>不能在修剪模式下运行一个钱包。</translation>
</message>
@@ -3267,18 +3255,14 @@ rpcpassword=%s
<translation>RPC 支持 HTTP 持久连接 (默认: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>随机每1个丢失测试&lt;n&gt;网络信息</translation>
- </message>
- <message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>随机每1个模拟测试&lt;n&gt;网络信息</translation>
- </message>
- <message>
<source>Rebuild block chain index from current blk000??.dat files on startup</source>
<translation>启动时重新为当前的 blk000??.dat 文件建立索引</translation>
</message>
<message>
+ <source>Receive and display P2P network alerts (default: %u)</source>
+ <translation>收到并且显示P2P网络的告警(默认:%u)</translation>
+ </message>
+ <message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>跟踪/调试信息输出到控制台,不输出到 debug.log 文件</translation>
</message>
@@ -3426,18 +3410,10 @@ rpcpassword=%s
<translation>(1 = 保留 tx meta data , 如 account owner 和 payment request information, 2 = 不保留 tx meta data) </translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>数据块验证 严密级别 -checkblocks (0-4, 默认: %u) </translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>挖矿时,记录交易优先级 和 每kb交易费 (默认: %u) </translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>维护一份完整的交易索引, 用于 getrawtransaction RPC调用 (默认: %u)</translation>
</message>
@@ -3462,18 +3438,10 @@ rpcpassword=%s
<translation>可接受的密码算法 (默认: %s) </translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>禁止使用安全模式,重新写入一个真正的安全模式日志(默认: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>wallet.dat 钱包文件加载出错</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>强制安全模式 (默认: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>生成比特币 (默认: %u)</translation>
</message>
@@ -3490,10 +3458,6 @@ rpcpassword=%s
<translation>无效的代理地址:%s</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>签名缓冲区大小限制最多 &lt;n&gt; 条 (默认: %u) </translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>使用 &lt;port&gt;端口监听 JSON-RPC 连接 (默认: %u ; testnet: %u) </translation>
</message>
@@ -3518,10 +3482,6 @@ rpcpassword=%s
<translation>每个连接的最大发送缓存,&lt;n&gt;*1000 字节 (默认: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>仅接受符合客户端检查点设置 的数据块链 (默认: %u) </translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>输出调试信息时,前面加上时间戳 (默认: %u)</translation>
</message>
@@ -3534,10 +3494,6 @@ rpcpassword=%s
<translation>是否转发 非P2SH格式的多签名交易 (默认: %u) </translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>运行一个线程,定时清理钱包 (默认: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>服务器证书文件 (默认: %s) </translation>
</message>
@@ -3558,10 +3514,6 @@ rpcpassword=%s
<translation>设置RPC服务线程数 (默认: %d) </translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>指定配置文件 (默认: %s) </translation>
</message>
@@ -3578,10 +3530,6 @@ rpcpassword=%s
<translation>付款时允许使用未确认的零钱 (默认: %u) </translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>从磁盘导入数据块后退出 (默认: %u) </translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>断开 非礼节点的阀值 (默认: %u) </translation>
</message>
diff --git a/src/qt/locale/bitcoin_zh_HK.ts b/src/qt/locale/bitcoin_zh_HK.ts
index dfdbb7d1da..7062377f45 100644
--- a/src/qt/locale/bitcoin_zh_HK.ts
+++ b/src/qt/locale/bitcoin_zh_HK.ts
@@ -1,4 +1,4 @@
-<TS language="zh_HK" version="2.1">
+<TS language="zh_HK" version="2.0">
<context>
<name>AddressBookPage</name>
</context>
diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts
index 3792a76095..9a93d896fe 100644
--- a/src/qt/locale/bitcoin_zh_TW.ts
+++ b/src/qt/locale/bitcoin_zh_TW.ts
@@ -1,4 +1,4 @@
-<TS language="zh_TW" version="2.1">
+<TS language="zh_TW" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
@@ -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>
@@ -184,6 +188,10 @@
<translation>輸入錢包的新密碼。&lt;br/&gt;密碼請用&lt;b&gt;10 個以上的字元&lt;/b&gt;,或是&lt;b&gt;8 個以上的字詞&lt;/b&gt;。</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>
@@ -391,6 +399,10 @@
<translation>關於位元幣核心</translation>
</message>
<message>
+ <source>Modify configuration options for Bitcoin Core</source>
+ <translation>修改位元幣核心的設定選項</translation>
+ </message>
+ <message>
<source>Show the list of used sending addresses and labels</source>
<translation>顯示已使用過的付款位址和標記的清單</translation>
</message>
@@ -419,6 +431,10 @@
<translation>沒有可用的區塊來源...</translation>
</message>
<message numerus="yes">
+ <source>Processed %n block(s) of transaction history.</source>
+ <translation><numerusform>已經處理了 %n 個區塊的交易紀錄。</numerusform></translation>
+ </message>
+ <message numerus="yes">
<source>%n hour(s)</source>
<translation><numerusform>%n 個小時</numerusform></translation>
</message>
@@ -471,6 +487,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>
@@ -669,6 +715,18 @@
<translation>無</translation>
</message>
<message>
+ <source>This label turns red if the transaction size is greater than 1000 bytes.</source>
+ <translation>當交易大小大於 1000 位元組時,文字會變紅色。</translation>
+ </message>
+ <message>
+ <source>This label turns red if the priority is smaller than "medium".</source>
+ <translation>當優先度低於「中等」時,文字會變紅色。</translation>
+ </message>
+ <message>
+ <source>This label turns red if any recipient receives an amount smaller than %1.</source>
+ <translation>當任何一個收款金額小於 %1 時,文字會變紅色。</translation>
+ </message>
+ <message>
<source>Can vary +/- %1 satoshi(s) per input.</source>
<translation>每組輸入可能有 +/- %1 個 satoshi 的誤差。</translation>
</message>
@@ -919,6 +977,14 @@
<translation>代理伺服器的網際網路位址(像是 IPv4 的 127.0.0.1 或 IPv6 的 ::1)</translation>
</message>
<message>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
+ <translation>當視窗關閉時,把應用程式縮到最小,而不是結束。當勾選這個選項時,只能夠用選單中的結束來關掉應用程式。</translation>
+ </message>
+ <message>
+ <source>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</source>
+ <translation>可以在這裡設定使用者介面的語言。這個設定在重啓位元幣核心後才會生效。</translation>
+ </message>
+ <message>
<source>Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
<translation>在交易頁籤的情境選單出現的第三方(比如說區塊探索網站)網址連結。網址中的 %s 會被取代為交易的雜湊值。可以用直線符號 | 來分隔多個連結。</translation>
</message>
@@ -943,6 +1009,14 @@
<translation>網路</translation>
</message>
<message>
+ <source>Automatically start Bitcoin Core after logging in to the system.</source>
+ <translation>在登入系統後自動啓動位元幣核心。</translation>
+ </message>
+ <message>
+ <source>&amp;Start Bitcoin Core on system login</source>
+ <translation>系統登入時啟動位元幣核心</translation>
+ </message>
+ <message>
<source>(0 = auto, &lt;0 = leave that many cores free)</source>
<translation>(0 表示程式自動決定,小於 0 表示保留處理器核心不用的數目)</translation>
</message>
@@ -1055,6 +1129,10 @@
<translation>需要重新啟動客戶端軟體來讓改變生效。</translation>
</message>
<message>
+ <source>Client will be shut down. Do you want to proceed?</source>
+ <translation>客戶端軟體就要關掉了。繼續做下去嗎?</translation>
+ </message>
+ <message>
<source>This change would require a client restart.</source>
<translation>這項改變需要重新啟動客戶端軟體。</translation>
</message>
@@ -1189,10 +1267,18 @@
<translation>沒辦法讀取付款要求檔案!可能是無效的檔案造成的。</translation>
</message>
<message>
+ <source>Payment request expired.</source>
+ <translation>付款的要求過期了。</translation>
+ </message>
+ <message>
<source>Unverified payment requests to custom payment scripts are unsupported.</source>
<translation>不支援含有自訂付款指令碼,且沒驗證過的付款要求。</translation>
</message>
<message>
+ <source>Invalid payment request.</source>
+ <translation>付款的要求無效。</translation>
+ </message>
+ <message>
<source>Refund from %1</source>
<translation>來自 %1 的退款</translation>
</message>
@@ -1232,6 +1318,10 @@
<translation>使用者代理</translation>
</message>
<message>
+ <source>Node/Service</source>
+ <translation>節點/服務</translation>
+ </message>
+ <message>
<source>Ping Time</source>
<translation>Ping 時間</translation>
</message>
@@ -1353,6 +1443,10 @@
<translation>目前區塊數</translation>
</message>
<message>
+ <source>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</source>
+ <translation>從目前的資料目錄下開啓位元幣核心的除錯紀錄檔。當紀錄檔很大時,可能會花好幾秒的時間。</translation>
+ </message>
+ <message>
<source>Received</source>
<translation>收款</translation>
</message>
@@ -1421,6 +1515,10 @@
<translation>Ping 時間</translation>
</message>
<message>
+ <source>Time Offset</source>
+ <translation>時間差</translation>
+ </message>
+ <message>
<source>Last block time</source>
<translation>最近區塊時間</translation>
</message>
@@ -1465,6 +1563,10 @@
<translation>清主控台</translation>
</message>
<message>
+ <source>Welcome to the Bitcoin Core RPC console.</source>
+ <translation>歡迎使用位元幣核心 RPC 主控台。</translation>
+ </message>
+ <message>
<source>Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.</source>
<translation>請用上下游標鍵來瀏覽先前指令的紀錄,並用 &lt;b&gt;Ctrl-L&lt;/b&gt; 來清畫面。</translation>
</message>
@@ -1761,6 +1863,10 @@
<translation>如果自訂手續費設定為 1000 satoshi, 而交易資料大小只有 250 個位元組的話,那麽選擇「每千位元組」就只會付 250 satoshi 的手續費,換做選「總共至少」就會付 1000 satoshi. 但是如果交易資料大小超過一千個位元組,那麽兩者都是每千位元組的費用。</translation>
</message>
<message>
+ <source>Hide</source>
+ <translation>隱藏</translation>
+ </message>
+ <message>
<source>total at least</source>
<translation>總共最少</translation>
</message>
@@ -1901,10 +2007,26 @@
<translation>交易被拒絕了!有時候會發生這種錯誤,是因為你錢包中的一些錢已經被花掉了。比如說你複製了錢包檔 wallet.dat, 然後用複製的錢包花掉了錢,你現在所用的原來的錢包中,卻沒有那筆錢已經花掉的紀錄。</translation>
</message>
<message>
+ <source>A fee higher than %1 is considered an absurdly high fee.</source>
+ <translation>高於 %1 的手續費會被認為是不合理。</translation>
+ </message>
+ <message>
+ <source>Payment request expired.</source>
+ <translation>付款的要求過期了。</translation>
+ </message>
+ <message>
<source>Pay only the minimum fee of %1</source>
<translation>只付最低手續費 %1</translation>
</message>
<message>
+ <source>The recipient address is not valid. Please recheck.</source>
+ <translation>收款位址無效。請再檢查看看。</translation>
+ </message>
+ <message>
+ <source>Duplicate address found: addresses should only be used once each.</source>
+ <translation>發現有重複的位址: 每個位址只能出現一次。</translation>
+ </message>
+ <message>
<source>Warning: Invalid Bitcoin address</source>
<translation>警告: 位元幣位址無效</translation>
</message>
@@ -1976,10 +2098,26 @@
<translation>刪掉這個項目</translation>
</message>
<message>
+ <source>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
+ <translation>手續費會從要付款出去的金額中扣掉。因此收款人會收到比輸入的金額還要少的位元幣。如果有多個收款人的話,手續費會平均分配來扣除。</translation>
+ </message>
+ <message>
+ <source>S&amp;ubtract fee from amount</source>
+ <translation>從付款金額減去手續費</translation>
+ </message>
+ <message>
<source>Message:</source>
<translation>訊息:</translation>
</message>
<message>
+ <source>This is an unauthenticated payment request.</source>
+ <translation>這是個沒驗證過的付款要求。</translation>
+ </message>
+ <message>
+ <source>This is an authenticated payment request.</source>
+ <translation>這是個已驗證的付款要求。</translation>
+ </message>
+ <message>
<source>Enter a label for this address to add it to the list of used addresses</source>
<translation>請輸入這個位址的標記,來把它加進去已使用過位址的清單。</translation>
</message>
@@ -2018,6 +2156,10 @@
<translation>簽署訊息</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>你可以用自己的位址簽署訊息或合約,來證明你可以從該位址收款。但是請小心,不要簽署語意含糊不清,或隨機產生的內容,因為釣魚式詐騙可能會用騙你簽署的手法來冒充是你。只有在語句中的細節你都同意時才簽署。</translation>
+ </message>
+ <message>
<source>The Bitcoin address to sign the message with</source>
<translation>用來簽署訊息的位元幣位址</translation>
</message>
@@ -2070,6 +2212,10 @@
<translation>驗證訊息</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>請在下面輸入收款人的位址,訊息(請確定完整複製了所包含的換行,空格,跳位符號等等),以及簽章,來驗證這個訊息。請小心,除了訊息內容以外,不要對簽章本身過度解讀,以避免被用「中間人攻擊法」詐騙。請注意,通過驗證的簽章只能證明簽章人確實可以從該位址收款,不能證明任何交易中的付款人身份!</translation>
+ </message>
+ <message>
<source>The Bitcoin address the message was signed with</source>
<translation>簽署這個訊息的位元幣位址</translation>
</message>
@@ -2421,6 +2567,10 @@
<translation>不論如何有一個只能觀看的地只有參與這次的交易</translation>
</message>
<message>
+ <source>User-defined intent/purpose of the transaction.</source>
+ <translation>使用者定義的交易動機或理由。</translation>
+ </message>
+ <message>
<source>Amount removed from or added to balance.</source>
<translation>要減掉或加進餘額的金額。</translation>
</message>
@@ -2672,16 +2822,16 @@
<translation>這套軟體是依據 MIT 軟體授權條款散布,詳情請見附帶的 COPYING 檔案,或是以下網站: &lt;http://www.opensource.org/licenses/mit-license.php&gt;.</translation>
</message>
<message>
- <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
- <translation>進入回歸測試模式,使用可以立即解出區塊的特殊區塊鏈。</translation>
- </message>
- <message>
<source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
<translation>當錢包有交易改變時要執行的指令(指令中的 %s 會被取代成交易識別碼)</translation>
</message>
<message>
- <source>In this mode -genproclimit controls how many blocks are generated immediately.</source>
- <translation>在這個運作模式下,-genproclimit 選項控制立刻產生出的區塊數目。</translation>
+ <source>Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)</source>
+ <translation>一次錢包交易允許付出最高的總手續費;設定太低的話,可能會無法進行資料量大的交易(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, &gt;%u = target size in MiB to use for block files)</source>
+ <translation>修剪(刪除)掉老舊區塊來減少儲存空間的需求。這種模式會關閉錢包功能,並且和 -txindex 參數不相容。警告: 從這種模式還原會需要重新下載一整個區塊鏈。(預設值: 0 表示不修剪區塊,&gt;%u 表示為區塊檔案的目標大小,單位是百萬位元組 MiB)</translation>
</message>
<message>
<source>Set the number of script verification threads (%u to %d, 0 = auto, &lt;0 = leave that many cores free, default: %d)</source>
@@ -2696,6 +2846,14 @@
<translation>沒辦法繫結在這台電腦上的 %s 。位元幣核心可能已經在執行了。</translation>
</message>
<message>
+ <source>WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>警告: 收到了不尋常地多的 %d 個區塊在過去 %d 小時內生產出來(預期是 %d 個)</translation>
+ </message>
+ <message>
+ <source>WARNING: check your network connection, %d blocks received in the last %d hours (%d expected)</source>
+ <translation>警告: 請檢查你的網路連線狀況,收到了 %d 個區塊是在過去 %d 小時內生產出來(預期是 %d 個)</translation>
+ </message>
+ <message>
<source>Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.</source>
<translation>警告: -paytxfee 設定了很高的金額!這可是你交易付款所要付的手續費。</translation>
</message>
@@ -2812,6 +2970,14 @@
<translation>只有連接到網絡節點 &lt;net&gt; (IPv4,IPv6或onion)</translation>
</message>
<message>
+ <source>Prune cannot be configured with a negative value.</source>
+ <translation>修剪值不能設定為負的。</translation>
+ </message>
+ <message>
+ <source>Prune mode is incompatible with -txindex.</source>
+ <translation>修剪模式和 -txindex 參數不相容。</translation>
+ </message>
+ <message>
<source>Set database cache size in megabytes (%d to %d, default: %d)</source>
<translation>設定資料庫快取大小是多少百萬位元組(MB,範圍: %d 到 %d,預設值: %d)</translation>
</message>
@@ -2824,10 +2990,6 @@
<translation>指定錢包檔(會在資料目錄中)</translation>
</message>
<message>
- <source>This is intended for regression testing tools and app development.</source>
- <translation>這是設計用來給回歸測試工具和應用程式開發用的。</translation>
- </message>
- <message>
<source>Verifying blocks...</source>
<translation>正在驗證區塊資料...</translation>
</message>
@@ -2844,6 +3006,10 @@
<translation>錢包選項:</translation>
</message>
<message>
+ <source>Warning: This version is obsolete; upgrade required!</source>
+ <translation>警告: 這個版本已經被淘汰了;必須要升級!</translation>
+ </message>
+ <message>
<source>You need to rebuild the database using -reindex to change -txindex</source>
<translation>改變 -txindex 參數後,必須要用 -reindex 參數來重建資料庫</translation>
</message>
@@ -2876,6 +3042,10 @@
<translation>用系統預設權限來造出新的檔案,而不是用使用者權限罩遮(umask)值 077 (只有在關掉錢包功能時才有作用)。</translation>
</message>
<message>
+ <source>Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)</source>
+ <translation>找出自己的網際網路位址(預設值: 當有聽候連線且沒有指定 -externalip 或 -proxy 時為 1)</translation>
+ </message>
+ <message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>錯誤: 聽候外來連線失敗(回傳錯誤 %s)</translation>
</message>
@@ -2892,10 +3062,6 @@
<translation>當處理轉發的交易時,如果每千位元組(Kb)的手續費比這個值低,就視為沒付手續費 (預設值: %s)</translation>
</message>
<message>
- <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
- <translation>當製造交易時,如果每千位元組(Kb)的手續費比這個值低,就視為沒付手續費 (預設值: %s)</translation>
- </message>
- <message>
<source>If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)</source>
<translation>當沒有設定 paytxfee 時,自動包含可以讓交易能在平均 n 個區塊內開始確認的手續費(預設值: %u)</translation>
</message>
@@ -2908,10 +3074,18 @@
<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>
<message>
+ <source>Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)</source>
+ <translation>對每個代理連線使用隨機產生的憑證。這個選項會開啟 Tor 的串流隔離(預設值: %u)</translation>
+ </message>
+ <message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>設定高優先度或低手續費的交易資料大小上限成多少位元組(預設值: %d)</translation>
</message>
@@ -2920,6 +3094,10 @@
<translation>設定產生錢幣的執行緒數目(-1 表示處理器核心數,預設值: %d)</translation>
</message>
<message>
+ <source>The transaction amount is too small to send after the fee has been deducted</source>
+ <translation>扣除手續費後的交易金額太少而不能傳送</translation>
+ </message>
+ <message>
<source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit &lt;https://www.openssl.org/&gt; and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source>
<translation>此產品也包含了由 OpenSSL Project 所開發的 OpenSSL Toolkit 軟體 &lt;https://www.openssl.org/&gt;, 和由 Eric Young 撰寫的加解密軟體,以及由 Thomas Bernard 所撰寫的 UPnP 軟體。</translation>
</message>
@@ -2960,10 +3138,26 @@ rpcpassword=%s
<translation>在白名單中的節點不會因為偵測到阻斷服務攻擊而被停用。來自這些節點的交易也一定會被轉發,即使說交易本來就在記憶池裡了也一樣。適用於像是閘道伺服器。</translation>
</message>
<message>
+ <source>You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
+ <translation>回到非修剪的模式需要用 -reindex 參數來重建資料庫。這會導致重新下載整個區塊鏈。</translation>
+ </message>
+ <message>
+ <source>(default: %u)</source>
+ <translation>(預設值: %u)</translation>
+ </message>
+ <message>
<source>Accept public REST requests (default: %u)</source>
<translation>接受公開的REST請求 (預設值: %u)</translation>
</message>
<message>
+ <source>Activating best chain...</source>
+ <translation>啟用最佳鏈結...</translation>
+ </message>
+ <message>
+ <source>Can't run with a wallet in prune mode.</source>
+ <translation>不能在有錢包時執行修剪模式。</translation>
+ </message>
+ <message>
<source>Cannot resolve -whitebind address: '%s'</source>
<translation>沒辦法解析 -whitebind 指定的位址: '%s'</translation>
</message>
@@ -3052,12 +3246,8 @@ rpcpassword=%s
<translation>RPC 是否支援 HTTP 持久連線(預設值: %d)</translation>
</message>
<message>
- <source>Randomly drop 1 of every &lt;n&gt; network messages</source>
- <translation>隨機丟掉 &lt;n&gt; 分之一的網路訊息</translation>
- </message>
- <message>
- <source>Randomly fuzz 1 of every &lt;n&gt; network messages</source>
- <translation>隨機亂動 &lt;n&gt; 分之一的網路訊息裡的資料</translation>
+ <source>Rebuild block chain index from current blk000??.dat files on startup</source>
+ <translation>啟動時從目前的區塊檔 blk000??.dat 重建區塊鏈的索引</translation>
</message>
<message>
<source>Send trace/debug info to console instead of debug.log file</source>
@@ -3096,6 +3286,10 @@ rpcpassword=%s
<translation>啓動時縮到最小</translation>
</message>
<message>
+ <source>The transaction amount is too small to pay the fee</source>
+ <translation>交易金額太少而付不起手續費</translation>
+ </message>
+ <message>
<source>This is experimental software.</source>
<translation>這套軟體屬於實驗性質。</translation>
</message>
@@ -3116,6 +3310,10 @@ rpcpassword=%s
<translation>交易位元量太大</translation>
</message>
<message>
+ <source>UI Options:</source>
+ <translation>使用介面選項:</translation>
+ </message>
+ <message>
<source>Unable to bind to %s on this computer (bind returned error %s)</source>
<translation>無法和這台電腦上的 %s 繫結(回傳錯誤 %s)</translation>
</message>
@@ -3196,18 +3394,10 @@ rpcpassword=%s
<translation>(1 表示保留交易描述資料,像是帳戶使用者和付款請求資訊;2 表示丟掉交易描述資料)</translation>
</message>
<message>
- <source>Flush database activity from memory pool to disk log every &lt;n&gt; megabytes (default: %u)</source>
- <translation>每當累積到 &lt;n&gt; 百萬位元組(MB)時,才將資料庫的變動從記憶體暫存池中寫進磁碟紀錄檔(預設值: %u)</translation>
- </message>
- <message>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>使用 -checkblocks 檢查區塊的仔細程度(0 到 4,預設值: %u)</translation>
</message>
<message>
- <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
- <translation>開採區塊的時候,紀錄交易的優先度以及每千位元組(kB)的手續費(預設值: %u)</translation>
- </message>
- <message>
<source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
<translation>維護全部交易的索引,用在 getrawtransaction 這個 RPC 請求(預設值: %u)</translation>
</message>
@@ -3236,18 +3426,10 @@ rpcpassword=%s
<translation>是否一定要用域名查詢來搜尋節點(預設值: %u)</translation>
</message>
<message>
- <source>Disable safemode, override a real safe mode event (default: %u)</source>
- <translation>不進入安全模式,用在真的發生需要進入安全模式的事件時,強制不進入(預設值: %u)</translation>
- </message>
- <message>
<source>Error loading wallet.dat</source>
<translation>載入錢包檔 wallet.dat 時發生錯誤</translation>
</message>
<message>
- <source>Force safe mode (default: %u)</source>
- <translation>強制進入安全模式(預設值: %u)</translation>
- </message>
- <message>
<source>Generate coins (default: %u)</source>
<translation>生產位元幣(預設值: %u)</translation>
</message>
@@ -3264,10 +3446,6 @@ rpcpassword=%s
<translation>無效的 -proxy 位址: '%s'</translation>
</message>
<message>
- <source>Limit size of signature cache to &lt;n&gt; entries (default: %u)</source>
- <translation>限制簽章快取大小為 &lt;n&gt; 筆(預設值: %u)</translation>
- </message>
- <message>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: %u or testnet: %u)</source>
<translation>在通訊埠 &lt;port&gt; 聽候 JSON-RPC 連線(預設值: %u, 或若為測試網路: %u)</translation>
</message>
@@ -3280,6 +3458,10 @@ rpcpassword=%s
<translation>維持與節點連線數的上限為 &lt;n&gt; 個(預設值: %u)</translation>
</message>
<message>
+ <source>Make the wallet broadcast transactions</source>
+ <translation>讓錢包能公告交易</translation>
+ </message>
+ <message>
<source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: %u)</source>
<translation>每個連線的接收緩衝區大小上限為 &lt;n&gt;*1000 個位元組(預設值: %u)</translation>
</message>
@@ -3288,10 +3470,6 @@ rpcpassword=%s
<translation>每個連線的傳送緩衝區大小上限為 &lt;n&gt;*1000 個位元組(預設值: %u)</translation>
</message>
<message>
- <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
- <translation>只接受與內建的檢查段點吻合的區塊鎖鏈(預設值: %u)</translation>
- </message>
- <message>
<source>Prepend debug output with timestamp (default: %u)</source>
<translation>在除錯輸出內容前附加時間(預設值: %u)</translation>
</message>
@@ -3304,10 +3482,6 @@ rpcpassword=%s
<translation>允許轉發非 P2SH 的多簽章交易(預設值: %u)</translation>
</message>
<message>
- <source>Run a thread to flush wallet periodically (default: %u)</source>
- <translation>啟用定期將變動寫入錢包檔的執行緒(預設值: %u)</translation>
- </message>
- <message>
<source>Server certificate file (default: %s)</source>
<translation>伺服器憑證檔(預設值: %s)</translation>
</message>
@@ -3328,10 +3502,6 @@ rpcpassword=%s
<translation>設定處理 RPC 服務請求的執行緒數目(預設值: %d)</translation>
</message>
<message>
- <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
- <translation>在錢包資料庫環境變數設定 DB_PRIVATE 旗標(預設值: %u)</translation>
- </message>
- <message>
<source>Specify configuration file (default: %s)</source>
<translation>指定設定檔(預設值: %s)</translation>
</message>
@@ -3348,10 +3518,6 @@ rpcpassword=%s
<translation>傳送交易時可以花還沒確認的零錢(預設值: %u)</translation>
</message>
<message>
- <source>Stop running after importing blocks from disk (default: %u)</source>
- <translation>從磁碟匯入區塊資料後停止執行(預設值: %u)</translation>
- </message>
- <message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>與亂搞的節點斷線的臨界值 (預設: %u)</translation>
</message>
diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp
index e28f903b2e..4541c75886 100644
--- a/src/qt/networkstyle.cpp
+++ b/src/qt/networkstyle.cpp
@@ -5,7 +5,6 @@
#include "networkstyle.h"
#include "guiconstants.h"
-#include "scicon.h"
#include <QApplication>
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index 173bed3b62..f57c1203f6 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -13,7 +13,7 @@
#include "guiutil.h"
#include "optionsmodel.h"
-#include "main.h" // for MAX_SCRIPTCHECK_THREADS
+#include "main.h" // for DEFAULT_SCRIPTCHECK_THREADS and MAX_SCRIPTCHECK_THREADS
#include "netbase.h"
#include "txdb.h" // for -dbcache defaults
@@ -35,7 +35,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
ui(new Ui::OptionsDialog),
model(0),
mapper(0),
- fProxyIpValid(true)
+ fProxyIpsValid(true)
{
ui->setupUi(this);
@@ -54,10 +54,18 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
ui->proxyPort->setEnabled(false);
ui->proxyPort->setValidator(new QIntValidator(1, 65535, this));
+ ui->proxyIpTor->setEnabled(false);
+ ui->proxyPortTor->setEnabled(false);
+ ui->proxyPortTor->setValidator(new QIntValidator(1, 65535, this));
+
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool)));
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool)));
+ connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyIpTor, SLOT(setEnabled(bool)));
+ connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyPortTor, SLOT(setEnabled(bool)));
+
ui->proxyIp->installEventFilter(this);
+ ui->proxyIpTor->installEventFilter(this);
/* Window elements init */
#ifdef Q_OS_MAC
@@ -110,7 +118,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
mapper->setOrientation(Qt::Vertical);
- /* setup/change UI elements when proxy IP is invalid/valid */
+ /* setup/change UI elements when proxy IPs are invalid/valid */
connect(this, SIGNAL(proxyIpChecks(QValidatedLineEdit *, int)), this, SLOT(doProxyIpChecks(QValidatedLineEdit *, int)));
}
@@ -137,6 +145,8 @@ void OptionsDialog::setModel(OptionsModel *model)
mapper->setModel(model);
setMapper();
mapper->toFirst();
+
+ updateDefaultProxyNets();
}
/* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */
@@ -149,6 +159,7 @@ void OptionsDialog::setModel(OptionsModel *model)
/* Network */
connect(ui->allowIncoming, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
+ connect(ui->connectSocksTor, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
/* Display */
connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning()));
connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning()));
@@ -173,6 +184,10 @@ void OptionsDialog::setMapper()
mapper->addMapping(ui->proxyIp, OptionsModel::ProxyIP);
mapper->addMapping(ui->proxyPort, OptionsModel::ProxyPort);
+ mapper->addMapping(ui->connectSocksTor, OptionsModel::ProxyUseTor);
+ mapper->addMapping(ui->proxyIpTor, OptionsModel::ProxyIPTor);
+ mapper->addMapping(ui->proxyPortTor, OptionsModel::ProxyPortTor);
+
/* Window */
#ifndef Q_OS_MAC
mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray);
@@ -188,7 +203,7 @@ void OptionsDialog::setMapper()
void OptionsDialog::enableOkButton()
{
/* prevent enabling of the OK button when data modified, if there is an invalid proxy address present */
- if(fProxyIpValid)
+ if(fProxyIpsValid)
setOkButtonState(true);
}
@@ -224,6 +239,7 @@ void OptionsDialog::on_okButton_clicked()
{
mapper->submit();
accept();
+ updateDefaultProxyNets();
}
void OptionsDialog::on_cancelButton_clicked()
@@ -257,11 +273,10 @@ void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPo
{
Q_UNUSED(nProxyPort);
- const std::string strAddrProxy = pUiProxyIp->text().toStdString();
CService addrProxy;
/* Check for a valid IPv4 / IPv6 address */
- if (!(fProxyIpValid = LookupNumeric(strAddrProxy.c_str(), addrProxy)))
+ if (!(fProxyIpsValid = LookupNumeric(pUiProxyIp->text().toStdString().c_str(), addrProxy)))
{
disableOkButton();
pUiProxyIp->setValid(false);
@@ -275,6 +290,28 @@ void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPo
}
}
+void OptionsDialog::updateDefaultProxyNets()
+{
+ proxyType proxy;
+ std::string strProxy;
+ QString strDefaultProxyGUI;
+
+ GetProxy(NET_IPV4, proxy);
+ strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort();
+ strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text();
+ (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachIPv4->setChecked(true) : ui->proxyReachIPv4->setChecked(false);
+
+ GetProxy(NET_IPV6, proxy);
+ strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort();
+ strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text();
+ (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachIPv6->setChecked(true) : ui->proxyReachIPv6->setChecked(false);
+
+ GetProxy(NET_TOR, proxy);
+ strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort();
+ strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text();
+ (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachTor->setChecked(true) : ui->proxyReachTor->setChecked(false);
+}
+
bool OptionsDialog::eventFilter(QObject *object, QEvent *event)
{
if(event->type() == QEvent::FocusOut)
@@ -283,6 +320,10 @@ bool OptionsDialog::eventFilter(QObject *object, QEvent *event)
{
Q_EMIT proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt());
}
+ else if(object == ui->proxyIpTor)
+ {
+ Q_EMIT proxyIpChecks(ui->proxyIpTor, ui->proxyPortTor->text().toInt());
+ }
}
return QDialog::eventFilter(object, event);
}
diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h
index fa983e798c..348489c599 100644
--- a/src/qt/optionsdialog.h
+++ b/src/qt/optionsdialog.h
@@ -47,6 +47,8 @@ private Q_SLOTS:
void showRestartWarning(bool fPersistent = false);
void clearStatusLabel();
void doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort);
+ /* query the networks, for which the default proxy is used */
+ void updateDefaultProxyNets();
Q_SIGNALS:
void proxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort);
@@ -55,7 +57,7 @@ private:
Ui::OptionsDialog *ui;
OptionsModel *model;
QDataWidgetMapper *mapper;
- bool fProxyIpValid;
+ bool fProxyIpsValid;
};
#endif // BITCOIN_QT_OPTIONSDIALOG_H
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index b4ce8191d0..65e490570e 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -13,7 +13,7 @@
#include "amount.h"
#include "init.h"
-#include "main.h"
+#include "main.h" // For DEFAULT_SCRIPTCHECK_THREADS
#include "net.h"
#include "txdb.h" // for -dbcache defaults
@@ -117,6 +117,16 @@ void OptionsModel::Init()
else if(!settings.value("fUseProxy").toBool() && !GetArg("-proxy", "").empty())
addOverriddenOption("-proxy");
+ if (!settings.contains("fUseSeparateProxyTor"))
+ settings.setValue("fUseSeparateProxyTor", false);
+ if (!settings.contains("addrSeparateProxyTor"))
+ settings.setValue("addrSeparateProxyTor", "127.0.0.1:9050");
+ // Only try to set -onion, if user has enabled fUseSeparateProxyTor
+ if (settings.value("fUseSeparateProxyTor").toBool() && !SoftSetArg("-onion", settings.value("addrSeparateProxyTor").toString().toStdString()))
+ addOverriddenOption("-onion");
+ else if(!settings.value("fUseSeparateProxyTor").toBool() && !GetArg("-onion", "").empty())
+ addOverriddenOption("-onion");
+
// Display
if (!settings.contains("language"))
settings.setValue("language", "");
@@ -178,6 +188,20 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
return strlIpPort.at(1);
}
+ // separate Tor proxy
+ case ProxyUseTor:
+ return settings.value("fUseSeparateProxyTor", false);
+ case ProxyIPTor: {
+ // contains IP at index 0 and port at index 1
+ QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
+ return strlIpPort.at(0);
+ }
+ case ProxyPortTor: {
+ // contains IP at index 0 and port at index 1
+ QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
+ return strlIpPort.at(1);
+ }
+
#ifdef ENABLE_WALLET
case SpendZeroConfChange:
return settings.value("bSpendZeroConfChange");
@@ -259,6 +283,39 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
}
}
break;
+
+ // separate Tor proxy
+ case ProxyUseTor:
+ if (settings.value("fUseSeparateProxyTor") != value) {
+ settings.setValue("fUseSeparateProxyTor", value.toBool());
+ setRestartRequired(true);
+ }
+ break;
+ case ProxyIPTor: {
+ // contains current IP at index 0 and current port at index 1
+ QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
+ // if that key doesn't exist or has a changed IP
+ if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(0) != value.toString()) {
+ // construct new value from new IP and current port
+ QString strNewValue = value.toString() + ":" + strlIpPort.at(1);
+ settings.setValue("addrSeparateProxyTor", strNewValue);
+ setRestartRequired(true);
+ }
+ }
+ break;
+ case ProxyPortTor: {
+ // contains current IP at index 0 and current port at index 1
+ QStringList strlIpPort = settings.value("addrSeparateProxyTor").toString().split(":", QString::SkipEmptyParts);
+ // if that key doesn't exist or has a changed port
+ if (!settings.contains("addrSeparateProxyTor") || strlIpPort.at(1) != value.toString()) {
+ // construct new value from current IP and new port
+ QString strNewValue = strlIpPort.at(0) + ":" + value.toString();
+ settings.setValue("addrSeparateProxyTor", strNewValue);
+ setRestartRequired(true);
+ }
+ }
+ break;
+
#ifdef ENABLE_WALLET
case SpendZeroConfChange:
if (settings.value("bSpendZeroConfChange") != value) {
diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h
index fc26d65b04..8448cad8de 100644
--- a/src/qt/optionsmodel.h
+++ b/src/qt/optionsmodel.h
@@ -34,6 +34,9 @@ public:
ProxyUse, // bool
ProxyIP, // QString
ProxyPort, // int
+ ProxyUseTor, // bool
+ ProxyIPTor, // QString
+ ProxyPortTor, // int
DisplayUnit, // BitcoinUnits::Unit
ThirdPartyTxUrls, // QString
Language, // QString
diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp
index bbd95ef478..a56c80ac63 100644
--- a/src/qt/overviewpage.cpp
+++ b/src/qt/overviewpage.cpp
@@ -10,7 +10,7 @@
#include "guiconstants.h"
#include "guiutil.h"
#include "optionsmodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "transactionfilterproxy.h"
#include "transactiontablemodel.h"
#include "walletmodel.h"
@@ -25,7 +25,9 @@ class TxViewDelegate : public QAbstractItemDelegate
{
Q_OBJECT
public:
- TxViewDelegate(): QAbstractItemDelegate(), unit(BitcoinUnits::BTC)
+ TxViewDelegate(const PlatformStyle *platformStyle):
+ QAbstractItemDelegate(), unit(BitcoinUnits::BTC),
+ platformStyle(platformStyle)
{
}
@@ -43,7 +45,7 @@ public:
int halfheight = (mainRect.height() - 2*ypad)/2;
QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight);
QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight);
- icon = SingleColorIcon(icon, SingleColor());
+ icon = platformStyle->SingleColorIcon(icon);
icon.paint(painter, decorationRect);
QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime();
@@ -101,11 +103,12 @@ public:
}
int unit;
+ const PlatformStyle *platformStyle;
};
#include "overviewpage.moc"
-OverviewPage::OverviewPage(QWidget *parent) :
+OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) :
QWidget(parent),
ui(new Ui::OverviewPage),
clientModel(0),
@@ -116,13 +119,13 @@ OverviewPage::OverviewPage(QWidget *parent) :
currentWatchOnlyBalance(-1),
currentWatchUnconfBalance(-1),
currentWatchImmatureBalance(-1),
- txdelegate(new TxViewDelegate()),
+ txdelegate(new TxViewDelegate(platformStyle)),
filter(0)
{
ui->setupUi(this);
// use a SingleColorIcon for the "out of sync warning" icon
- QIcon icon = SingleColorIcon(":/icons/warning");
+ QIcon icon = platformStyle->SingleColorIcon(":/icons/warning");
icon.addPixmap(icon.pixmap(QSize(64,64), QIcon::Normal), QIcon::Disabled); // also set the disabled icon because we are using a disabled QPushButton to work around missing HiDPI support of QLabel (https://bugreports.qt.io/browse/QTBUG-42503)
ui->labelTransactionsStatus->setIcon(icon);
ui->labelWalletStatus->setIcon(icon);
diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h
index de5ac345da..4139eb35d3 100644
--- a/src/qt/overviewpage.h
+++ b/src/qt/overviewpage.h
@@ -12,6 +12,7 @@
class ClientModel;
class TransactionFilterProxy;
class TxViewDelegate;
+class PlatformStyle;
class WalletModel;
namespace Ui {
@@ -28,7 +29,7 @@ class OverviewPage : public QWidget
Q_OBJECT
public:
- explicit OverviewPage(QWidget *parent = 0);
+ explicit OverviewPage(const PlatformStyle *platformStyle, QWidget *parent = 0);
~OverviewPage();
void setClientModel(ClientModel *clientModel);
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index 6481b0046e..31a6d65a8d 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -10,7 +10,7 @@
#include "base58.h"
#include "chainparams.h"
-#include "main.h"
+#include "main.h" // For minRelayTxFee
#include "ui_interface.h"
#include "util.h"
#include "wallet/wallet.h"
@@ -509,12 +509,7 @@ bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentR
}
// BIP70 DoS protection
- if (f.size() > BIP70_MAX_PAYMENTREQUEST_SIZE) {
- qWarning() << QString("PaymentServer::%1: Payment request %2 is too large (%3 bytes, allowed %4 bytes).")
- .arg(__func__)
- .arg(filename)
- .arg(f.size())
- .arg(BIP70_MAX_PAYMENTREQUEST_SIZE);
+ if (!verifySize(f.size())) {
return false;
}
@@ -685,14 +680,13 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply)
reply->deleteLater();
// BIP70 DoS protection
- if (reply->size() > BIP70_MAX_PAYMENTREQUEST_SIZE) {
- QString msg = tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).")
- .arg(reply->request().url().toString())
- .arg(reply->size())
- .arg(BIP70_MAX_PAYMENTREQUEST_SIZE);
-
- qWarning() << QString("PaymentServer::%1:").arg(__func__) << msg;
- Q_EMIT message(tr("Payment request DoS protection"), msg, CClientUIInterface::MSG_ERROR);
+ if (!verifySize(reply->size())) {
+ Q_EMIT message(tr("Payment request rejected"),
+ tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).")
+ .arg(reply->request().url().toString())
+ .arg(reply->size())
+ .arg(BIP70_MAX_PAYMENTREQUEST_SIZE),
+ CClientUIInterface::MSG_ERROR);
return;
}
@@ -762,7 +756,7 @@ void PaymentServer::setOptionsModel(OptionsModel *optionsModel)
void PaymentServer::handlePaymentACK(const QString& paymentACKMsg)
{
- // currently we don't futher process or store the paymentACK message
+ // currently we don't further process or store the paymentACK message
Q_EMIT message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL);
}
@@ -790,6 +784,18 @@ bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails
return fVerified;
}
+bool PaymentServer::verifySize(qint64 requestSize)
+{
+ bool fVerified = (requestSize <= BIP70_MAX_PAYMENTREQUEST_SIZE);
+ if (!fVerified) {
+ qWarning() << QString("PaymentServer::%1: Payment request too large (%2 bytes, allowed %3 bytes).")
+ .arg(__func__)
+ .arg(requestSize)
+ .arg(BIP70_MAX_PAYMENTREQUEST_SIZE);
+ }
+ return fVerified;
+}
+
bool PaymentServer::verifyAmount(const CAmount& requestAmount)
{
bool fVerified = MoneyRange(requestAmount);
diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h
index 5df0a14cf7..fa120a435c 100644
--- a/src/qt/paymentserver.h
+++ b/src/qt/paymentserver.h
@@ -88,13 +88,12 @@ public:
// OptionsModel is used for getting proxy settings and display unit
void setOptionsModel(OptionsModel *optionsModel);
- // This is now public, because we use it in paymentservertests.cpp
- static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request);
-
// Verify that the payment request network matches the client network
static bool verifyNetwork(const payments::PaymentDetails& requestDetails);
// Verify if the payment request is expired
static bool verifyExpired(const payments::PaymentDetails& requestDetails);
+ // Verify the payment request size is valid as per BIP70
+ static bool verifySize(qint64 requestSize);
// Verify the payment request amount is valid
static bool verifyAmount(const CAmount& requestAmount);
@@ -131,6 +130,7 @@ protected:
bool eventFilter(QObject *object, QEvent *event);
private:
+ static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request);
bool processPaymentRequest(const PaymentRequestPlus& request, SendCoinsRecipient& recipient);
void fetchRequest(const QUrl& url);
diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp
index 85339166b0..770a860544 100644
--- a/src/qt/peertablemodel.cpp
+++ b/src/qt/peertablemodel.cpp
@@ -8,7 +8,6 @@
#include "guiconstants.h"
#include "guiutil.h"
-#include "net.h"
#include "sync.h"
#include <QDebug>
@@ -96,18 +95,17 @@ public:
mapNodeRows.insert(std::pair<NodeId, int>(stats.nodeStats.nodeid, row++));
}
- int size()
+ int size() const
{
return cachedNodeStats.size();
}
CNodeCombinedStats *index(int idx)
{
- if(idx >= 0 && idx < cachedNodeStats.size()) {
+ if (idx >= 0 && idx < cachedNodeStats.size())
return &cachedNodeStats[idx];
- } else {
- return 0;
- }
+
+ return 0;
}
};
@@ -171,7 +169,7 @@ QVariant PeerTableModel::data(const QModelIndex &index, int role) const
}
} else if (role == Qt::TextAlignmentRole) {
if (index.column() == Ping)
- return (int)(Qt::AlignRight | Qt::AlignVCenter);
+ return (QVariant)(Qt::AlignRight | Qt::AlignVCenter);
}
return QVariant();
@@ -204,13 +202,8 @@ QModelIndex PeerTableModel::index(int row, int column, const QModelIndex &parent
CNodeCombinedStats *data = priv->index(row);
if (data)
- {
return createIndex(row, column, data);
- }
- else
- {
- return QModelIndex();
- }
+ return QModelIndex();
}
const CNodeCombinedStats *PeerTableModel::getNodeStats(int idx)
diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h
index fcb89b7611..5f149ea873 100644
--- a/src/qt/peertablemodel.h
+++ b/src/qt/peertablemodel.h
@@ -5,7 +5,7 @@
#ifndef BITCOIN_QT_PEERTABLEMODEL_H
#define BITCOIN_QT_PEERTABLEMODEL_H
-#include "main.h"
+#include "main.h" // For CNodeStateStats
#include "net.h"
#include <QAbstractTableModel>
diff --git a/src/qt/platformstyle.cpp b/src/qt/platformstyle.cpp
new file mode 100644
index 0000000000..11cbc7a47c
--- /dev/null
+++ b/src/qt/platformstyle.cpp
@@ -0,0 +1,147 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "platformstyle.h"
+
+#include "guiconstants.h"
+
+#include <QApplication>
+#include <QColor>
+#include <QIcon>
+#include <QImage>
+#include <QPalette>
+#include <QPixmap>
+
+static const struct {
+ const char *platformId;
+ /** Show images on push buttons */
+ const bool imagesOnButtons;
+ /** Colorize single-color icons */
+ const bool colorizeIcons;
+ /** Extra padding/spacing in transactionview */
+ const bool useExtraSpacing;
+} platform_styles[] = {
+ {"macosx", false, false, true},
+ {"windows", true, false, false},
+ /* Other: linux, unix, ... */
+ {"other", true, true, false}
+};
+static const unsigned platform_styles_count = sizeof(platform_styles)/sizeof(*platform_styles);
+
+namespace {
+/* Local functions for colorizing single-color images */
+
+void MakeSingleColorImage(QImage& img, const QColor& colorbase)
+{
+ img = img.convertToFormat(QImage::Format_ARGB32);
+ for (int x = img.width(); x--; )
+ {
+ for (int y = img.height(); y--; )
+ {
+ const QRgb rgb = img.pixel(x, y);
+ img.setPixel(x, y, qRgba(colorbase.red(), colorbase.green(), colorbase.blue(), qAlpha(rgb)));
+ }
+ }
+}
+
+QIcon ColorizeIcon(const QIcon& ico, const QColor& colorbase)
+{
+ QIcon new_ico;
+ QSize sz;
+ Q_FOREACH(sz, ico.availableSizes())
+ {
+ QImage img(ico.pixmap(sz).toImage());
+ MakeSingleColorImage(img, colorbase);
+ new_ico.addPixmap(QPixmap::fromImage(img));
+ }
+ return new_ico;
+}
+
+QImage ColorizeImage(const QString& filename, const QColor& colorbase)
+{
+ QImage img(filename);
+ MakeSingleColorImage(img, colorbase);
+ return img;
+}
+
+QIcon ColorizeIcon(const QString& filename, const QColor& colorbase)
+{
+ return QIcon(QPixmap::fromImage(ColorizeImage(filename, colorbase)));
+}
+
+}
+
+
+PlatformStyle::PlatformStyle(const QString &name, bool imagesOnButtons, bool colorizeIcons, bool useExtraSpacing):
+ name(name),
+ imagesOnButtons(imagesOnButtons),
+ colorizeIcons(colorizeIcons),
+ useExtraSpacing(useExtraSpacing),
+ singleColor(0,0,0),
+ textColor(0,0,0)
+{
+ // Determine icon highlighting color
+ if (colorizeIcons) {
+ const QColor colorHighlightBg(QApplication::palette().color(QPalette::Highlight));
+ const QColor colorHighlightFg(QApplication::palette().color(QPalette::HighlightedText));
+ const QColor colorText(QApplication::palette().color(QPalette::WindowText));
+ const int colorTextLightness = colorText.lightness();
+ QColor colorbase;
+ if (abs(colorHighlightBg.lightness() - colorTextLightness) < abs(colorHighlightFg.lightness() - colorTextLightness))
+ colorbase = colorHighlightBg;
+ else
+ colorbase = colorHighlightFg;
+ singleColor = colorbase;
+ }
+ // Determine text color
+ textColor = QColor(QApplication::palette().color(QPalette::WindowText));
+}
+
+QImage PlatformStyle::SingleColorImage(const QString& filename) const
+{
+ if (!colorizeIcons)
+ return QImage(filename);
+ return ColorizeImage(filename, SingleColor());
+}
+
+QIcon PlatformStyle::SingleColorIcon(const QString& filename) const
+{
+ if (!colorizeIcons)
+ return QIcon(filename);
+ return ColorizeIcon(filename, SingleColor());
+}
+
+QIcon PlatformStyle::SingleColorIcon(const QIcon& icon) const
+{
+ if (!colorizeIcons)
+ return icon;
+ return ColorizeIcon(icon, SingleColor());
+}
+
+QIcon PlatformStyle::TextColorIcon(const QString& filename) const
+{
+ return ColorizeIcon(filename, TextColor());
+}
+
+QIcon PlatformStyle::TextColorIcon(const QIcon& icon) const
+{
+ return ColorizeIcon(icon, TextColor());
+}
+
+const PlatformStyle *PlatformStyle::instantiate(const QString &platformId)
+{
+ for (unsigned x=0; x<platform_styles_count; ++x)
+ {
+ if (platformId == platform_styles[x].platformId)
+ {
+ return new PlatformStyle(
+ platform_styles[x].platformId,
+ platform_styles[x].imagesOnButtons,
+ platform_styles[x].colorizeIcons,
+ platform_styles[x].useExtraSpacing);
+ }
+ }
+ return 0;
+}
+
diff --git a/src/qt/platformstyle.h b/src/qt/platformstyle.h
new file mode 100644
index 0000000000..4e763e760e
--- /dev/null
+++ b/src/qt/platformstyle.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_PLATFORMSTYLE_H
+#define BITCOIN_QT_PLATFORMSTYLE_H
+
+#include <QIcon>
+#include <QPixmap>
+#include <QString>
+
+/* Coin network-specific GUI style information */
+class PlatformStyle
+{
+public:
+ /** Get style associated with provided platform name, or 0 if not known */
+ static const PlatformStyle *instantiate(const QString &platformId);
+
+ const QString &getName() const { return name; }
+
+ bool getImagesOnButtons() const { return imagesOnButtons; }
+ bool getUseExtraSpacing() const { return useExtraSpacing; }
+
+ QColor TextColor() const { return textColor; }
+ QColor SingleColor() const { return singleColor; }
+
+ /** Colorize an image (given filename) with the icon color */
+ QImage SingleColorImage(const QString& filename) const;
+
+ /** Colorize an icon (given filename) with the icon color */
+ QIcon SingleColorIcon(const QString& filename) const;
+
+ /** Colorize an icon (given object) with the icon color */
+ QIcon SingleColorIcon(const QIcon& icon) const;
+
+ /** Colorize an icon (given filename) with the text color */
+ QIcon TextColorIcon(const QString& filename) const;
+
+ /** Colorize an icon (given object) with the text color */
+ QIcon TextColorIcon(const QIcon& icon) const;
+
+private:
+ PlatformStyle(const QString &name, bool imagesOnButtons, bool colorizeIcons, bool useExtraSpacing);
+
+ QString name;
+ bool imagesOnButtons;
+ bool colorizeIcons;
+ bool useExtraSpacing;
+ QColor singleColor;
+ QColor textColor;
+ /* ... more to come later */
+};
+
+#endif // BITCOIN_QT_PLATFORMSTYLE_H
+
diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp
index 43b46c63b5..7fb68cc32a 100644
--- a/src/qt/receivecoinsdialog.cpp
+++ b/src/qt/receivecoinsdialog.cpp
@@ -10,9 +10,9 @@
#include "bitcoinunits.h"
#include "guiutil.h"
#include "optionsmodel.h"
+#include "platformstyle.h"
#include "receiverequestdialog.h"
#include "recentrequeststablemodel.h"
-#include "scicon.h"
#include "walletmodel.h"
#include <QAction>
@@ -22,24 +22,25 @@
#include <QScrollBar>
#include <QTextDocument>
-ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget *parent) :
+ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) :
QDialog(parent),
ui(new Ui::ReceiveCoinsDialog),
- model(0)
+ model(0),
+ platformStyle(platformStyle)
{
ui->setupUi(this);
-#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
- ui->clearButton->setIcon(QIcon());
- ui->receiveButton->setIcon(QIcon());
- ui->showRequestButton->setIcon(QIcon());
- ui->removeRequestButton->setIcon(QIcon());
-#else
- ui->clearButton->setIcon(SingleColorIcon(":/icons/remove"));
- ui->receiveButton->setIcon(SingleColorIcon(":/icons/receiving_addresses"));
- ui->showRequestButton->setIcon(SingleColorIcon(":/icons/edit"));
- ui->removeRequestButton->setIcon(SingleColorIcon(":/icons/remove"));
-#endif
+ if (!platformStyle->getImagesOnButtons()) {
+ ui->clearButton->setIcon(QIcon());
+ ui->receiveButton->setIcon(QIcon());
+ ui->showRequestButton->setIcon(QIcon());
+ ui->removeRequestButton->setIcon(QIcon());
+ } else {
+ ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->receiveButton->setIcon(platformStyle->SingleColorIcon(":/icons/receiving_addresses"));
+ ui->showRequestButton->setIcon(platformStyle->SingleColorIcon(":/icons/edit"));
+ ui->removeRequestButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ }
// context menu actions
QAction *copyLabelAction = new QAction(tr("Copy label"), this);
@@ -132,7 +133,7 @@ void ReceiveCoinsDialog::on_receiveButton_clicked()
if(ui->reuseAddress->isChecked())
{
/* Choose existing receiving address */
- AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
+ AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
dlg.setModel(model->getAddressTableModel());
if(dlg.exec())
{
diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h
index 6bb159482b..eaaf129a91 100644
--- a/src/qt/receivecoinsdialog.h
+++ b/src/qt/receivecoinsdialog.h
@@ -16,6 +16,7 @@
#include <QVariant>
class OptionsModel;
+class PlatformStyle;
class WalletModel;
namespace Ui {
@@ -39,7 +40,7 @@ public:
MINIMUM_COLUMN_WIDTH = 130
};
- explicit ReceiveCoinsDialog(QWidget *parent = 0);
+ explicit ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent = 0);
~ReceiveCoinsDialog();
void setModel(WalletModel *model);
@@ -57,6 +58,8 @@ private:
GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer;
WalletModel *model;
QMenu *contextMenu;
+ const PlatformStyle *platformStyle;
+
void copyColumnToClipboard(int column);
virtual void resizeEvent(QResizeEvent *event);
diff --git a/src/qt/res/icons/about_qt.png b/src/qt/res/icons/about_qt.png
index dd27a99d0a..c40abfd3a6 100644
--- a/src/qt/res/icons/about_qt.png
+++ b/src/qt/res/icons/about_qt.png
Binary files differ
diff --git a/src/qt/res/icons/clock1.png b/src/qt/res/icons/clock1.png
index ceae5ed0d9..162204d1bb 100644
--- a/src/qt/res/icons/clock1.png
+++ b/src/qt/res/icons/clock1.png
Binary files differ
diff --git a/src/qt/res/icons/clock2.png b/src/qt/res/icons/clock2.png
index 159f69a8fc..8f4263a31c 100644
--- a/src/qt/res/icons/clock2.png
+++ b/src/qt/res/icons/clock2.png
Binary files differ
diff --git a/src/qt/res/icons/clock3.png b/src/qt/res/icons/clock3.png
index d668e35ffc..7f11a7566c 100644
--- a/src/qt/res/icons/clock3.png
+++ b/src/qt/res/icons/clock3.png
Binary files differ
diff --git a/src/qt/res/icons/clock4.png b/src/qt/res/icons/clock4.png
index 5ebf8ed7ac..fdd1a0fce3 100644
--- a/src/qt/res/icons/clock4.png
+++ b/src/qt/res/icons/clock4.png
Binary files differ
diff --git a/src/qt/res/icons/clock5.png b/src/qt/res/icons/clock5.png
index 96f15ef7d9..7d6556c6cf 100644
--- a/src/qt/res/icons/clock5.png
+++ b/src/qt/res/icons/clock5.png
Binary files differ
diff --git a/src/qt/res/icons/connect0.png b/src/qt/res/icons/connect0.png
index 58e2c3e965..ef708d81fb 100644
--- a/src/qt/res/icons/connect0.png
+++ b/src/qt/res/icons/connect0.png
Binary files differ
diff --git a/src/qt/res/icons/connect1.png b/src/qt/res/icons/connect1.png
index 949e7a922d..ed358e6f8e 100644
--- a/src/qt/res/icons/connect1.png
+++ b/src/qt/res/icons/connect1.png
Binary files differ
diff --git a/src/qt/res/icons/connect2.png b/src/qt/res/icons/connect2.png
index 143b2054fb..3bbb0d395c 100644
--- a/src/qt/res/icons/connect2.png
+++ b/src/qt/res/icons/connect2.png
Binary files differ
diff --git a/src/qt/res/icons/connect3.png b/src/qt/res/icons/connect3.png
index 143b2054fb..0db99ad8d3 100644
--- a/src/qt/res/icons/connect3.png
+++ b/src/qt/res/icons/connect3.png
Binary files differ
diff --git a/src/qt/res/icons/connect4.png b/src/qt/res/icons/connect4.png
index f96e3455ce..9dd19fc2bd 100644
--- a/src/qt/res/icons/connect4.png
+++ b/src/qt/res/icons/connect4.png
Binary files differ
diff --git a/src/qt/res/icons/transaction0.png b/src/qt/res/icons/transaction0.png
index 1091b86e68..72c44565ec 100644
--- a/src/qt/res/icons/transaction0.png
+++ b/src/qt/res/icons/transaction0.png
Binary files differ
diff --git a/src/qt/res/icons/warning.png b/src/qt/res/icons/warning.png
index 723a30a658..6bc5ac7895 100644
--- a/src/qt/res/icons/warning.png
+++ b/src/qt/res/icons/warning.png
Binary files differ
diff --git a/src/qt/res/movies/makespinner.sh b/src/qt/res/movies/makespinner.sh
index 625fb17173..a4c2fddbbf 100755
--- a/src/qt/res/movies/makespinner.sh
+++ b/src/qt/res/movies/makespinner.sh
@@ -1,6 +1,7 @@
-for i in {1..35}
+FRAMEDIR=$(dirname $0)
+for i in {0..35}
do
- value=$(printf "%03d" $i)
+ frame=$(printf "%03d" $i)
angle=$(($i * 10))
- convert spinner-000.png -background "rgba(0,0,0,0.0)" -distort SRT $angle spinner-$value.png
+ convert $FRAMEDIR/../src/spinner.png -background "rgba(0,0,0,0.0)" -distort SRT $angle $FRAMEDIR/spinner-$frame.png
done
diff --git a/src/qt/res/movies/spinner-000.png b/src/qt/res/movies/spinner-000.png
index 1e92d859da..0dc48d0d8c 100644
--- a/src/qt/res/movies/spinner-000.png
+++ b/src/qt/res/movies/spinner-000.png
Binary files differ
diff --git a/src/qt/res/src/clock_1.svg b/src/qt/res/src/clock_1.svg
index 4e49772d26..2a3d84c2d0 100644
--- a/src/qt/res/src/clock_1.svg
+++ b/src/qt/res/src/clock_1.svg
@@ -9,5 +9,7 @@
c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
</g>
-<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+<path
+ d="M 478.3,253.4 297.6,184.6 c 0,0 0,78.8 0,118.2 0,117.5 -0.4,118.1 118.2,118.1 39.4,0 118.2,0 118.2,0 z"
+ id="polygon7" />
</svg>
diff --git a/src/qt/res/src/clock_2.svg b/src/qt/res/src/clock_2.svg
index 995446e46e..2de8d467b7 100644
--- a/src/qt/res/src/clock_2.svg
+++ b/src/qt/res/src/clock_2.svg
@@ -9,6 +9,5 @@
c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
</g>
-<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>
-<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+<polygon points="465.2,601.6 534,420.9 478.3,253.4 297.6,184.6 297.6,420.9 297.6,657.3 "/>
</svg>
diff --git a/src/qt/res/src/clock_3.svg b/src/qt/res/src/clock_3.svg
index ea47a84730..b691043e3e 100644
--- a/src/qt/res/src/clock_3.svg
+++ b/src/qt/res/src/clock_3.svg
@@ -9,7 +9,7 @@
c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
</g>
-<polygon points="117,588.5 297.6,657.3 297.6,420.9 61.3,420.9 "/>
-<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>
-<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
+<path
+ d="M 465.2,601.6 534,420.9 478.3,253.4 297.6,184.6 c 0,0 0,78.8 0,118.2 0,117.7 0.4,118.1 -118.1,118.1 -39.4,0 -118.2,0 -118.2,0 l 55.7,167.6 180.6,68.8 z"
+ id="polygon7" />
</svg>
diff --git a/src/qt/res/src/clock_4.svg b/src/qt/res/src/clock_4.svg
index 43160288d8..ea311f31e8 100644
--- a/src/qt/res/src/clock_4.svg
+++ b/src/qt/res/src/clock_4.svg
@@ -1,18 +1,23 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 841.9 841.9" enable-background="new 0 0 841.9 841.9" xml:space="preserve">
-<g>
- <path d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1
- s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6
- c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4
- c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>
-</g>
-<polygon points="130.1,240.3 61.3,420.9 297.6,420.9 297.6,184.6 "/>
-<polygon points="117,588.5 297.6,657.3 297.6,420.9 61.3,420.9 "/>
-<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>
-<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>
-<path fill="#FFFFFF" d="M293.5,452.6h99.6c14.9,0,24.8-9.9,24.8-24.8S408,403,393.1,403h-74.8V278.2c0-14.9-9.9-24.8-24.8-24.8
- c-14.9,0-24.8,9.9-24.8,24.8v149.6C268.7,440.2,278.7,452.6,293.5,452.6z"/>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xml:space="preserve"
+ enable-background="new 0 0 841.9 841.9"
+ viewBox="0 0 841.9 841.9"
+ y="0px"
+ x="0px"
+ id="Ebene_1"
+ version="1.1"><metadata
+ id="metadata15"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs13" /><g
+ id="g3"><path
+ id="path5"
+ d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1 s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6 c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4 c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z" /></g><path
+ id="polygon7"
+ d="M 297.6 184.6 L 130.1 240.3 L 61.3 420.9 L 117 588.5 L 297.6 657.3 L 465.2 601.6 L 534 420.9 L 478.3 253.4 L 297.6 184.6 z M 293.5 253.4 C 308.4 253.4 318.3 263.3 318.3 278.2 L 318.3 403 L 393.1 403 C 408 403 417.9 412.9 417.9 427.8 C 417.9 442.7 408 452.6 393.1 452.6 L 293.5 452.6 C 278.7 452.6 268.7 440.2 268.7 427.8 L 268.7 278.2 C 268.7 263.3 278.6 253.4 293.5 253.4 z " /></svg> \ No newline at end of file
diff --git a/src/qt/res/src/connect-0.svg b/src/qt/res/src/connect-0.svg
index bedbec7777..7d2afac622 100644
--- a/src/qt/res/src/connect-0.svg
+++ b/src/qt/res/src/connect-0.svg
@@ -1,11 +1,66 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
-<path fill="none" stroke="#000000" stroke-miterlimit="10" d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0
- c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z M7.8,15.8c-0.5,0-1-0.2-1.4-0.6c-0.8-0.8-0.8-2,0-2.8
- c3.1-3.1,8.2-3.1,11.3,0c0.8,0.8,0.8,2,0,2.8c-0.8,0.8-2,0.8-2.8,0c-1.6-1.6-4.1-1.6-5.7,0C8.8,15.6,8.3,15.8,7.8,15.8z"/>
-<path fill="none" stroke="#000000" stroke-miterlimit="10" d="M20.5,11.5c-0.5,0-1-0.2-1.4-0.6C15.2,7,8.8,7,4.9,10.9
- c-0.8,0.8-2,0.8-2.8,0c-0.8-0.8-0.8-2,0-2.8c5.5-5.5,14.3-5.5,19.8,0c0.8,0.8,0.8,2,0,2.8C21.5,11.3,21,11.5,20.5,11.5z"/>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ id="svg2"
+ viewBox="0 0 24 24"
+ height="24"
+ width="24"
+ version="1.2">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <g
+ id="g4142"
+ transform="matrix(0,-1,-1,0,23.96,24)">
+ <g
+ id="g4210"
+ transform="matrix(-1,0,0,1,59.86,-106.6)">
+ <g
+ id="g4289"
+ transform="matrix(-1,0,0,1,-16.98,0.8136)">
+ <g
+ id="g4291">
+ <path
+ id="path4293"
+ d="m -65.35,116.3 0,3 0.5,0 c 0.54,0 1,0.5 1,1 l 0,2.6 c -1.15,0.5 -2,1.6 -2,3 0,2 1.59,3.5 3.5,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-2.3 -1.81,-4 -4,-4 z m 1,1.2 c 1.39,0.3 2.5,1.3 2.5,2.8 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.5,-1.1 -2.5,-2.5 0,-1.1 0.69,-2 1.66,-2.3 l 0.34,-0.1 0,-3.2 c 0,-0.9 -0.67,-1.5 -1.5,-1.8 z"
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <g
+ style="fill:#969696;fill-opacity:1"
+ id="g4295">
+ <path
+ id="path4297"
+ d="m -67.35,106.1 c -1.94,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,2.2 1.79,4 4,4 l 0.5,0 0,-0.5 0,-2.5 -0.5,0 c -0.55,0 -1,-0.5 -1,-1 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.57,-3.5 -3.5,-3.5 z m 0,1 c 1.37,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,0.9 0.67,1.5 1.5,1.8 l 0,1 c -1.38,-0.3 -2.5,-1.4 -2.5,-2.8 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.12,-2.5 2.5,-2.5 z"
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <path
+ id="path4299"
+ d="m -57.35,106.1 c -1.93,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,0.5 -0.45,1 -1,1 l -4.85,0 3.17,3 1.68,0 c 2.21,0 4,-1.8 4,-4 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.56,-3.5 -3.5,-3.5 z m 0,1 c 1.38,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,1.6 -1.35,3 -3,3 l -1.81,0 -2.04,-1 3.85,0 c 1.11,0 2,-0.9 2,-2 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.13,-2.5 2.5,-2.5 z"
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ </g>
+ <path
+ id="path4301"
+ d="m -69.84,116.3 c -2.19,0 -4,1.7 -4,4 l 0,2.6 c -1.14,0.6 -1.99,1.6 -1.99,3 0,2 1.6,3.5 3.51,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-0.5 0.45,-1 1,-1 l 5.01,0 -3.36,-3 z m 0,1 1.84,0 2.19,1 -4.01,0 c -1.11,0 -2,0.9 -2,2 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.51,-1.1 -2.51,-2.5 0,-1.1 0.7,-2 1.66,-2.3 l 0.33,-0.1 0,-0.4 0,-2.8 c 0,-1.7 1.33,-3 3,-3 z"
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ </g>
+ </g>
+ </g>
+ <path
+ id="path4165"
+ d="m 12,8.77 c -0.84,0 -1.66,0.341 -2.254,0.937 -0.599,0.593 -0.942,1.403 -0.945,2.253 0,0.85 0.337,1.67 0.933,2.26 a 0.6001,0.6001 0 0 0 0,0 c 0.594,0.6 1.424,0.94 2.264,0.94 0.84,0 1.67,-0.34 2.26,-0.94 0.6,-0.59 0.94,-1.41 0.94,-2.26 0,-0.84 -0.34,-1.66 -0.95,-2.253 C 13.66,9.111 12.84,8.77 12,8.77 Z"
+ style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/src/qt/res/src/connect-1.svg b/src/qt/res/src/connect-1.svg
index d3d4e46a41..d17928c97d 100644
--- a/src/qt/res/src/connect-1.svg
+++ b/src/qt/res/src/connect-1.svg
@@ -1,21 +1,69 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
-<g>
- <path d="M12,11c1.9,0,3.6,0.7,4.9,2c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C14.6,13.5,13.3,13,12,13
- c-1.3,0-2.6,0.5-3.5,1.5c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C8.4,11.7,10.1,11,12,11 M12,17
- c0.3,0,0.5,0.1,0.7,0.3c0.2,0.2,0.3,0.4,0.3,0.7s-0.1,0.5-0.3,0.7C12.5,18.9,12.3,19,12,19c-0.3,0-0.5-0.1-0.7-0.3
- C11.1,18.5,11,18.3,11,18c0-0.3,0.1-0.5,0.3-0.7C11.5,17.1,11.7,17,12,17 M12,10c-2,0-4.1,0.8-5.7,2.3c-0.8,0.8-0.8,2,0,2.8
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C10,14.4,11,14,12,14c1,0,2,0.4,2.8,1.2c0.4,0.4,0.9,0.6,1.4,0.6s1-0.2,1.4-0.6
- c0.8-0.8,0.8-2,0-2.8C16.1,10.8,14,10,12,10L12,10z M12,16c-0.5,0-1,0.2-1.4,0.6c-0.8,0.8-0.8,2.1,0,2.8C11,19.8,11.5,20,12,20
- c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C13,16.2,12.5,16,12,16L12,16z"/>
-</g>
-<g>
- <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7
- c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4
- C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.2"
+ width="24"
+ height="24"
+ viewBox="0 0 24 24"
+ id="svg2">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <g
+ id="g4210"
+ transform="translate(0,0.25)">
+ <g
+ id="g4142"
+ transform="matrix(0,-1,-1,0,23.96,23.75)">
+ <g
+ id="g4213"
+ transform="matrix(-1,0,0,1,59.86,-106.6)">
+ <g
+ id="g4289"
+ transform="matrix(-1,0,0,1,-16.98,0.8136)">
+ <g
+ id="g4291">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m -65.35,116.3 0,3 0.5,0 c 0.54,0 1,0.5 1,1 l 0,2.6 c -1.15,0.5 -2,1.6 -2,3 0,2 1.59,3.5 3.5,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-2.3 -1.81,-4 -4,-4 z m 1,1.2 c 1.39,0.3 2.5,1.3 2.5,2.8 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.5,-1.1 -2.5,-2.5 0,-1.1 0.69,-2 1.66,-2.3 l 0.34,-0.1 0,-3.2 c 0,-0.9 -0.67,-1.5 -1.5,-1.8 z"
+ id="path4293" />
+ <g
+ id="g4295">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m -67.35,106.1 c -1.94,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,2.2 1.79,4 4,4 l 0.5,0 0,-0.5 0,-2.5 -0.5,0 c -0.55,0 -1,-0.5 -1,-1 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.57,-3.5 -3.5,-3.5 z m 0,1 c 1.37,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,0.9 0.67,1.5 1.5,1.8 l 0,1 c -1.38,-0.3 -2.5,-1.4 -2.5,-2.8 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.12,-2.5 2.5,-2.5 z"
+ id="path4297" />
+ <path
+ id="path4145"
+ d="m -57.35,106 c -1.99,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,0.5 -0.41,0.9 -0.9,0.9 l -4.35,0 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 l 4.35,0 c 2.26,0 4.1,-1.9 4.1,-4.1 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.6,-3.6 -3.6,-3.6 z"
+ style="" />
+ </g>
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m -69.84,116.3 c -2.19,0 -4,1.7 -4,4 l 0,2.6 c -1.14,0.6 -1.99,1.6 -1.99,3 0,2 1.6,3.5 3.51,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-0.5 0.45,-1 1,-1 l 5.01,0 -3.34,-3 z m 0,1 2.02,0 2.01,1 -4.01,0 c -1.11,0 -2,0.9 -2,2 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.51,-1.1 -2.51,-2.5 0,-1.1 0.7,-2 1.66,-2.3 l 0.33,-0.1 0,-0.4 0,-2.8 c 0,-1.7 1.33,-3 3,-3 z"
+ id="path4301" />
+ </g>
+ </g>
+ </g>
+ <path
+ id="path4173"
+ d="m 12,8.764 c -0.84,0 -1.67,0.336 -2.264,0.931 a 0.6001,0.6001 0 0 0 -0,0 C 9.138,10.29 8.802,11.11 8.801,11.96 c 0,0.85 0.337,1.67 0.933,2.26 a 0.6001,0.6001 0 0 0 0,0 c 0.594,0.6 1.424,0.94 2.264,0.94 0.84,0 1.67,-0.34 2.26,-0.94 0.6,-0.59 0.94,-1.41 0.94,-2.26 0,-0.84 -0.34,-1.67 -0.94,-2.265 C 13.67,9.1 12.84,8.764 12,8.764 Z"
+ style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ </g>
+</svg>
diff --git a/src/qt/res/src/connect-2.svg b/src/qt/res/src/connect-2.svg
index d5becc52b7..841ca6071d 100644
--- a/src/qt/res/src/connect-2.svg
+++ b/src/qt/res/src/connect-2.svg
@@ -1,22 +1,59 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
-<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z"/>
-<g>
- <path d="M12,11c1.9,0,3.6,0.7,4.9,2c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C14.6,13.5,13.3,13,12,13
- c-1.3,0-2.6,0.5-3.5,1.5c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C8.4,11.7,10.1,11,12,11 M12,17
- c0.3,0,0.5,0.1,0.7,0.3c0.2,0.2,0.3,0.4,0.3,0.7s-0.1,0.5-0.3,0.7C12.5,18.9,12.3,19,12,19c-0.3,0-0.5-0.1-0.7-0.3
- C11.1,18.5,11,18.3,11,18c0-0.3,0.1-0.5,0.3-0.7C11.5,17.1,11.7,17,12,17 M12,10c-2,0-4.1,0.8-5.7,2.3c-0.8,0.8-0.8,2,0,2.8
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C10,14.4,11,14,12,14c1,0,2,0.4,2.8,1.2c0.4,0.4,0.9,0.6,1.4,0.6s1-0.2,1.4-0.6
- c0.8-0.8,0.8-2,0-2.8C16.1,10.8,14,10,12,10L12,10z M12,16c-0.5,0-1,0.2-1.4,0.6c-0.8,0.8-0.8,2.1,0,2.8C11,19.8,11.5,20,12,20
- c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C13,16.2,12.5,16,12,16L12,16z"/>
-</g>
-<g>
- <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7
- c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4
- C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.2"
+ width="24"
+ height="24"
+ viewBox="0 0 24 24"
+ id="svg2">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <g
+ id="g4210"
+ transform="matrix(0,1,-1,0,130.6,-35.86)">
+ <g
+ id="g4289"
+ transform="matrix(-1,0,0,1,-16.98,0.8136)">
+ <g
+ id="g4291">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m -65.35,116.3 0,3 0.5,0 c 0.54,0 1,0.5 1,1 l 0,2.6 c -1.15,0.5 -2,1.6 -2,3 0,2 1.59,3.5 3.5,3.5 1.91,0 3.5,-1.5 3.5,-3.5 0,-1.4 -0.85,-2.5 -2,-3 l 0,-2.6 c 0,-2.3 -1.81,-4 -4,-4 z m 1,1.2 c 1.39,0.3 2.5,1.3 2.5,2.8 l 0,3.2 0.34,0.1 c 0.96,0.3 1.66,1.2 1.66,2.3 0,1.4 -1.11,2.5 -2.5,2.5 -1.39,0 -2.5,-1.1 -2.5,-2.5 0,-1.1 0.69,-2 1.66,-2.3 l 0.34,-0.1 0,-3.2 c 0,-0.9 -0.67,-1.5 -1.5,-1.8 z"
+ id="path4293" />
+ <g
+ id="g4295">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m -67.35,106.1 c -1.94,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,2.2 1.79,4 4,4 l 0.5,0 0,-0.5 0,-2.5 -0.5,0 c -0.55,0 -1,-0.5 -1,-1 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.57,-3.5 -3.5,-3.5 z m 0,1 c 1.37,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,0.9 0.67,1.5 1.5,1.8 l 0,1 c -1.38,-0.3 -2.5,-1.4 -2.5,-2.8 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.12,-2.5 2.5,-2.5 z"
+ id="path4297" />
+ <path
+ id="path4142"
+ d="m -57.35,106 c -1.99,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,0.5 -0.41,0.9 -0.9,0.9 l -4.35,0 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 l 4.35,0 c 2.26,0 4.1,-1.9 4.1,-4.1 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.6,-3.6 -3.6,-3.6 z" />
+ </g>
+ <path
+ id="path4148"
+ d="m -69.84,116.2 c -2.24,0 -4.1,1.8 -4.1,4.1 l 0,2.5 c -1.17,0.5 -1.99,1.7 -1.99,3.1 0,2 1.64,3.6 3.61,3.6 1.96,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-0.5 0.41,-0.9 0.9,-0.9 l 4.51,0 a 0.6001,0.6001 0 0 0 0.6,-0.6 l 0,-2 a 0.6001,0.6001 0 0 0 -0.6,-0.6 l -4.53,0 z" />
+ </g>
+ </g>
+ <path
+ id="path4170"
+ d="m 47.86,115.4 c -0.84,0 -1.65,0.4 -2.24,1 -0.64,0.5 -0.96,1.3 -0.96,2.2 0,0.9 0.32,1.7 0.96,2.2 0.59,0.6 1.4,1 2.24,1 0.84,0 1.65,-0.4 2.24,-1 0.64,-0.5 0.96,-1.3 0.96,-2.2 0,-0.9 -0.32,-1.7 -0.96,-2.2 -0.59,-0.6 -1.4,-1 -2.24,-1 z"
+ style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+</svg>
diff --git a/src/qt/res/src/connect-3.svg b/src/qt/res/src/connect-3.svg
index 9bfa04721f..b06e67daf8 100644
--- a/src/qt/res/src/connect-3.svg
+++ b/src/qt/res/src/connect-3.svg
@@ -1,16 +1,72 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
-<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z"/>
-<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z M7.8,15.8
- c-0.5,0-1-0.2-1.4-0.6c-0.8-0.8-0.8-2,0-2.8c3.1-3.1,8.2-3.1,11.3,0c0.8,0.8,0.8,2,0,2.8c-0.8,0.8-2,0.8-2.8,0
- c-1.6-1.6-4.1-1.6-5.7,0C8.8,15.6,8.3,15.8,7.8,15.8z"/>
-<g>
- <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7
- c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4
- C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9
- c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ id="svg2"
+ viewBox="0 0 24 24"
+ height="24"
+ width="24"
+ version="1.2">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <g
+ transform="translate(0.2636,0.29)"
+ id="g4160">
+ <g
+ id="g4210"
+ transform="matrix(0,1,-1,0,130.3,-36.15)">
+ <g
+ id="g4289"
+ transform="matrix(-1,0,0,1,-16.98,0.8136)">
+ <g
+ id="g4291">
+ <path
+ id="path4147"
+ d="m -64.85,116.2 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 c 0.48,0 0.9,0.4 0.9,0.9 l 0,2.4 c -1.18,0.6 -2,1.8 -2,3.2 0,2 1.64,3.6 3.6,3.6 1.97,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-2.3 -1.86,-4.1 -4.1,-4.1 z"
+ style="" />
+ <g
+ id="g4295">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m -67.35,106.1 c -1.94,0 -3.5,1.6 -3.5,3.5 0,1.4 0.85,2.5 2,3 l 0,2.7 c 0,2.2 1.79,4 4,4 l 0.5,0 0,-0.5 0,-2.5 -0.5,0 c -0.55,0 -1,-0.5 -1,-1 l 0,-2.7 c 1.15,-0.5 2,-1.6 2,-3 0,-1.9 -1.57,-3.5 -3.5,-3.5 z m 0,1 c 1.37,0 2.5,1.2 2.5,2.5 0,1.1 -0.7,2 -1.66,2.3 l -0.34,0.1 0,3.3 c 0,0.9 0.67,1.5 1.5,1.8 l 0,1 c -1.38,-0.3 -2.5,-1.4 -2.5,-2.8 l 0,-3.3 -0.34,-0.1 c -0.96,-0.3 -1.66,-1.2 -1.66,-2.3 0,-1.3 1.12,-2.5 2.5,-2.5 z"
+ id="path4297" />
+ <path
+ id="path4145"
+ d="m -57.35,106 c -1.99,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,0.5 -0.41,0.9 -0.9,0.9 l -4.35,0 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 l 4.35,0 c 2.26,0 4.1,-1.9 4.1,-4.1 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.6,-3.6 -3.6,-3.6 z"
+ style="" />
+ </g>
+ <path
+ id="path4149"
+ d="m -69.84,116.2 c -2.24,0 -4.1,1.8 -4.1,4.1 l 0,2.5 c -1.17,0.5 -1.99,1.7 -1.99,3.1 0,2 1.64,3.6 3.61,3.6 1.96,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-0.5 0.41,-0.9 0.9,-0.9 l 4.51,0 a 0.6001,0.6001 0 0 0 0.6,-0.6 l 0,-2 a 0.6001,0.6001 0 0 0 -0.6,-0.6 l -4.53,0 z"
+ style="" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="matrix(0,1,1,0,-106.3,-36.15)"
+ id="g4142">
+ <g
+ transform="matrix(-1,0,0,1,-16.98,0.8136)"
+ id="g4144" />
+ </g>
+ </g>
+ <path
+ id="path4170"
+ d="m 15.2,12 c 0,-0.84 -0.4,-1.65 -1,-2.242 -0.5,-0.64 -1.3,-0.96 -2.2,-0.96 -0.9,0 -1.7,0.32 -2.2,0.96 -0.6,0.592 -1,1.402 -1,2.242 0,0.84 0.4,1.65 1,2.24 0.5,0.64 1.3,0.96 2.2,0.96 0.9,0 1.7,-0.32 2.2,-0.96 0.6,-0.59 1,-1.4 1,-2.24 z"
+ style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+</svg>
diff --git a/src/qt/res/src/connect-4.svg b/src/qt/res/src/connect-4.svg
new file mode 100644
index 0000000000..0abc7955fd
--- /dev/null
+++ b/src/qt/res/src/connect-4.svg
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.2"
+ width="24"
+ height="24"
+ viewBox="0 0 24 24"
+ id="svg2">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <g
+ id="g4142"
+ transform="matrix(0,-1,-1,0,23.96,24)">
+ <g
+ transform="matrix(-1,0,0,1,59.86,-106.6)"
+ id="g4210">
+ <g
+ transform="matrix(-1,0,0,1,-16.98,0.8136)"
+ id="g4289">
+ <g
+ id="g4291">
+ <path
+ id="path4153"
+ d="m -64.85,116.2 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 c 0.48,0 0.9,0.4 0.9,0.9 l 0,2.4 c -1.18,0.6 -2,1.8 -2,3.2 0,2 1.64,3.6 3.6,3.6 1.97,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-2.3 -1.86,-4.1 -4.1,-4.1 z"
+ style="" />
+ <g
+ id="g4295">
+ <path
+ id="path4149"
+ d="m -67.35,106 c -2,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,2.2 1.84,4.1 4.1,4.1 a 0.6001,0.6001 0 0 0 0.6,-0.6 l 0,-2 a 0.6001,0.6001 0 0 0 -0.6,-0.6 c -0.49,0 -0.9,-0.4 -0.9,-0.9 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.61,-3.6 -3.6,-3.6 z"
+ style="" />
+ <path
+ id="path4147"
+ d="m -57.35,106 c -1.99,0 -3.6,1.7 -3.6,3.6 0,1.4 0.83,2.6 2,3.2 l 0,2.5 c 0,0.5 -0.41,0.9 -0.9,0.9 l -4.35,0 a 0.6001,0.6001 0 0 0 -0.6,0.6 l 0,2 a 0.6001,0.6001 0 0 0 0.6,0.6 l 4.35,0 c 2.26,0 4.1,-1.9 4.1,-4.1 l 0,-2.5 c 1.17,-0.6 2,-1.8 2,-3.2 0,-1.9 -1.6,-3.6 -3.6,-3.6 z"
+ style="" />
+ </g>
+ <path
+ id="path4155"
+ d="m -69.84,116.2 c -2.24,0 -4.1,1.8 -4.1,4.1 l 0,2.5 c -1.17,0.5 -1.99,1.7 -1.99,3.1 0,2 1.64,3.6 3.61,3.6 1.96,0 3.6,-1.6 3.6,-3.6 0,-1.4 -0.83,-2.6 -2,-3.2 l 0,-2.4 c 0,-0.5 0.41,-0.9 0.9,-0.9 l 4.51,0 a 0.6001,0.6001 0 0 0 0.6,-0.6 l 0,-2 a 0.6001,0.6001 0 0 0 -0.6,-0.6 l -4.53,0 z"
+ style="" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <path
+ id="path4170"
+ d="m 15.2,12 c 0,-0.84 -0.4,-1.65 -1,-2.24 C 13.7,9.12 12.9,8.8 12,8.8 c -0.9,0 -1.7,0.32 -2.2,0.96 -0.6,0.59 -1,1.4 -1,2.24 0,0.84 0.4,1.65 1,2.24 0.5,0.64 1.3,0.96 2.2,0.96 0.9,0 1.7,-0.32 2.2,-0.96 0.6,-0.59 1,-1.4 1,-2.24 z"
+ style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+</svg>
diff --git a/src/qt/res/src/qt.svg b/src/qt/res/src/qt.svg
index 9ef54f493c..373c91f0c6 100644
--- a/src/qt/res/src/qt.svg
+++ b/src/qt/res/src/qt.svg
@@ -1,25 +1,26 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- viewBox="0 0 841.9 595.3" enable-background="new 0 0 841.9 595.3" xml:space="preserve">
-<g>
- <path d="M182.8,310c0-74.4,0-148.8,0-220.7c0-19.8,5-39.7,19.8-54.6c12.4-12.4,27.3-17.4,44.6-19.8c37.2-5,74.4,2.5,109.1,7.4
- C428.4,34.7,497.8,44.6,569.8,57c27.3,5,57,9.9,84.3,12.4c7.4,0,5,5,5,9.9c0,91.8,0,181.1,0,272.8c0,32.2,0,64.5,0,99.2
- c0,14.9-5,29.8-12.4,44.6c-9.9,14.9-22.3,22.3-39.7,27.3c-69.4,12.4-138.9,22.3-208.3,34.7c-57,9.9-114.1,19.8-171.1,29.8
- c-2.5,0-5,0-7.4-2.5c-12.4-14.9-22.3-24.8-32.2-34.7c-2.5-2.5-2.5-7.4-2.5-9.9c0-71.9,0-143.9,0-215.8
- C182.8,320,182.8,315,182.8,310z M430.9,436.5c9.9-7.4,19.8-12.4,29.8-19.8c14.9-14.9,24.8-32.2,29.8-54.6
- c12.4-54.6,14.9-111.6,0-166.2c-12.4-47.1-42.2-74.4-84.3-79.4c-37.2-2.5-67,7.4-86.8,39.7c-7.4,14.9-12.4,29.8-14.9,44.6
- c-9.9,39.7-9.9,81.9-5,121.5c2.5,22.3,7.4,44.6,17.4,67c12.4,24.8,29.8,42.2,54.6,49.6c2.5,0,5,2.5,5,5c5,12.4,7.4,22.3,12.4,34.7
- s17.4,19.8,32.2,22.3c14.9,2.5,27.3,2.5,42.2,0c2.5,0,2.5-2.5,2.5-2.5c0-9.9,0-22.3,0-32.2C438.3,461.3,433.3,456.4,430.9,436.5z
- M505.3,191c0,12.4,0,22.3,0,34.7c0,2.5,2.5,2.5,5,2.5c5,0,7.4,0,12.4,0c0,2.5,0,5,0,9.9c0,44.6,0,86.8,0,131.5
- c0,7.4,0,17.4,2.5,24.8c2.5,12.4,12.4,22.3,24.8,24.8c19.8,5,37.2-2.5,54.6-9.9l2.5-2.5c0-9.9,0-19.8,0-29.8
- c-7.4,2.5-14.9,5-22.3,5s-12.4-2.5-14.9-9.9c0-5-2.5-9.9-2.5-14.9c0-39.7,0-79.4,0-119.1c0-2.5,0-5,0-7.4c9.9,0,19.8,0,29.8,2.5
- c5,0,7.4-2.5,7.4-7.4c0-7.4,0-14.9,0-22.3c0-5-2.5-7.4-7.4-7.4c-7.4,0-14.9-2.5-22.3-2.5c-5,0-7.4-2.5-7.4-7.4
- c0-14.9,0-29.8,0-42.2c0-5-2.5-5-5-7.4c-5,0-12.4,0-17.4-2.5s-7.4,0-9.9,7.4c-2.5,17.4-7.4,32.2-12.4,49.6
- C520.2,191,512.7,191,505.3,191z"/>
- <path d="M443.3,277.8c-2.5,27.3-5,57-9.9,84.3c0,7.4-5,17.4-9.9,24.8c-12.4,17.4-32.2,14.9-44.6-2.5c-9.9-14.9-12.4-32.2-14.9-49.6
- c-5-42.2-5-81.9,0-124c5-12.4,7.4-24.8,14.9-37.2c12.4-17.4,34.7-17.4,47.1-2.5c2.5,5,7.4,9.9,7.4,14.9c2.5,9.9,5,19.8,7.4,32.2
- c2.5,9.9,2.5,22.3,2.5,34.7C440.8,260.4,440.8,270.4,443.3,277.8L443.3,277.8z"/>
-</g>
-</svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ id="Ebene_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 609.4 609.4"
+ enable-background="new 0 0 841.9 595.3"
+ xml:space="preserve"
+ width="609.4"
+ height="609.4"><metadata
+ id="metadata13"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs11" /><g
+ id="g4151"
+ transform="matrix(2.553,0,0,2.553,-2149,281.5)"><path
+ id="path26"
+ transform="matrix(0.3917,0,0,0.3917,841.8,-110.3)"
+ d="M 153.7 16.9 C 115 16.44 69.7 31.67 67.96 86.81 L 67.96 550.7 L 105 592.4 L 495.9 526.7 C 521.4 522.1 541.9 490.2 541.9 455.9 L 541.9 77.77 L 183.4 18.97 C 179.4 18.3 161.4 17 157.5 16.99 C 156.2 16.94 155 16.91 153.7 16.9 z M 273.5 124.1 C 278.1 124.1 282.7 124.3 287.3 124.9 L 287.3 125 C 320 128.8 343.7 144.2 359.3 170.9 C 374.6 197.1 382 234.6 382 284 C 382 329.2 376.4 364.7 365.4 390.7 C 354.2 417.2 337.1 434.6 313.4 442.8 C 315.9 455 319.5 463.2 324.1 467.5 C 326.9 469.8 330.7 471.4 335.3 471.9 L 335.6 471.9 L 336.3 471.9 L 341.5 471.9 C 343.5 471.9 344.5 472.4 348.3 471.9 L 348.3 507.9 L 332 510.2 C 327.2 510.7 322.6 510.9 318.2 510.9 C 303.9 510.9 292.4 507.6 283.5 500.5 C 272 491.3 263.6 473.4 258.2 447.1 C 233.2 441.8 213.5 425.9 200 399.1 C 186.5 372.1 179.3 332.2 179.3 280.4 C 179.3 224.5 189 183.2 207.7 157 C 223.8 134.9 245.7 124.1 273.5 124.1 z M 424.4 143.5 L 455.1 146.9 L 455.1 202.2 L 488.2 204.8 L 488.2 239.5 L 455.1 237.8 L 455.1 364.7 C 455.1 375.6 457.6 382.8 460.2 386.1 C 460.2 388.9 465.3 390.4 467.8 390.4 L 470.4 390.4 C 478 389.9 485.7 387.9 493.4 384.1 L 493.4 415.7 C 478 422.1 465.3 425.7 450 426.9 C 450 427.2 447.4 427.2 444.8 427.2 C 432.1 427.2 424.4 423.6 416.8 416.5 C 409.1 408.1 404 394.5 404 376.1 L 404 235.6 L 390.2 234.8 L 390.2 197.6 L 411.7 199.1 L 424.4 143.5 z M 284.5 166.4 C 272.5 166.4 263.3 173.3 256.9 187.3 C 250.1 202.5 246.7 233.9 246.7 281.7 C 246.7 327.6 250.1 360.3 256.9 379.5 C 263.3 397.8 273 406.8 285.8 406.8 L 287.3 406.8 C 300.1 406 309.5 397.1 316.2 380.5 C 322.6 363.9 325.6 331.5 325.6 283 C 325.6 239.4 322.6 209.5 316.2 193 C 309.8 176.4 300.1 167.5 287.3 166.4 L 284.5 166.4 z "
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></svg> \ No newline at end of file
diff --git a/src/qt/res/spinner.png b/src/qt/res/src/spinner.png
index b296a58481..b296a58481 100644
--- a/src/qt/res/spinner.png
+++ b/src/qt/res/src/spinner.png
Binary files differ
diff --git a/src/qt/res/src/transaction0.svg b/src/qt/res/src/transaction0.svg
new file mode 100644
index 0000000000..e7fcd8214c
--- /dev/null
+++ b/src/qt/res/src/transaction0.svg
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ id="svg4142"
+ viewBox="0 0 128 127.9"
+ height="36.12mm"
+ width="36.12mm">
+ <defs
+ id="defs4144" />
+ <metadata
+ id="metadata4147">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ transform="translate(-284.4,-501.6)">
+ <path
+ id="path4792"
+ d="m 348.8,513.8 c -12.7,-0.7 -24.9,9.1 -27,21.7 -3.8,8.8 7.2,13.7 13.7,9.2 3.1,-7.5 9.4,-17.9 18.9,-11.6 9.7,6.1 2.1,17.6 -3,24.1 -6.1,7.8 -11.4,14.8 -8.9,23 5.4,17.7 10.8,3.7 12.8,-0.1 4.3,-8.2 6,-8.8 11.5,-16.1 6.4,-8.6 11.6,-19.9 7.7,-30.8 -2.8,-11.5 -13.9,-19.9 -25.7,-19.4 z m -0.7,84.7 c -11.4,2.4 -9.1,19.5 2.7,17.1 11.8,-2.4 8.7,-19.5 -2.7,-17.1 z"
+ style="fill:#000000" />
+ </g>
+</svg>
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 2fafb83d43..f387a3ec8c 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -3,14 +3,14 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "rpcconsole.h"
-#include "ui_rpcconsole.h"
+#include "ui_debugwindow.h"
+#include "bantablemodel.h"
#include "clientmodel.h"
#include "guiutil.h"
-#include "peertablemodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
+#include "bantablemodel.h"
-#include "main.h"
#include "chainparams.h"
#include "rpcserver.h"
#include "rpcclient.h"
@@ -18,7 +18,7 @@
#include <openssl/crypto.h>
-#include "univalue/univalue.h"
+#include <univalue.h>
#ifdef ENABLE_WALLET
#include <db_cxx.h>
@@ -27,8 +27,10 @@
#include <QKeyEvent>
#include <QMenu>
#include <QScrollBar>
+#include <QSignalMapper>
#include <QThread>
#include <QTime>
+#include <QTimer>
#if QT_VERSION < 0x050000
#include <QUrl>
@@ -67,6 +69,40 @@ Q_SIGNALS:
void reply(int category, const QString &command);
};
+/** Class for handling RPC timers
+ * (used for e.g. re-locking the wallet after a timeout)
+ */
+class QtRPCTimerBase: public QObject, public RPCTimerBase
+{
+ Q_OBJECT
+public:
+ QtRPCTimerBase(boost::function<void(void)>& func, int64_t millis):
+ func(func)
+ {
+ timer.setSingleShot(true);
+ connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
+ timer.start(millis);
+ }
+ ~QtRPCTimerBase() {}
+private Q_SLOTS:
+ void timeout() { func(); }
+private:
+ QTimer timer;
+ boost::function<void(void)> func;
+};
+
+class QtRPCTimerInterface: public RPCTimerInterface
+{
+public:
+ ~QtRPCTimerInterface() {}
+ const char *Name() { return "Qt"; }
+ RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis)
+ {
+ return new QtRPCTimerBase(func, millis);
+ }
+};
+
+
#include "rpcconsole.moc"
/**
@@ -201,21 +237,23 @@ void RPCExecutor::request(const QString &command)
}
}
-RPCConsole::RPCConsole(QWidget *parent) :
+RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) :
QWidget(parent),
ui(new Ui::RPCConsole),
clientModel(0),
historyPtr(0),
cachedNodeid(-1),
- contextMenu(0)
+ platformStyle(platformStyle),
+ peersTableContextMenu(0),
+ banTableContextMenu(0)
{
ui->setupUi(this);
GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this);
-#ifndef Q_OS_MAC
- ui->openDebugLogfileButton->setIcon(SingleColorIcon(":/icons/export"));
-#endif
- ui->clearButton->setIcon(SingleColorIcon(":/icons/remove"));
+ if (platformStyle->getImagesOnButtons()) {
+ ui->openDebugLogfileButton->setIcon(platformStyle->SingleColorIcon(":/icons/export"));
+ }
+ ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
// Install event filter for up and down arrow
ui->lineEdit->installEventFilter(this);
@@ -232,6 +270,9 @@ RPCConsole::RPCConsole(QWidget *parent) :
ui->label_berkeleyDBVersion->hide();
ui->berkeleyDBVersion->hide();
#endif
+ // Register RPC timer interface
+ rpcTimerInterface = new QtRPCTimerInterface();
+ RPCRegisterTimerInterface(rpcTimerInterface);
startExecutor();
setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS);
@@ -246,6 +287,8 @@ RPCConsole::~RPCConsole()
{
GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this);
Q_EMIT stopExecutor();
+ RPCUnregisterTimerInterface(rpcTimerInterface);
+ delete rpcTimerInterface;
delete ui;
}
@@ -289,8 +332,7 @@ void RPCConsole::setClientModel(ClientModel *model)
{
clientModel = model;
ui->trafficGraph->setClientModel(model);
- if(model)
- {
+ if (model && clientModel->getPeerTableModel() && clientModel->getBanTableModel()) {
// Keep up to date with client
setNumConnections(model->getNumConnections());
connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
@@ -311,29 +353,81 @@ void RPCConsole::setClientModel(ClientModel *model)
ui->peerWidget->setColumnWidth(PeerTableModel::Address, ADDRESS_COLUMN_WIDTH);
ui->peerWidget->setColumnWidth(PeerTableModel::Subversion, SUBVERSION_COLUMN_WIDTH);
ui->peerWidget->setColumnWidth(PeerTableModel::Ping, PING_COLUMN_WIDTH);
+ ui->peerWidget->horizontalHeader()->setStretchLastSection(true);
- // create context menu actions
+ // create peer table context menu actions
QAction* disconnectAction = new QAction(tr("&Disconnect Node"), this);
-
- // create context menu
- contextMenu = new QMenu();
- contextMenu->addAction(disconnectAction);
-
- // context menu signals
- connect(ui->peerWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showMenu(const QPoint&)));
+ QAction* banAction1h = new QAction(tr("Ban Node for") + " " + tr("1 &hour"), this);
+ QAction* banAction24h = new QAction(tr("Ban Node for") + " " + tr("1 &day"), this);
+ QAction* banAction7d = new QAction(tr("Ban Node for") + " " + tr("1 &week"), this);
+ QAction* banAction365d = new QAction(tr("Ban Node for") + " " + tr("1 &year"), this);
+
+ // create peer table context menu
+ peersTableContextMenu = new QMenu();
+ peersTableContextMenu->addAction(disconnectAction);
+ peersTableContextMenu->addAction(banAction1h);
+ peersTableContextMenu->addAction(banAction24h);
+ peersTableContextMenu->addAction(banAction7d);
+ peersTableContextMenu->addAction(banAction365d);
+
+ // Add a signal mapping to allow dynamic context menu arguments.
+ // We need to use int (instead of int64_t), because signal mapper only supports
+ // int or objects, which is okay because max bantime (1 year) is < int_max.
+ QSignalMapper* signalMapper = new QSignalMapper(this);
+ signalMapper->setMapping(banAction1h, 60*60);
+ signalMapper->setMapping(banAction24h, 60*60*24);
+ signalMapper->setMapping(banAction7d, 60*60*24*7);
+ signalMapper->setMapping(banAction365d, 60*60*24*365);
+ connect(banAction1h, SIGNAL(triggered()), signalMapper, SLOT(map()));
+ connect(banAction24h, SIGNAL(triggered()), signalMapper, SLOT(map()));
+ connect(banAction7d, SIGNAL(triggered()), signalMapper, SLOT(map()));
+ connect(banAction365d, SIGNAL(triggered()), signalMapper, SLOT(map()));
+ connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(banSelectedNode(int)));
+
+ // peer table context menu signals
+ connect(ui->peerWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showPeersTableContextMenu(const QPoint&)));
connect(disconnectAction, SIGNAL(triggered()), this, SLOT(disconnectSelectedNode()));
- // connect the peerWidget selection model to our peerSelected() handler
+ // peer table signal handling - update peer details when selecting new node
connect(ui->peerWidget->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
- this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &)));
+ this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &)));
+ // peer table signal handling - update peer details when new nodes are added to the model
connect(model->getPeerTableModel(), SIGNAL(layoutChanged()), this, SLOT(peerLayoutChanged()));
+ // set up ban table
+ ui->banlistWidget->setModel(model->getBanTableModel());
+ ui->banlistWidget->verticalHeader()->hide();
+ ui->banlistWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ ui->banlistWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
+ ui->banlistWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+ ui->banlistWidget->setContextMenuPolicy(Qt::CustomContextMenu);
+ ui->banlistWidget->setColumnWidth(BanTableModel::Address, BANSUBNET_COLUMN_WIDTH);
+ ui->banlistWidget->setColumnWidth(BanTableModel::Bantime, BANTIME_COLUMN_WIDTH);
+ ui->banlistWidget->horizontalHeader()->setStretchLastSection(true);
+
+ // create ban table context menu action
+ QAction* unbanAction = new QAction(tr("&Unban Node"), this);
+
+ // create ban table context menu
+ banTableContextMenu = new QMenu();
+ banTableContextMenu->addAction(unbanAction);
+
+ // ban table context menu signals
+ connect(ui->banlistWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showBanTableContextMenu(const QPoint&)));
+ connect(unbanAction, SIGNAL(triggered()), this, SLOT(unbanSelectedNode()));
+
+ // ban table signal handling - clear peer details when clicking a peer in the ban table
+ connect(ui->banlistWidget, SIGNAL(clicked(const QModelIndex&)), this, SLOT(clearSelectedNode()));
+ // ban table signal handling - ensure ban table is shown or hidden (if empty)
+ connect(model->getBanTableModel(), SIGNAL(layoutChanged()), this, SLOT(showOrHideBanTableIfRequired()));
+ showOrHideBanTableIfRequired();
+
// Provide initial values
ui->clientVersion->setText(model->formatFullVersion());
+ ui->clientUserAgent->setText(model->formatSubVersion());
ui->clientName->setText(model->clientName());
ui->buildDate->setText(model->formatBuildDate());
ui->startupTime->setText(model->formatClientStartupTime());
-
ui->networkName->setText(QString::fromStdString(Params().NetworkIDString()));
}
}
@@ -364,7 +458,7 @@ void RPCConsole::clear()
ui->messagesWidget->document()->addResource(
QTextDocument::ImageResource,
QUrl(ICON_MAPPING[i].url),
- SingleColorImage(ICON_MAPPING[i].source, SingleColor()).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ platformStyle->SingleColorImage(ICON_MAPPING[i].source).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
}
// Set default style sheet
@@ -537,7 +631,7 @@ void RPCConsole::peerSelected(const QItemSelection &selected, const QItemSelecti
{
Q_UNUSED(deselected);
- if (!clientModel || selected.indexes().isEmpty())
+ if (!clientModel || !clientModel->getPeerTableModel() || selected.indexes().isEmpty())
return;
const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(selected.indexes().first().row());
@@ -547,7 +641,7 @@ void RPCConsole::peerSelected(const QItemSelection &selected, const QItemSelecti
void RPCConsole::peerLayoutChanged()
{
- if (!clientModel)
+ if (!clientModel || !clientModel->getPeerTableModel())
return;
const CNodeCombinedStats *stats = NULL;
@@ -570,7 +664,7 @@ void RPCConsole::peerLayoutChanged()
if (detailNodeRow < 0)
{
- // detail node dissapeared from table (node disconnected)
+ // detail node disappeared from table (node disconnected)
fUnselect = true;
}
else
@@ -656,7 +750,7 @@ void RPCConsole::showEvent(QShowEvent *event)
{
QWidget::showEvent(event);
- if (!clientModel)
+ if (!clientModel || !clientModel->getPeerTableModel())
return;
// start PeerTableModel auto refresh
@@ -667,18 +761,25 @@ void RPCConsole::hideEvent(QHideEvent *event)
{
QWidget::hideEvent(event);
- if (!clientModel)
+ if (!clientModel || !clientModel->getPeerTableModel())
return;
// stop PeerTableModel auto refresh
clientModel->getPeerTableModel()->stopAutoRefresh();
}
-void RPCConsole::showMenu(const QPoint& point)
+void RPCConsole::showPeersTableContextMenu(const QPoint& point)
{
QModelIndex index = ui->peerWidget->indexAt(point);
if (index.isValid())
- contextMenu->exec(QCursor::pos());
+ peersTableContextMenu->exec(QCursor::pos());
+}
+
+void RPCConsole::showBanTableContextMenu(const QPoint& point)
+{
+ QModelIndex index = ui->banlistWidget->indexAt(point);
+ if (index.isValid())
+ banTableContextMenu->exec(QCursor::pos());
}
void RPCConsole::disconnectSelectedNode()
@@ -692,6 +793,46 @@ void RPCConsole::disconnectSelectedNode()
}
}
+void RPCConsole::banSelectedNode(int bantime)
+{
+ if (!clientModel)
+ return;
+
+ // Get currently selected peer address
+ QString strNode = GUIUtil::getEntryData(ui->peerWidget, 0, PeerTableModel::Address);
+ // Find possible nodes, ban it and clear the selected node
+ if (CNode *bannedNode = FindNode(strNode.toStdString())) {
+ std::string nStr = strNode.toStdString();
+ std::string addr;
+ int port = 0;
+ SplitHostPort(nStr, port, addr);
+
+ CNode::Ban(CNetAddr(addr), BanReasonManuallyAdded, bantime);
+ bannedNode->fDisconnect = true;
+ DumpBanlist();
+
+ clearSelectedNode();
+ clientModel->getBanTableModel()->refresh();
+ }
+}
+
+void RPCConsole::unbanSelectedNode()
+{
+ if (!clientModel)
+ return;
+
+ // Get currently selected ban address
+ QString strNode = GUIUtil::getEntryData(ui->banlistWidget, 0, BanTableModel::Address);
+ CSubNet possibleSubnet(strNode.toStdString());
+
+ if (possibleSubnet.IsValid())
+ {
+ CNode::Unban(possibleSubnet);
+ DumpBanlist();
+ clientModel->getBanTableModel()->refresh();
+ }
+}
+
void RPCConsole::clearSelectedNode()
{
ui->peerWidget->selectionModel()->clearSelection();
@@ -699,3 +840,13 @@ void RPCConsole::clearSelectedNode()
ui->detailWidget->hide();
ui->peerHeading->setText(tr("Select a peer to view detailed information."));
}
+
+void RPCConsole::showOrHideBanTableIfRequired()
+{
+ if (!clientModel)
+ return;
+
+ bool visible = clientModel->getBanTableModel()->shouldShow();
+ ui->banlistWidget->setVisible(visible);
+ ui->banHeading->setVisible(visible);
+} \ No newline at end of file
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 6f42aa08b7..b86f776786 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -13,6 +13,8 @@
#include <QWidget>
class ClientModel;
+class PlatformStyle;
+class RPCTimerInterface;
namespace Ui {
class RPCConsole;
@@ -29,7 +31,7 @@ class RPCConsole: public QWidget
Q_OBJECT
public:
- explicit RPCConsole(QWidget *parent);
+ explicit RPCConsole(const PlatformStyle *platformStyle, QWidget *parent);
~RPCConsole();
void setClientModel(ClientModel *model);
@@ -59,7 +61,13 @@ private Q_SLOTS:
void showEvent(QShowEvent *event);
void hideEvent(QHideEvent *event);
/** Show custom context menu on Peers tab */
- void showMenu(const QPoint& point);
+ void showPeersTableContextMenu(const QPoint& point);
+ /** Show custom context menu on Bans tab */
+ void showBanTableContextMenu(const QPoint& point);
+ /** Hides ban table if no bans are present */
+ void showOrHideBanTableIfRequired();
+ /** clear the selected node */
+ void clearSelectedNode();
public Q_SLOTS:
void clear();
@@ -78,6 +86,10 @@ public Q_SLOTS:
void peerLayoutChanged();
/** Disconnect a selected node on the Peers tab */
void disconnectSelectedNode();
+ /** Ban a selected node on the Peers tab */
+ void banSelectedNode(int bantime);
+ /** Unban a selected node on the Bans tab */
+ void unbanSelectedNode();
Q_SIGNALS:
// For RPC command executor
@@ -90,14 +102,15 @@ private:
void setTrafficGraphRange(int mins);
/** show detailed information on ui about selected node */
void updateNodeDetail(const CNodeCombinedStats *stats);
- /** clear the selected node */
- void clearSelectedNode();
enum ColumnWidths
{
ADDRESS_COLUMN_WIDTH = 200,
SUBVERSION_COLUMN_WIDTH = 100,
- PING_COLUMN_WIDTH = 80
+ PING_COLUMN_WIDTH = 80,
+ BANSUBNET_COLUMN_WIDTH = 200,
+ BANTIME_COLUMN_WIDTH = 250
+
};
Ui::RPCConsole *ui;
@@ -105,7 +118,10 @@ private:
QStringList history;
int historyPtr;
NodeId cachedNodeid;
- QMenu *contextMenu;
+ const PlatformStyle *platformStyle;
+ RPCTimerInterface *rpcTimerInterface;
+ QMenu *peersTableContextMenu;
+ QMenu *banTableContextMenu;
};
#endif // BITCOIN_QT_RPCCONSOLE_H
diff --git a/src/qt/scicon.cpp b/src/qt/scicon.cpp
deleted file mode 100644
index c493b5569e..0000000000
--- a/src/qt/scicon.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#include "scicon.h"
-
-#include <QApplication>
-#include <QColor>
-#include <QIcon>
-#include <QImage>
-#include <QPalette>
-#include <QPixmap>
-
-namespace {
-
-void MakeSingleColorImage(QImage& img, const QColor& colorbase)
-{
- img = img.convertToFormat(QImage::Format_ARGB32);
- for (int x = img.width(); x--; )
- {
- for (int y = img.height(); y--; )
- {
- const QRgb rgb = img.pixel(x, y);
- img.setPixel(x, y, qRgba(colorbase.red(), colorbase.green(), colorbase.blue(), qAlpha(rgb)));
- }
- }
-}
-
-}
-
-QImage SingleColorImage(const QString& filename, const QColor& colorbase)
-{
- QImage img(filename);
-#if !defined(WIN32) && !defined(MAC_OSX)
- MakeSingleColorImage(img, colorbase);
-#endif
- return img;
-}
-
-QIcon SingleColorIcon(const QIcon& ico, const QColor& colorbase)
-{
-#if defined(WIN32) || defined(MAC_OSX)
- return ico;
-#else
- QIcon new_ico;
- QSize sz;
- Q_FOREACH(sz, ico.availableSizes())
- {
- QImage img(ico.pixmap(sz).toImage());
- MakeSingleColorImage(img, colorbase);
- new_ico.addPixmap(QPixmap::fromImage(img));
- }
- return new_ico;
-#endif
-}
-
-QIcon SingleColorIcon(const QString& filename, const QColor& colorbase)
-{
- return QIcon(QPixmap::fromImage(SingleColorImage(filename, colorbase)));
-}
-
-QColor SingleColor()
-{
-#if defined(WIN32) || defined(MAC_OSX)
- return QColor(0,0,0);
-#else
- const QColor colorHighlightBg(QApplication::palette().color(QPalette::Highlight));
- const QColor colorHighlightFg(QApplication::palette().color(QPalette::HighlightedText));
- const QColor colorText(QApplication::palette().color(QPalette::WindowText));
- const int colorTextLightness = colorText.lightness();
- QColor colorbase;
- if (abs(colorHighlightBg.lightness() - colorTextLightness) < abs(colorHighlightFg.lightness() - colorTextLightness))
- colorbase = colorHighlightBg;
- else
- colorbase = colorHighlightFg;
- return colorbase;
-#endif
-}
-
-QIcon SingleColorIcon(const QString& filename)
-{
- return SingleColorIcon(filename, SingleColor());
-}
-
-static QColor TextColor()
-{
- return QColor(QApplication::palette().color(QPalette::WindowText));
-}
-
-QIcon TextColorIcon(const QString& filename)
-{
- return SingleColorIcon(filename, TextColor());
-}
-
-QIcon TextColorIcon(const QIcon& ico)
-{
- return SingleColorIcon(ico, TextColor());
-}
diff --git a/src/qt/scicon.h b/src/qt/scicon.h
deleted file mode 100644
index 1388069ddb..0000000000
--- a/src/qt/scicon.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef BITCOIN_QT_SCICON_H
-#define BITCOIN_QT_SCICON_H
-
-#include <QtCore>
-
-QT_BEGIN_NAMESPACE
-class QColor;
-class QIcon;
-class QString;
-QT_END_NAMESPACE
-
-QImage SingleColorImage(const QString& filename, const QColor&);
-QIcon SingleColorIcon(const QIcon&, const QColor&);
-QIcon SingleColorIcon(const QString& filename, const QColor&);
-QColor SingleColor();
-QIcon SingleColorIcon(const QString& filename);
-QIcon TextColorIcon(const QIcon&);
-QIcon TextColorIcon(const QString& filename);
-
-#endif // BITCOIN_QT_SCICON_H
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index e13cd714a6..a083a6f80e 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -11,14 +11,15 @@
#include "coincontroldialog.h"
#include "guiutil.h"
#include "optionsmodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "sendcoinsentry.h"
#include "walletmodel.h"
#include "base58.h"
#include "coincontrol.h"
-#include "main.h"
+#include "main.h" // mempool and minRelayTxFee
#include "ui_interface.h"
+#include "txmempool.h"
#include "wallet/wallet.h"
#include <QMessageBox>
@@ -26,25 +27,26 @@
#include <QSettings>
#include <QTextDocument>
-SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
+SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) :
QDialog(parent),
ui(new Ui::SendCoinsDialog),
clientModel(0),
model(0),
fNewRecipientAllowed(true),
- fFeeMinimized(true)
+ fFeeMinimized(true),
+ platformStyle(platformStyle)
{
ui->setupUi(this);
-#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
- ui->addButton->setIcon(QIcon());
- ui->clearButton->setIcon(QIcon());
- ui->sendButton->setIcon(QIcon());
-#else
- ui->addButton->setIcon(SingleColorIcon(":/icons/add"));
- ui->clearButton->setIcon(SingleColorIcon(":/icons/remove"));
- ui->sendButton->setIcon(SingleColorIcon(":/icons/send"));
-#endif
+ if (!platformStyle->getImagesOnButtons()) {
+ ui->addButton->setIcon(QIcon());
+ ui->clearButton->setIcon(QIcon());
+ ui->sendButton->setIcon(QIcon());
+ } else {
+ ui->addButton->setIcon(platformStyle->SingleColorIcon(":/icons/add"));
+ ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->sendButton->setIcon(platformStyle->SingleColorIcon(":/icons/send"));
+ }
GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this);
@@ -310,9 +312,9 @@ void SendCoinsDialog::on_sendButton_clicked()
if(u != model->getOptionsModel()->getDisplayUnit())
alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount));
}
- questionString.append(tr("Total Amount %1 (= %2)")
+ questionString.append(tr("Total Amount %1<span style='font-size:10pt;font-weight:normal;'><br />(=%2)</span>")
.arg(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), totalAmount))
- .arg(alternativeUnits.join(" " + tr("or") + " ")));
+ .arg(alternativeUnits.join(" " + tr("or") + "<br />")));
QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"),
questionString.arg(formatted.join("<br />")),
@@ -363,7 +365,7 @@ void SendCoinsDialog::accept()
SendCoinsEntry *SendCoinsDialog::addEntry()
{
- SendCoinsEntry *entry = new SendCoinsEntry(this);
+ SendCoinsEntry *entry = new SendCoinsEntry(platformStyle, this);
entry->setModel(model);
ui->entries->addWidget(entry);
connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*)));
@@ -710,7 +712,7 @@ void SendCoinsDialog::coinControlFeatureChanged(bool checked)
// Coin Control: button inputs -> show actual coin control dialog
void SendCoinsDialog::coinControlButtonClicked()
{
- CoinControlDialog dlg;
+ CoinControlDialog dlg(platformStyle);
dlg.setModel(model);
dlg.exec();
coinControlUpdateLabels();
@@ -752,10 +754,9 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text)
}
else // Valid address
{
- CPubKey pubkey;
CKeyID keyid;
addr.GetKeyID(keyid);
- if (!model->getPubKey(keyid, pubkey)) // Unknown change address
+ if (!model->havePrivKey(keyid)) // Unknown change address
{
ui->labelCoinControlChangeLabel->setText(tr("Warning: Unknown change address"));
}
diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h
index c833da84b2..391905ffcd 100644
--- a/src/qt/sendcoinsdialog.h
+++ b/src/qt/sendcoinsdialog.h
@@ -12,6 +12,7 @@
class ClientModel;
class OptionsModel;
+class PlatformStyle;
class SendCoinsEntry;
class SendCoinsRecipient;
@@ -31,7 +32,7 @@ class SendCoinsDialog : public QDialog
Q_OBJECT
public:
- explicit SendCoinsDialog(QWidget *parent = 0);
+ explicit SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent = 0);
~SendCoinsDialog();
void setClientModel(ClientModel *clientModel);
@@ -60,6 +61,7 @@ private:
WalletModel *model;
bool fNewRecipientAllowed;
bool fFeeMinimized;
+ const PlatformStyle *platformStyle;
// Process WalletModel::SendCoinsReturn and generate a pair consisting
// of a message and message flags for use in Q_EMIT message().
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index 90a8cbdc4e..44aa8ad1af 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -9,30 +9,30 @@
#include "addresstablemodel.h"
#include "guiutil.h"
#include "optionsmodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "walletmodel.h"
#include <QApplication>
#include <QClipboard>
-SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
+SendCoinsEntry::SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *parent) :
QStackedWidget(parent),
ui(new Ui::SendCoinsEntry),
- model(0)
+ model(0),
+ platformStyle(platformStyle)
{
ui->setupUi(this);
- ui->addressBookButton->setIcon(SingleColorIcon(":/icons/address-book"));
- ui->pasteButton->setIcon(SingleColorIcon(":/icons/editpaste"));
- ui->deleteButton->setIcon(SingleColorIcon(":/icons/remove"));
- ui->deleteButton_is->setIcon(SingleColorIcon(":/icons/remove"));
- ui->deleteButton_s->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->addressBookButton->setIcon(platformStyle->SingleColorIcon(":/icons/address-book"));
+ ui->pasteButton->setIcon(platformStyle->SingleColorIcon(":/icons/editpaste"));
+ ui->deleteButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->deleteButton_is->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->deleteButton_s->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
setCurrentWidget(ui->SendCoins);
-#ifdef Q_OS_MAC
- ui->payToLayout->setSpacing(4);
-#endif
+ if (platformStyle->getUseExtraSpacing())
+ ui->payToLayout->setSpacing(4);
#if QT_VERSION >= 0x040700
ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book"));
#endif
@@ -65,7 +65,7 @@ void SendCoinsEntry::on_addressBookButton_clicked()
{
if(!model)
return;
- AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this);
+ AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::SendingTab, this);
dlg.setModel(model->getAddressTableModel());
if(dlg.exec())
{
diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h
index d7e655fdc3..107ab70158 100644
--- a/src/qt/sendcoinsentry.h
+++ b/src/qt/sendcoinsentry.h
@@ -10,6 +10,7 @@
#include <QStackedWidget>
class WalletModel;
+class PlatformStyle;
namespace Ui {
class SendCoinsEntry;
@@ -25,7 +26,7 @@ class SendCoinsEntry : public QStackedWidget
Q_OBJECT
public:
- explicit SendCoinsEntry(QWidget *parent = 0);
+ explicit SendCoinsEntry(const PlatformStyle *platformStyle, QWidget *parent = 0);
~SendCoinsEntry();
void setModel(WalletModel *model);
@@ -64,6 +65,7 @@ private:
SendCoinsRecipient recipient;
Ui::SendCoinsEntry *ui;
WalletModel *model;
+ const PlatformStyle *platformStyle;
bool updateLabel(const QString &address);
};
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index ce166f3672..60e8e36ebe 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -7,7 +7,7 @@
#include "addressbookpage.h"
#include "guiutil.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "walletmodel.h"
#include "base58.h"
@@ -20,21 +20,22 @@
#include <QClipboard>
-SignVerifyMessageDialog::SignVerifyMessageDialog(QWidget *parent) :
+SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent) :
QDialog(parent),
ui(new Ui::SignVerifyMessageDialog),
- model(0)
+ model(0),
+ platformStyle(platformStyle)
{
ui->setupUi(this);
- ui->addressBookButton_SM->setIcon(SingleColorIcon(":/icons/address-book"));
- ui->pasteButton_SM->setIcon(SingleColorIcon(":/icons/editpaste"));
- ui->copySignatureButton_SM->setIcon(SingleColorIcon(":/icons/editcopy"));
- ui->signMessageButton_SM->setIcon(SingleColorIcon(":/icons/edit"));
- ui->clearButton_SM->setIcon(SingleColorIcon(":/icons/remove"));
- ui->addressBookButton_VM->setIcon(SingleColorIcon(":/icons/address-book"));
- ui->verifyMessageButton_VM->setIcon(SingleColorIcon(":/icons/transaction_0"));
- ui->clearButton_VM->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->addressBookButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/address-book"));
+ ui->pasteButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/editpaste"));
+ ui->copySignatureButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/editcopy"));
+ ui->signMessageButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/edit"));
+ ui->clearButton_SM->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
+ ui->addressBookButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/address-book"));
+ ui->verifyMessageButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/transaction_0"));
+ ui->clearButton_VM->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
#if QT_VERSION >= 0x040700
ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature"));
@@ -94,7 +95,7 @@ void SignVerifyMessageDialog::on_addressBookButton_SM_clicked()
{
if (model && model->getAddressTableModel())
{
- AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
+ AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
dlg.setModel(model->getAddressTableModel());
if (dlg.exec())
{
@@ -148,12 +149,12 @@ void SignVerifyMessageDialog::on_signMessageButton_SM_clicked()
return;
}
- CDataStream ss(SER_GETHASH, 0);
+ CHashWriter ss(SER_GETHASH, 0);
ss << strMessageMagic;
ss << ui->messageIn_SM->document()->toPlainText().toStdString();
std::vector<unsigned char> vchSig;
- if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig))
+ if (!key.SignCompact(ss.GetHash(), vchSig))
{
ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signing failed.") + QString("</nobr>"));
@@ -185,7 +186,7 @@ void SignVerifyMessageDialog::on_addressBookButton_VM_clicked()
{
if (model && model->getAddressTableModel())
{
- AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this);
+ AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::SendingTab, this);
dlg.setModel(model->getAddressTableModel());
if (dlg.exec())
{
@@ -223,12 +224,12 @@ void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked()
return;
}
- CDataStream ss(SER_GETHASH, 0);
+ CHashWriter ss(SER_GETHASH, 0);
ss << strMessageMagic;
ss << ui->messageIn_VM->document()->toPlainText().toStdString();
CPubKey pubkey;
- if (!pubkey.RecoverCompact(Hash(ss.begin(), ss.end()), vchSig))
+ if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
{
ui->signatureIn_VM->setValid(false);
ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h
index bf841e4f8b..d651d5049b 100644
--- a/src/qt/signverifymessagedialog.h
+++ b/src/qt/signverifymessagedialog.h
@@ -7,6 +7,7 @@
#include <QDialog>
+class PlatformStyle;
class WalletModel;
namespace Ui {
@@ -18,7 +19,7 @@ class SignVerifyMessageDialog : public QDialog
Q_OBJECT
public:
- explicit SignVerifyMessageDialog(QWidget *parent);
+ explicit SignVerifyMessageDialog(const PlatformStyle *platformStyle, QWidget *parent);
~SignVerifyMessageDialog();
void setModel(WalletModel *model);
@@ -34,6 +35,7 @@ protected:
private:
Ui::SignVerifyMessageDialog *ui;
WalletModel *model;
+ const PlatformStyle *platformStyle;
private Q_SLOTS:
/* sign message */
diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp
index 8430e017c1..c15b64c327 100644
--- a/src/qt/splashscreen.cpp
+++ b/src/qt/splashscreen.cpp
@@ -57,7 +57,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
QPainter pixPaint(&pixmap);
pixPaint.setPen(QColor(100,100,100));
- // draw a slighly radial gradient
+ // draw a slightly radial gradient
QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio);
gradient.setColorAt(0, Qt::white);
gradient.setColorAt(1, QColor(247,247,247));
diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp
index b28934cd31..fa5696325d 100644
--- a/src/qt/test/paymentservertests.cpp
+++ b/src/qt/test/paymentservertests.cpp
@@ -185,7 +185,8 @@ void PaymentServerTests::paymentServerTests()
tempFile.open();
tempFile.write((const char*)randData, sizeof(randData));
tempFile.close();
- QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false);
+ // compares 50001 <= BIP70_MAX_PAYMENTREQUEST_SIZE == false
+ QCOMPARE(PaymentServer::verifySize(tempFile.size()), false);
// Payment request with amount overflow (amount is set to 21000001 BTC):
data = DecodeBase64(paymentrequest5_cert2_BASE64);
diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp
index bb768f1325..f91de2008c 100644
--- a/src/qt/test/test_main.cpp
+++ b/src/qt/test/test_main.cpp
@@ -17,6 +17,8 @@
#include <QObject>
#include <QTest>
+#include <openssl/ssl.h>
+
#if defined(QT_STATICPLUGIN) && QT_VERSION < 0x050000
#include <QtPlugin>
Q_IMPORT_PLUGIN(qcncodecs)
@@ -36,6 +38,8 @@ int main(int argc, char *argv[])
QCoreApplication app(argc, argv);
app.setApplicationName("Bitcoin-Qt-test");
+ SSL_library_init();
+
URITests test1;
if (QTest::qExec(&test1) != 0)
fInvalid = true;
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index af78a51d0f..801c6c62d2 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -165,7 +165,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
if (fAllFromMe)
{
- if(fAllFromMe == ISMINE_WATCH_ONLY)
+ if(fAllFromMe & ISMINE_WATCH_ONLY)
strHTML += "<b>" + tr("From") + ":</b> " + tr("watch-only") + "<br>";
//
@@ -190,7 +190,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
strHTML += GUIUtil::HtmlEscape(CBitcoinAddress(address).ToString());
if(toSelf == ISMINE_SPENDABLE)
strHTML += " (own address)";
- else if(toSelf == ISMINE_WATCH_ONLY)
+ else if(toSelf & ISMINE_WATCH_ONLY)
strHTML += " (watch-only)";
strHTML += "<br>";
}
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index 15d13e9fc9..d8623daf5d 100644
--- a/src/qt/transactionrecord.cpp
+++ b/src/qt/transactionrecord.cpp
@@ -56,7 +56,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
CTxDestination address;
sub.idx = parts.size(); // sequence number
sub.credit = txout.nValue;
- sub.involvesWatchAddress = mine == ISMINE_WATCH_ONLY;
+ sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY;
if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
{
// Received by Bitcoin Address
@@ -86,7 +86,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
{
isminetype mine = wallet->IsMine(txin);
- if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true;
+ if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
if(fAllFromMe > mine) fAllFromMe = mine;
}
@@ -94,7 +94,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
{
isminetype mine = wallet->IsMine(txout);
- if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true;
+ if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
if(fAllToMe > mine) fAllToMe = mine;
}
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index e3d64387f7..98ad1a44b6 100644
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -8,7 +8,7 @@
#include "guiconstants.h"
#include "guiutil.h"
#include "optionsmodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "transactiondesc.h"
#include "transactionrecord.h"
#include "walletmodel.h"
@@ -25,6 +25,8 @@
#include <QIcon>
#include <QList>
+#include <boost/foreach.hpp>
+
// Amount column is right-aligned it contains numbers
static int column_alignments[] = {
Qt::AlignLeft|Qt::AlignVCenter, /* status */
@@ -220,12 +222,13 @@ public:
}
};
-TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *parent):
+TransactionTableModel::TransactionTableModel(const PlatformStyle *platformStyle, CWallet* wallet, WalletModel *parent):
QAbstractTableModel(parent),
wallet(wallet),
walletModel(parent),
priv(new TransactionTablePriv(wallet, this)),
- fProcessingQueuedTransactions(false)
+ fProcessingQueuedTransactions(false),
+ platformStyle(platformStyle)
{
columns << QString() << QString() << tr("Date") << tr("Type") << tr("Label") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit());
priv->refreshWallet();
@@ -519,7 +522,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
case Qt::DecorationRole:
{
QIcon icon = qvariant_cast<QIcon>(index.data(RawDecorationRole));
- return TextColorIcon(icon);
+ return platformStyle->TextColorIcon(icon);
}
case Qt::DisplayRole:
switch(index.column())
diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h
index 25c82c764b..2089f703a6 100644
--- a/src/qt/transactiontablemodel.h
+++ b/src/qt/transactiontablemodel.h
@@ -10,6 +10,7 @@
#include <QAbstractTableModel>
#include <QStringList>
+class PlatformStyle;
class TransactionRecord;
class TransactionTablePriv;
class WalletModel;
@@ -23,7 +24,7 @@ class TransactionTableModel : public QAbstractTableModel
Q_OBJECT
public:
- explicit TransactionTableModel(CWallet* wallet, WalletModel *parent = 0);
+ explicit TransactionTableModel(const PlatformStyle *platformStyle, CWallet* wallet, WalletModel *parent = 0);
~TransactionTableModel();
enum ColumnIndex {
@@ -82,6 +83,7 @@ private:
QStringList columns;
TransactionTablePriv *priv;
bool fProcessingQueuedTransactions;
+ const PlatformStyle *platformStyle;
void subscribeToCoreSignals();
void unsubscribeFromCoreSignals();
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index 998789b3ae..54e5a82720 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -10,7 +10,7 @@
#include "editaddressdialog.h"
#include "guiutil.h"
#include "optionsmodel.h"
-#include "scicon.h"
+#include "platformstyle.h"
#include "transactiondescdialog.h"
#include "transactionfilterproxy.h"
#include "transactionrecord.h"
@@ -35,7 +35,7 @@
#include <QUrl>
#include <QVBoxLayout>
-TransactionView::TransactionView(QWidget *parent) :
+TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent) :
QWidget(parent), model(0), transactionProxyModel(0),
transactionView(0)
{
@@ -44,27 +44,28 @@ TransactionView::TransactionView(QWidget *parent) :
QHBoxLayout *hlayout = new QHBoxLayout();
hlayout->setContentsMargins(0,0,0,0);
-#ifdef Q_OS_MAC
- hlayout->setSpacing(5);
- hlayout->addSpacing(26);
-#else
- hlayout->setSpacing(0);
- hlayout->addSpacing(23);
-#endif
+
+ if (platformStyle->getUseExtraSpacing()) {
+ hlayout->setSpacing(5);
+ hlayout->addSpacing(26);
+ } else {
+ hlayout->setSpacing(0);
+ hlayout->addSpacing(23);
+ }
watchOnlyWidget = new QComboBox(this);
watchOnlyWidget->setFixedWidth(24);
watchOnlyWidget->addItem("", TransactionFilterProxy::WatchOnlyFilter_All);
- watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes);
- watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No);
+ watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes);
+ watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No);
hlayout->addWidget(watchOnlyWidget);
dateWidget = new QComboBox(this);
-#ifdef Q_OS_MAC
- dateWidget->setFixedWidth(121);
-#else
- dateWidget->setFixedWidth(120);
-#endif
+ if (platformStyle->getUseExtraSpacing()) {
+ dateWidget->setFixedWidth(121);
+ } else {
+ dateWidget->setFixedWidth(120);
+ }
dateWidget->addItem(tr("All"), All);
dateWidget->addItem(tr("Today"), Today);
dateWidget->addItem(tr("This week"), ThisWeek);
@@ -75,11 +76,11 @@ TransactionView::TransactionView(QWidget *parent) :
hlayout->addWidget(dateWidget);
typeWidget = new QComboBox(this);
-#ifdef Q_OS_MAC
- typeWidget->setFixedWidth(121);
-#else
- typeWidget->setFixedWidth(120);
-#endif
+ if (platformStyle->getUseExtraSpacing()) {
+ typeWidget->setFixedWidth(121);
+ } else {
+ typeWidget->setFixedWidth(120);
+ }
typeWidget->addItem(tr("All"), TransactionFilterProxy::ALL_TYPES);
typeWidget->addItem(tr("Received with"), TransactionFilterProxy::TYPE(TransactionRecord::RecvWithAddress) |
@@ -102,11 +103,11 @@ TransactionView::TransactionView(QWidget *parent) :
#if QT_VERSION >= 0x040700
amountWidget->setPlaceholderText(tr("Min amount"));
#endif
-#ifdef Q_OS_MAC
- amountWidget->setFixedWidth(97);
-#else
- amountWidget->setFixedWidth(100);
-#endif
+ if (platformStyle->getUseExtraSpacing()) {
+ amountWidget->setFixedWidth(97);
+ } else {
+ amountWidget->setFixedWidth(100);
+ }
amountWidget->setValidator(new QDoubleValidator(0, 1e20, 8, this));
hlayout->addWidget(amountWidget);
@@ -121,11 +122,11 @@ TransactionView::TransactionView(QWidget *parent) :
vlayout->setSpacing(0);
int width = view->verticalScrollBar()->sizeHint().width();
// Cover scroll bar width with spacing
-#ifdef Q_OS_MAC
- hlayout->addSpacing(width+2);
-#else
- hlayout->addSpacing(width);
-#endif
+ if (platformStyle->getUseExtraSpacing()) {
+ hlayout->addSpacing(width+2);
+ } else {
+ hlayout->addSpacing(width);
+ }
// Always show scroll bar
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
view->setTabKeyNavigation(false);
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index 6c35362be4..ac157fb98d 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -10,6 +10,7 @@
#include <QWidget>
#include <QKeyEvent>
+class PlatformStyle;
class TransactionFilterProxy;
class WalletModel;
@@ -32,7 +33,7 @@ class TransactionView : public QWidget
Q_OBJECT
public:
- explicit TransactionView(QWidget *parent = 0);
+ explicit TransactionView(const PlatformStyle *platformStyle, QWidget *parent = 0);
void setModel(WalletModel *model);
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index 892947bf3a..ba8c28464d 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -12,9 +12,10 @@
#include <QHBoxLayout>
#include <QLabel>
-WalletFrame::WalletFrame(BitcoinGUI *_gui) :
+WalletFrame::WalletFrame(const PlatformStyle *platformStyle, BitcoinGUI *_gui) :
QFrame(_gui),
- gui(_gui)
+ gui(_gui),
+ platformStyle(platformStyle)
{
// Leave HBox hook for adding a list view later
QHBoxLayout *walletFrameLayout = new QHBoxLayout(this);
@@ -42,7 +43,7 @@ bool WalletFrame::addWallet(const QString& name, WalletModel *walletModel)
if (!gui || !clientModel || !walletModel || mapWalletViews.count(name) > 0)
return false;
- WalletView *walletView = new WalletView(this);
+ WalletView *walletView = new WalletView(platformStyle, this);
walletView->setBitcoinGUI(gui);
walletView->setClientModel(clientModel);
walletView->setWalletModel(walletModel);
diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h
index 5a5e2ab944..9a56e97f9c 100644
--- a/src/qt/walletframe.h
+++ b/src/qt/walletframe.h
@@ -10,6 +10,7 @@
class BitcoinGUI;
class ClientModel;
+class PlatformStyle;
class SendCoinsRecipient;
class WalletModel;
class WalletView;
@@ -23,7 +24,7 @@ class WalletFrame : public QFrame
Q_OBJECT
public:
- explicit WalletFrame(BitcoinGUI *_gui = 0);
+ explicit WalletFrame(const PlatformStyle *platformStyle, BitcoinGUI *_gui = 0);
~WalletFrame();
void setClientModel(ClientModel *clientModel);
@@ -45,6 +46,8 @@ private:
bool bOutOfSync;
+ const PlatformStyle *platformStyle;
+
WalletView *currentWalletView();
public Q_SLOTS:
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 168a0255ff..5c21db8bdf 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -25,7 +25,9 @@
#include <QSet>
#include <QTimer>
-WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) :
+#include <boost/foreach.hpp>
+
+WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent) :
QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0),
transactionTableModel(0),
recentRequestsTableModel(0),
@@ -37,7 +39,7 @@ WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *p
fForceCheckBalanceChanged = false;
addressTableModel = new AddressTableModel(wallet, this);
- transactionTableModel = new TransactionTableModel(wallet, this);
+ transactionTableModel = new TransactionTableModel(platformStyle, wallet, this);
recentRequestsTableModel = new RecentRequestsTableModel(wallet, this);
// This timer will be fired repeatedly to update the balance
@@ -554,6 +556,11 @@ bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
return wallet->GetPubKey(address, vchPubKeyOut);
}
+bool WalletModel::havePrivKey(const CKeyID &address) const
+{
+ return wallet->HaveKey(address);
+}
+
// returns a list of COutputs from COutPoints
void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs)
{
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index 40bc623543..a5e877d81f 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -17,6 +17,7 @@
class AddressTableModel;
class OptionsModel;
+class PlatformStyle;
class RecentRequestsTableModel;
class TransactionTableModel;
class WalletModelTransaction;
@@ -100,7 +101,7 @@ class WalletModel : public QObject
Q_OBJECT
public:
- explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0);
+ explicit WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0);
~WalletModel();
enum StatusCode // Returned by sendCoins
@@ -186,6 +187,7 @@ public:
UnlockContext requestUnlock();
bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
+ bool havePrivKey(const CKeyID &address) const;
void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs);
bool isSpent(const COutPoint& outpoint) const;
void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const;
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
index c5f556b444..77efdb5cdd 100644
--- a/src/qt/walletview.cpp
+++ b/src/qt/walletview.cpp
@@ -11,8 +11,8 @@
#include "guiutil.h"
#include "optionsmodel.h"
#include "overviewpage.h"
+#include "platformstyle.h"
#include "receivecoinsdialog.h"
-#include "scicon.h"
#include "sendcoinsdialog.h"
#include "signverifymessagedialog.h"
#include "transactiontablemodel.h"
@@ -29,31 +29,35 @@
#include <QPushButton>
#include <QVBoxLayout>
-WalletView::WalletView(QWidget *parent):
+WalletView::WalletView(const PlatformStyle *platformStyle, QWidget *parent):
QStackedWidget(parent),
clientModel(0),
- walletModel(0)
+ walletModel(0),
+ platformStyle(platformStyle)
{
// Create tabs
- overviewPage = new OverviewPage();
+ overviewPage = new OverviewPage(platformStyle);
transactionsPage = new QWidget(this);
QVBoxLayout *vbox = new QVBoxLayout();
QHBoxLayout *hbox_buttons = new QHBoxLayout();
- transactionView = new TransactionView(this);
+ transactionView = new TransactionView(platformStyle, this);
vbox->addWidget(transactionView);
QPushButton *exportButton = new QPushButton(tr("&Export"), this);
exportButton->setToolTip(tr("Export the data in the current tab to a file"));
-#ifndef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
- exportButton->setIcon(SingleColorIcon(":/icons/export"));
-#endif
+ if (platformStyle->getImagesOnButtons()) {
+ exportButton->setIcon(platformStyle->SingleColorIcon(":/icons/export"));
+ }
hbox_buttons->addStretch();
hbox_buttons->addWidget(exportButton);
vbox->addLayout(hbox_buttons);
transactionsPage->setLayout(vbox);
- receiveCoinsPage = new ReceiveCoinsDialog();
- sendCoinsPage = new SendCoinsDialog();
+ receiveCoinsPage = new ReceiveCoinsDialog(platformStyle);
+ sendCoinsPage = new SendCoinsDialog(platformStyle);
+
+ usedSendingAddressesPage = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::SendingTab, this);
+ usedReceivingAddressesPage = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this);
addWidget(overviewPage);
addWidget(transactionsPage);
@@ -114,6 +118,8 @@ void WalletView::setWalletModel(WalletModel *walletModel)
overviewPage->setWalletModel(walletModel);
receiveCoinsPage->setModel(walletModel);
sendCoinsPage->setModel(walletModel);
+ usedReceivingAddressesPage->setModel(walletModel->getAddressTableModel());
+ usedSendingAddressesPage->setModel(walletModel->getAddressTableModel());
if (walletModel)
{
@@ -182,7 +188,7 @@ void WalletView::gotoSendCoinsPage(QString addr)
void WalletView::gotoSignMessageTab(QString addr)
{
// calls show() in showTab_SM()
- SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(this);
+ SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this);
signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
signVerifyMessageDialog->setModel(walletModel);
signVerifyMessageDialog->showTab_SM(true);
@@ -194,7 +200,7 @@ void WalletView::gotoSignMessageTab(QString addr)
void WalletView::gotoVerifyMessageTab(QString addr)
{
// calls show() in showTab_VM()
- SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(this);
+ SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this);
signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
signVerifyMessageDialog->setModel(walletModel);
signVerifyMessageDialog->showTab_VM(true);
@@ -272,20 +278,20 @@ void WalletView::usedSendingAddresses()
{
if(!walletModel)
return;
- AddressBookPage *dlg = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab, this);
- dlg->setAttribute(Qt::WA_DeleteOnClose);
- dlg->setModel(walletModel->getAddressTableModel());
- dlg->show();
+
+ usedSendingAddressesPage->show();
+ usedSendingAddressesPage->raise();
+ usedSendingAddressesPage->activateWindow();
}
void WalletView::usedReceivingAddresses()
{
if(!walletModel)
return;
- AddressBookPage *dlg = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this);
- dlg->setAttribute(Qt::WA_DeleteOnClose);
- dlg->setModel(walletModel->getAddressTableModel());
- dlg->show();
+
+ usedReceivingAddressesPage->show();
+ usedReceivingAddressesPage->raise();
+ usedReceivingAddressesPage->activateWindow();
}
void WalletView::showProgress(const QString &title, int nProgress)
diff --git a/src/qt/walletview.h b/src/qt/walletview.h
index 87c5d7bfbf..2a6a6a2df2 100644
--- a/src/qt/walletview.h
+++ b/src/qt/walletview.h
@@ -12,11 +12,13 @@
class BitcoinGUI;
class ClientModel;
class OverviewPage;
+class PlatformStyle;
class ReceiveCoinsDialog;
class SendCoinsDialog;
class SendCoinsRecipient;
class TransactionView;
class WalletModel;
+class AddressBookPage;
QT_BEGIN_NAMESPACE
class QModelIndex;
@@ -34,7 +36,7 @@ class WalletView : public QStackedWidget
Q_OBJECT
public:
- explicit WalletView(QWidget *parent);
+ explicit WalletView(const PlatformStyle *platformStyle, QWidget *parent);
~WalletView();
void setBitcoinGUI(BitcoinGUI *gui);
@@ -60,10 +62,13 @@ private:
QWidget *transactionsPage;
ReceiveCoinsDialog *receiveCoinsPage;
SendCoinsDialog *sendCoinsPage;
+ AddressBookPage *usedSendingAddressesPage;
+ AddressBookPage *usedReceivingAddressesPage;
TransactionView *transactionView;
QProgressDialog *progressDialog;
+ const PlatformStyle *platformStyle;
public Q_SLOTS:
/** Switch to overview (home) page */
diff --git a/src/rest.cpp b/src/rest.cpp
index dfe01495f7..c46d7a8bd2 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -3,9 +3,11 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include "chain.h"
#include "primitives/block.h"
#include "primitives/transaction.h"
#include "main.h"
+#include "httpserver.h"
#include "rpcserver.h"
#include "streams.h"
#include "sync.h"
@@ -16,7 +18,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/dynamic_bitset.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -55,35 +57,38 @@ struct CCoin {
}
};
-class RestErr
-{
-public:
- enum HTTPStatusCode status;
- string message;
-};
-
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false);
+extern UniValue mempoolInfoToJSON();
+extern UniValue mempoolToJSON(bool fVerbose = false);
extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
extern UniValue blockheaderToJSON(const CBlockIndex* blockindex);
-static RestErr RESTERR(enum HTTPStatusCode status, string message)
+static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, string message)
{
- RestErr re;
- re.status = status;
- re.message = message;
- return re;
+ req->WriteHeader("Content-Type", "text/plain");
+ req->WriteReply(status, message + "\r\n");
+ return false;
}
-static enum RetFormat ParseDataFormat(vector<string>& params, const string strReq)
+static enum RetFormat ParseDataFormat(std::string& param, const std::string& strReq)
{
- boost::split(params, strReq, boost::is_any_of("."));
- if (params.size() > 1) {
- for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
- if (params[1] == rf_names[i].name)
- return rf_names[i].rf;
+ const std::string::size_type pos = strReq.rfind('.');
+ if (pos == std::string::npos)
+ {
+ param = strReq;
+ return rf_names[0].rf;
}
+ param = strReq.substr(0, pos);
+ const std::string suff(strReq, pos + 1);
+
+ for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
+ if (suff == rf_names[i].name)
+ return rf_names[i].rf;
+
+ /* If no suffix is found, return original string. */
+ param = strReq;
return rf_names[0].rf;
}
@@ -112,28 +117,35 @@ static bool ParseHashStr(const string& strReq, uint256& v)
return true;
}
-static bool rest_headers(AcceptedConnection* conn,
- const std::string& strURIPart,
- const std::string& strRequest,
- const std::map<std::string, std::string>& mapHeaders,
- bool fRun)
+static bool CheckWarmup(HTTPRequest* req)
{
- vector<string> params;
- const RetFormat rf = ParseDataFormat(params, strURIPart);
+ std::string statusmessage;
+ if (RPCIsInWarmup(&statusmessage))
+ return RESTERR(req, HTTP_SERVICE_UNAVAILABLE, "Service temporarily unavailable: " + statusmessage);
+ return true;
+}
+
+static bool rest_headers(HTTPRequest* req,
+ const std::string& strURIPart)
+{
+ if (!CheckWarmup(req))
+ return false;
+ std::string param;
+ const RetFormat rf = ParseDataFormat(param, strURIPart);
vector<string> path;
- boost::split(path, params[0], boost::is_any_of("/"));
+ boost::split(path, param, boost::is_any_of("/"));
if (path.size() != 2)
- throw RESTERR(HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers/<count>/<hash>.<ext>.");
+ return RESTERR(req, HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers/<count>/<hash>.<ext>.");
long count = strtol(path[0].c_str(), NULL, 10);
if (count < 1 || count > 2000)
- throw RESTERR(HTTP_BAD_REQUEST, "Header count out of range: " + path[0]);
+ return RESTERR(req, HTTP_BAD_REQUEST, "Header count out of range: " + path[0]);
string hashStr = path[1];
uint256 hash;
if (!ParseHashStr(hashStr, hash))
- throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
+ return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
std::vector<const CBlockIndex *> headers;
headers.reserve(count);
@@ -157,28 +169,29 @@ static bool rest_headers(AcceptedConnection* conn,
switch (rf) {
case RF_BINARY: {
string binaryHeader = ssHeader.str();
- conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryHeader.size(), "application/octet-stream") << binaryHeader << std::flush;
+ req->WriteHeader("Content-Type", "application/octet-stream");
+ req->WriteReply(HTTP_OK, binaryHeader);
return true;
}
case RF_HEX: {
string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n";
- conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush;
+ req->WriteHeader("Content-Type", "text/plain");
+ req->WriteReply(HTTP_OK, strHex);
return true;
}
-
case RF_JSON: {
UniValue jsonHeaders(UniValue::VARR);
BOOST_FOREACH(const CBlockIndex *pindex, headers) {
jsonHeaders.push_back(blockheaderToJSON(pindex));
}
string strJSON = jsonHeaders.write() + "\n";
- conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
+ req->WriteHeader("Content-Type", "application/json");
+ req->WriteReply(HTTP_OK, strJSON);
return true;
}
-
default: {
- throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)");
+ return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)");
}
}
@@ -186,34 +199,32 @@ static bool rest_headers(AcceptedConnection* conn,
return true; // continue to process further HTTP reqs on this cxn
}
-static bool rest_block(AcceptedConnection* conn,
+static bool rest_block(HTTPRequest* req,
const std::string& strURIPart,
- const std::string& strRequest,
- const std::map<std::string, std::string>& mapHeaders,
- bool fRun,
bool showTxDetails)
{
- vector<string> params;
- const RetFormat rf = ParseDataFormat(params, strURIPart);
+ if (!CheckWarmup(req))
+ return false;
+ std::string hashStr;
+ const RetFormat rf = ParseDataFormat(hashStr, strURIPart);
- string hashStr = params[0];
uint256 hash;
if (!ParseHashStr(hashStr, hash))
- throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
+ return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
CBlock block;
CBlockIndex* pblockindex = NULL;
{
LOCK(cs_main);
if (mapBlockIndex.count(hash) == 0)
- throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found");
+ return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
pblockindex = mapBlockIndex[hash];
if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0)
- throw RESTERR(HTTP_NOT_FOUND, hashStr + " not available (pruned data)");
+ return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)");
if (!ReadBlockFromDisk(block, pblockindex))
- throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found");
+ return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
}
CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION);
@@ -222,25 +233,28 @@ static bool rest_block(AcceptedConnection* conn,
switch (rf) {
case RF_BINARY: {
string binaryBlock = ssBlock.str();
- conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryBlock.size(), "application/octet-stream") << binaryBlock << std::flush;
+ req->WriteHeader("Content-Type", "application/octet-stream");
+ req->WriteReply(HTTP_OK, binaryBlock);
return true;
}
case RF_HEX: {
string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n";
- conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush;
+ req->WriteHeader("Content-Type", "text/plain");
+ req->WriteReply(HTTP_OK, strHex);
return true;
}
case RF_JSON: {
UniValue objBlock = blockToJSON(block, pblockindex, showTxDetails);
string strJSON = objBlock.write() + "\n";
- conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
+ req->WriteHeader("Content-Type", "application/json");
+ req->WriteReply(HTTP_OK, strJSON);
return true;
}
default: {
- throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
+ return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
}
}
@@ -248,43 +262,34 @@ static bool rest_block(AcceptedConnection* conn,
return true; // continue to process further HTTP reqs on this cxn
}
-static bool rest_block_extended(AcceptedConnection* conn,
- const std::string& strURIPart,
- const std::string& strRequest,
- const std::map<std::string, std::string>& mapHeaders,
- bool fRun)
+static bool rest_block_extended(HTTPRequest* req, const std::string& strURIPart)
{
- return rest_block(conn, strURIPart, strRequest, mapHeaders, fRun, true);
+ return rest_block(req, strURIPart, true);
}
-static bool rest_block_notxdetails(AcceptedConnection* conn,
- const std::string& strURIPart,
- const std::string& strRequest,
- const std::map<std::string, std::string>& mapHeaders,
- bool fRun)
+static bool rest_block_notxdetails(HTTPRequest* req, const std::string& strURIPart)
{
- return rest_block(conn, strURIPart, strRequest, mapHeaders, fRun, false);
+ return rest_block(req, strURIPart, false);
}
-static bool rest_chaininfo(AcceptedConnection* conn,
- const std::string& strURIPart,
- const std::string& strRequest,
- const std::map<std::string, std::string>& mapHeaders,
- bool fRun)
+static bool rest_chaininfo(HTTPRequest* req, const std::string& strURIPart)
{
- vector<string> params;
- const RetFormat rf = ParseDataFormat(params, strURIPart);
+ if (!CheckWarmup(req))
+ return false;
+ std::string param;
+ const RetFormat rf = ParseDataFormat(param, strURIPart);
switch (rf) {
case RF_JSON: {
UniValue rpcParams(UniValue::VARR);
UniValue chainInfoObject = getblockchaininfo(rpcParams, false);
string strJSON = chainInfoObject.write() + "\n";
- conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
+ req->WriteHeader("Content-Type", "application/json");
+ req->WriteReply(HTTP_OK, strJSON);
return true;
}
default: {
- throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)");
+ return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
}
}
@@ -292,24 +297,71 @@ static bool rest_chaininfo(AcceptedConnection* conn,
return true; // continue to process further HTTP reqs on this cxn
}
-static bool rest_tx(AcceptedConnection* conn,
- const std::string& strURIPart,
- const std::string& strRequest,
- const std::map<std::string, std::string>& mapHeaders,
- bool fRun)
+static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart)
{
- vector<string> params;
- const RetFormat rf = ParseDataFormat(params, strURIPart);
+ if (!CheckWarmup(req))
+ return false;
+ std::string param;
+ const RetFormat rf = ParseDataFormat(param, strURIPart);
+
+ switch (rf) {
+ case RF_JSON: {
+ UniValue mempoolInfoObject = mempoolInfoToJSON();
+
+ string strJSON = mempoolInfoObject.write() + "\n";
+ req->WriteHeader("Content-Type", "application/json");
+ req->WriteReply(HTTP_OK, strJSON);
+ return true;
+ }
+ default: {
+ return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
+ }
+ }
+
+ // not reached
+ return true; // continue to process further HTTP reqs on this cxn
+}
+
+static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPart)
+{
+ if (!CheckWarmup(req))
+ return false;
+ std::string param;
+ const RetFormat rf = ParseDataFormat(param, strURIPart);
+
+ switch (rf) {
+ case RF_JSON: {
+ UniValue mempoolObject = mempoolToJSON(true);
+
+ string strJSON = mempoolObject.write() + "\n";
+ req->WriteHeader("Content-Type", "application/json");
+ req->WriteReply(HTTP_OK, strJSON);
+ return true;
+ }
+ default: {
+ return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
+ }
+ }
+
+ // not reached
+ return true; // continue to process further HTTP reqs on this cxn
+}
+
+static bool rest_tx(HTTPRequest* req, const std::string& strURIPart)
+{
+ if (!CheckWarmup(req))
+ return false;
+ std::string hashStr;
+ const RetFormat rf = ParseDataFormat(hashStr, strURIPart);
- string hashStr = params[0];
uint256 hash;
if (!ParseHashStr(hashStr, hash))
- throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
+ return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
CTransaction tx;
uint256 hashBlock = uint256();
if (!GetTransaction(hash, tx, hashBlock, true))
- throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found");
+ return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << tx;
@@ -317,13 +369,15 @@ static bool rest_tx(AcceptedConnection* conn,
switch (rf) {
case RF_BINARY: {
string binaryTx = ssTx.str();
- conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryTx.size(), "application/octet-stream") << binaryTx << std::flush;
+ req->WriteHeader("Content-Type", "application/octet-stream");
+ req->WriteReply(HTTP_OK, binaryTx);
return true;
}
case RF_HEX: {
string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n";
- conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush;
+ req->WriteHeader("Content-Type", "text/plain");
+ req->WriteReply(HTTP_OK, strHex);
return true;
}
@@ -331,12 +385,13 @@ static bool rest_tx(AcceptedConnection* conn,
UniValue objTx(UniValue::VOBJ);
TxToJSON(tx, hashBlock, objTx);
string strJSON = objTx.write() + "\n";
- conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
+ req->WriteHeader("Content-Type", "application/json");
+ req->WriteReply(HTTP_OK, strJSON);
return true;
}
default: {
- throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
+ return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
}
}
@@ -344,25 +399,24 @@ static bool rest_tx(AcceptedConnection* conn,
return true; // continue to process further HTTP reqs on this cxn
}
-static bool rest_getutxos(AcceptedConnection* conn,
- const std::string& strURIPart,
- const std::string& strRequest,
- const std::map<std::string, std::string>& mapHeaders,
- bool fRun)
+static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
{
- vector<string> params;
- enum RetFormat rf = ParseDataFormat(params, strURIPart);
+ if (!CheckWarmup(req))
+ return false;
+ std::string param;
+ const RetFormat rf = ParseDataFormat(param, strURIPart);
vector<string> uriParts;
- if (params.size() > 0 && params[0].length() > 1)
+ if (param.length() > 1)
{
- std::string strUriParams = params[0].substr(1);
+ std::string strUriParams = param.substr(1);
boost::split(uriParts, strUriParams, boost::is_any_of("/"));
}
// throw exception in case of a empty request
- if (strRequest.length() == 0 && uriParts.size() == 0)
- throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Error: empty request");
+ std::string strRequestMutable = req->ReadBody();
+ if (strRequestMutable.length() == 0 && uriParts.size() == 0)
+ return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request");
bool fInputParsed = false;
bool fCheckMemPool = false;
@@ -386,7 +440,7 @@ static bool rest_getutxos(AcceptedConnection* conn,
std::string strOutput = uriParts[i].substr(uriParts[i].find("-")+1);
if (!ParseInt32(strOutput, &nOutput) || !IsHex(strTxid))
- throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Parse error");
+ return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Parse error");
txid.SetHex(strTxid);
vOutPoints.push_back(COutPoint(txid, (uint32_t)nOutput));
@@ -395,15 +449,13 @@ static bool rest_getutxos(AcceptedConnection* conn,
if (vOutPoints.size() > 0)
fInputParsed = true;
else
- throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Error: empty request");
+ return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request");
}
- string strRequestMutable = strRequest; //convert const string to string for allowing hex to bin converting
-
switch (rf) {
case RF_HEX: {
// convert hex to bin, continue then with bin part
- std::vector<unsigned char> strRequestV = ParseHex(strRequest);
+ std::vector<unsigned char> strRequestV = ParseHex(strRequestMutable);
strRequestMutable.assign(strRequestV.begin(), strRequestV.end());
}
@@ -413,7 +465,7 @@ static bool rest_getutxos(AcceptedConnection* conn,
if (strRequestMutable.size() > 0)
{
if (fInputParsed) //don't allow sending input over URI and HTTP RAW DATA
- throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Combination of URI scheme inputs and raw post data is not allowed");
+ return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Combination of URI scheme inputs and raw post data is not allowed");
CDataStream oss(SER_NETWORK, PROTOCOL_VERSION);
oss << strRequestMutable;
@@ -422,24 +474,24 @@ static bool rest_getutxos(AcceptedConnection* conn,
}
} catch (const std::ios_base::failure& e) {
// abort in case of unreadable binary data
- throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Parse error");
+ return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Parse error");
}
break;
}
case RF_JSON: {
if (!fInputParsed)
- throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, "Error: empty request");
+ return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request");
break;
}
default: {
- throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
+ return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
}
}
// limit max outpoints
if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS)
- throw RESTERR(HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size()));
+ return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size()));
// check spentness and form a bitmap (as well as a JSON capable human-readble string representation)
vector<unsigned char> bitmap;
@@ -489,7 +541,8 @@ static bool rest_getutxos(AcceptedConnection* conn,
ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs;
string ssGetUTXOResponseString = ssGetUTXOResponse.str();
- conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, ssGetUTXOResponseString.size(), "application/octet-stream") << ssGetUTXOResponseString << std::flush;
+ req->WriteHeader("Content-Type", "application/octet-stream");
+ req->WriteReply(HTTP_OK, ssGetUTXOResponseString);
return true;
}
@@ -498,7 +551,8 @@ static bool rest_getutxos(AcceptedConnection* conn,
ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash() << bitmap << outs;
string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n";
- conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush;
+ req->WriteHeader("Content-Type", "text/plain");
+ req->WriteReply(HTTP_OK, strHex);
return true;
}
@@ -528,11 +582,12 @@ static bool rest_getutxos(AcceptedConnection* conn,
// return json string
string strJSON = objGetUTXOResponse.write() + "\n";
- conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
+ req->WriteHeader("Content-Type", "application/json");
+ req->WriteReply(HTTP_OK, strJSON);
return true;
}
default: {
- throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
+ return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
}
}
@@ -542,43 +597,31 @@ static bool rest_getutxos(AcceptedConnection* conn,
static const struct {
const char* prefix;
- bool (*handler)(AcceptedConnection* conn,
- const std::string& strURIPart,
- const std::string& strRequest,
- const std::map<std::string, std::string>& mapHeaders,
- bool fRun);
+ bool (*handler)(HTTPRequest* req, const std::string& strReq);
} uri_prefixes[] = {
{"/rest/tx/", rest_tx},
{"/rest/block/notxdetails/", rest_block_notxdetails},
{"/rest/block/", rest_block_extended},
{"/rest/chaininfo", rest_chaininfo},
+ {"/rest/mempool/info", rest_mempool_info},
+ {"/rest/mempool/contents", rest_mempool_contents},
{"/rest/headers/", rest_headers},
{"/rest/getutxos", rest_getutxos},
};
-bool HTTPReq_REST(AcceptedConnection* conn,
- const std::string& strURI,
- const string& strRequest,
- const std::map<std::string, std::string>& mapHeaders,
- bool fRun)
+bool StartREST()
{
- try {
- std::string statusmessage;
- if (RPCIsInWarmup(&statusmessage))
- throw RESTERR(HTTP_SERVICE_UNAVAILABLE, "Service temporarily unavailable: " + statusmessage);
-
- for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++) {
- unsigned int plen = strlen(uri_prefixes[i].prefix);
- if (strURI.substr(0, plen) == uri_prefixes[i].prefix) {
- string strURIPart = strURI.substr(plen);
- return uri_prefixes[i].handler(conn, strURIPart, strRequest, mapHeaders, fRun);
- }
- }
- } catch (const RestErr& re) {
- conn->stream() << HTTPReply(re.status, re.message + "\r\n", false, false, "text/plain") << std::flush;
- return false;
- }
+ for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++)
+ RegisterHTTPHandler(uri_prefixes[i].prefix, false, uri_prefixes[i].handler);
+ return true;
+}
- conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush;
- return false;
+void InterruptREST()
+{
+}
+
+void StopREST()
+{
+ for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++)
+ UnregisterHTTPHandler(uri_prefixes[i].prefix, false);
}
diff --git a/src/reverselock.h b/src/reverselock.h
new file mode 100644
index 0000000000..567636e16a
--- /dev/null
+++ b/src/reverselock.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_REVERSELOCK_H
+#define BITCOIN_REVERSELOCK_H
+
+/**
+ * An RAII-style reverse lock. Unlocks on construction and locks on destruction.
+ */
+template<typename Lock>
+class reverse_lock
+{
+public:
+
+ explicit reverse_lock(Lock& lock) : lock(lock) {
+ lock.unlock();
+ }
+
+ ~reverse_lock() {
+ lock.lock();
+ }
+
+private:
+ reverse_lock(reverse_lock const&);
+ reverse_lock& operator=(reverse_lock const&);
+
+ Lock& lock;
+};
+
+#endif // BITCOIN_REVERSELOCK_H
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
index f1c5ffe050..4786d72a3f 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -3,17 +3,24 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include "amount.h"
+#include "chain.h"
+#include "chainparams.h"
#include "checkpoints.h"
+#include "coins.h"
#include "consensus/validation.h"
#include "main.h"
#include "primitives/transaction.h"
#include "rpcserver.h"
+#include "streams.h"
#include "sync.h"
+#include "txmempool.h"
#include "util.h"
+#include "utilstrencodings.h"
#include <stdint.h>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -168,53 +175,15 @@ UniValue getdifficulty(const UniValue& params, bool fHelp)
return GetDifficulty();
}
-
-UniValue getrawmempool(const UniValue& params, bool fHelp)
+UniValue mempoolToJSON(bool fVerbose = false)
{
- if (fHelp || params.size() > 1)
- throw runtime_error(
- "getrawmempool ( verbose )\n"
- "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
- "\nArguments:\n"
- "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
- "\nResult: (for verbose = false):\n"
- "[ (json array of string)\n"
- " \"transactionid\" (string) The transaction id\n"
- " ,...\n"
- "]\n"
- "\nResult: (for verbose = true):\n"
- "{ (json object)\n"
- " \"transactionid\" : { (json object)\n"
- " \"size\" : n, (numeric) transaction size in bytes\n"
- " \"fee\" : n, (numeric) transaction fee in bitcoins\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"
- " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
- " \"transactionid\", (string) parent transaction id\n"
- " ... ]\n"
- " }, ...\n"
- "}\n"
- "\nExamples\n"
- + HelpExampleCli("getrawmempool", "true")
- + HelpExampleRpc("getrawmempool", "true")
- );
-
- LOCK(cs_main);
-
- bool fVerbose = false;
- if (params.size() > 0)
- fVerbose = params[0].get_bool();
-
if (fVerbose)
{
LOCK(mempool.cs);
UniValue o(UniValue::VOBJ);
- BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx)
+ BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx)
{
- const uint256& hash = entry.first;
- const CTxMemPoolEntry& e = entry.second;
+ const uint256& hash = e.GetTx().GetHash();
UniValue info(UniValue::VOBJ);
info.push_back(Pair("size", (int)e.GetTxSize()));
info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
@@ -222,6 +191,9 @@ UniValue getrawmempool(const UniValue& params, bool fHelp)
info.push_back(Pair("height", (int)e.GetHeight()));
info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight())));
info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height())));
+ info.push_back(Pair("descendantcount", e.GetCountWithDescendants()));
+ info.push_back(Pair("descendantsize", e.GetSizeWithDescendants()));
+ info.push_back(Pair("descendantfees", e.GetFeesWithDescendants()));
const CTransaction& tx = e.GetTx();
set<string> setDepends;
BOOST_FOREACH(const CTxIn& txin, tx.vin)
@@ -254,6 +226,50 @@ UniValue getrawmempool(const UniValue& params, bool fHelp)
}
}
+UniValue getrawmempool(const UniValue& params, bool fHelp)
+{
+ if (fHelp || params.size() > 1)
+ throw runtime_error(
+ "getrawmempool ( verbose )\n"
+ "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n"
+ "\nArguments:\n"
+ "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n"
+ "\nResult: (for verbose = false):\n"
+ "[ (json array of string)\n"
+ " \"transactionid\" (string) The transaction id\n"
+ " ,...\n"
+ "]\n"
+ "\nResult: (for verbose = true):\n"
+ "{ (json object)\n"
+ " \"transactionid\" : { (json object)\n"
+ " \"size\" : n, (numeric) transaction size in bytes\n"
+ " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n"
+ " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n"
+ " \"height\" : n, (numeric) block height when transaction entered pool\n"
+ " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n"
+ " \"currentpriority\" : n, (numeric) transaction priority now\n"
+ " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n"
+ " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n"
+ " \"descendantfees\" : n, (numeric) fees of in-mempool descendants (including this one)\n"
+ " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n"
+ " \"transactionid\", (string) parent transaction id\n"
+ " ... ]\n"
+ " }, ...\n"
+ "}\n"
+ "\nExamples\n"
+ + HelpExampleCli("getrawmempool", "true")
+ + HelpExampleRpc("getrawmempool", "true")
+ );
+
+ LOCK(cs_main);
+
+ bool fVerbose = false;
+ if (params.size() > 0)
+ fVerbose = params[0].get_bool();
+
+ return mempoolToJSON(fVerbose);
+}
+
UniValue getblockhash(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 1)
@@ -455,7 +471,7 @@ UniValue gettxout(const UniValue& params, bool fHelp)
"{\n"
" \"bestblock\" : \"hash\", (string) the block hash\n"
" \"confirmations\" : n, (numeric) The number of confirmations\n"
- " \"value\" : x.xxx, (numeric) The transaction value in btc\n"
+ " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n"
" \"scriptPubKey\" : { (json object)\n"
" \"asm\" : \"code\", (string) \n"
" \"hex\" : \"hex\", (string) \n"
@@ -632,6 +648,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)
@@ -750,6 +767,19 @@ UniValue getchaintips(const UniValue& params, bool fHelp)
return res;
}
+UniValue mempoolInfoToJSON()
+{
+ UniValue ret(UniValue::VOBJ);
+ ret.push_back(Pair("size", (int64_t) mempool.size()));
+ ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
+ ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
+ 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;
+}
+
UniValue getmempoolinfo(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 0)
@@ -767,12 +797,7 @@ UniValue getmempoolinfo(const UniValue& params, bool fHelp)
+ HelpExampleRpc("getmempoolinfo", "")
);
- UniValue ret(UniValue::VOBJ);
- ret.push_back(Pair("size", (int64_t) mempool.size()));
- ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
- ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage()));
-
- return ret;
+ return mempoolInfoToJSON();
}
UniValue invalidateblock(const UniValue& params, bool fHelp)
diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp
index b41e960e8a..343b6234d4 100644
--- a/src/rpcclient.cpp
+++ b/src/rpcclient.cpp
@@ -12,7 +12,7 @@
#include <stdint.h>
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -76,6 +76,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "getrawtransaction", 1 },
{ "createrawtransaction", 0 },
{ "createrawtransaction", 1 },
+ { "createrawtransaction", 2 },
{ "signrawtransaction", 1 },
{ "signrawtransaction", 2 },
{ "sendrawtransaction", 1 },
@@ -87,6 +88,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "lockunspent", 1 },
{ "importprivkey", 2 },
{ "importaddress", 2 },
+ { "importaddress", 3 },
+ { "importpubkey", 2 },
{ "verifychain", 0 },
{ "verifychain", 1 },
{ "keypoolrefill", 0 },
diff --git a/src/rpcclient.h b/src/rpcclient.h
index d68b4ed6ae..8937a56f03 100644
--- a/src/rpcclient.h
+++ b/src/rpcclient.h
@@ -6,7 +6,7 @@
#ifndef BITCOIN_RPCCLIENT_H
#define BITCOIN_RPCCLIENT_H
-#include "univalue/univalue.h"
+#include <univalue.h>
UniValue RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams);
/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null)
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index 703b0ee653..c49c3e5194 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -4,6 +4,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "amount.h"
+#include "chain.h"
#include "chainparams.h"
#include "consensus/consensus.h"
#include "consensus/validation.h"
@@ -14,7 +15,9 @@
#include "net.h"
#include "pow.h"
#include "rpcserver.h"
+#include "txmempool.h"
#include "util.h"
+#include "utilstrencodings.h"
#include "validationinterface.h"
#include <stdint.h>
@@ -22,7 +25,7 @@
#include <boost/assign/list_of.hpp>
#include <boost/shared_ptr.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -116,7 +119,8 @@ UniValue generate(const UniValue& params, bool fHelp)
"generate numblocks\n"
"\nMine blocks immediately (before the RPC call returns)\n"
"\nNote: this function can only be used on the regtest network\n"
- "1. numblocks (numeric) How many blocks are generated immediately.\n"
+ "\nArguments:\n"
+ "1. numblocks (numeric, required) How many blocks are generated immediately.\n"
"\nResult\n"
"[ blockhashes ] (array) hashes of blocks generated\n"
"\nExamples:\n"
@@ -135,8 +139,12 @@ UniValue generate(const UniValue& params, bool fHelp)
boost::shared_ptr<CReserveScript> coinbaseScript;
GetMainSignals().ScriptForMining(coinbaseScript);
+ // If the keypool is exhausted, no script is returned at all. Catch this.
+ if (!coinbaseScript)
+ throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
+
//throw an error if no script was provided
- if (!coinbaseScript->reserveScript.size())
+ if (coinbaseScript->reserveScript.empty())
throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available (mining requires a wallet)");
{ // Don't keep cs_main locked
diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp
index cab57d7027..0f0457c5cf 100644
--- a/src/rpcmisc.cpp
+++ b/src/rpcmisc.cpp
@@ -12,6 +12,7 @@
#include "rpcserver.h"
#include "timedata.h"
#include "util.h"
+#include "utilstrencodings.h"
#ifdef ENABLE_WALLET
#include "wallet/wallet.h"
#include "wallet/walletdb.h"
@@ -21,7 +22,7 @@
#include <boost/assign/list_of.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -59,8 +60,8 @@ UniValue getinfo(const UniValue& params, bool fHelp)
" \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
" \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
" \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n"
- " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc/kb\n"
- " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n"
+ " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in " + CURRENCY_UNIT + "/kB\n"
+ " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n"
" \"errors\": \"...\" (string) any error messages\n"
"}\n"
"\nExamples:\n"
@@ -156,13 +157,14 @@ UniValue validateaddress(const UniValue& params, bool fHelp)
"1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n"
"\nResult:\n"
"{\n"
- " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
+ " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
" \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
" \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
- " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
- " \"isscript\" : true|false, (boolean) If the key is a script\n"
+ " \"ismine\" : true|false, (boolean) If the address is yours or not\n"
+ " \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n"
+ " \"isscript\" : true|false, (boolean) If the key is a script\n"
" \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
- " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
+ " \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
" \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
"}\n"
"\nExamples:\n"
diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp
index dd631905fd..6b4815ebd8 100644
--- a/src/rpcnet.cpp
+++ b/src/rpcnet.cpp
@@ -4,6 +4,7 @@
#include "rpcserver.h"
+#include "chainparams.h"
#include "clientversion.h"
#include "main.h"
#include "net.h"
@@ -11,12 +12,14 @@
#include "protocol.h"
#include "sync.h"
#include "timedata.h"
+#include "ui_interface.h"
#include "util.h"
+#include "utilstrencodings.h"
#include "version.h"
#include <boost/foreach.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -94,6 +97,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp)
" \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
" \"timeoffset\": ttt, (numeric) The time offset in seconds\n"
" \"pingtime\": n, (numeric) ping time\n"
+ " \"minping\": n, (numeric) minimum observed ping time\n"
" \"pingwait\": n, (numeric) ping wait\n"
" \"version\": v, (numeric) The peer version, such as 7001\n"
" \"subver\": \"/Satoshi:0.8.5/\", (string) The string version\n"
@@ -137,6 +141,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp)
obj.push_back(Pair("conntime", stats.nTimeConnected));
obj.push_back(Pair("timeoffset", stats.nTimeOffset));
obj.push_back(Pair("pingtime", stats.dPingTime));
+ obj.push_back(Pair("minping", stats.dPingMin));
if (stats.dPingWait > 0.0)
obj.push_back(Pair("pingwait", stats.dPingWait));
obj.push_back(Pair("version", stats.nVersion));
@@ -374,6 +379,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;
}
@@ -421,7 +435,7 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp)
" }\n"
" ,...\n"
" ],\n"
- " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n"
+ " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n"
" \"localaddresses\": [ (array) list of local addresses\n"
" {\n"
" \"address\": \"xxxx\", (string) network address\n"
@@ -441,8 +455,7 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp)
UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("version", CLIENT_VERSION));
- obj.push_back(Pair("subversion",
- FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>())));
+ obj.push_back(Pair("subversion", strSubVersion));
obj.push_back(Pair("protocolversion",PROTOCOL_VERSION));
obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices)));
obj.push_back(Pair("timeoffset", GetTimeOffset()));
@@ -528,6 +541,8 @@ UniValue setban(const UniValue& params, bool fHelp)
}
DumpBanlist(); //store banlist to disk
+ uiInterface.BannedListChanged();
+
return NullUniValue;
}
@@ -574,6 +589,7 @@ UniValue clearbanned(const UniValue& params, bool fHelp)
CNode::ClearBanned();
DumpBanlist(); //store banlist to disk
+ uiInterface.BannedListChanged();
return NullUniValue;
}
diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp
index 2e5c913734..d83cd87f94 100644
--- a/src/rpcprotocol.cpp
+++ b/src/rpcprotocol.cpp
@@ -5,7 +5,6 @@
#include "rpcprotocol.h"
-#include "clientversion.h"
#include "random.h"
#include "tinyformat.h"
#include "util.h"
@@ -16,236 +15,8 @@
#include <stdint.h>
#include <fstream>
-#include <boost/algorithm/string.hpp>
-#include <boost/asio.hpp>
-#include <boost/asio/ssl.hpp>
-#include <boost/bind.hpp>
-#include <boost/filesystem.hpp>
-#include <boost/foreach.hpp>
-#include <boost/iostreams/concepts.hpp>
-#include <boost/iostreams/stream.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include "univalue/univalue.h"
-
using namespace std;
-//! Number of bytes to allocate and read at most at once in post data
-const size_t POST_READ_SIZE = 256 * 1024;
-
-/**
- * HTTP protocol
- *
- * This ain't Apache. We're just using HTTP header for the length field
- * and to be compatible with other JSON-RPC implementations.
- */
-
-string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeaders)
-{
- ostringstream s;
- s << "POST / HTTP/1.1\r\n"
- << "User-Agent: bitcoin-json-rpc/" << FormatFullVersion() << "\r\n"
- << "Host: 127.0.0.1\r\n"
- << "Content-Type: application/json\r\n"
- << "Content-Length: " << strMsg.size() << "\r\n"
- << "Connection: close\r\n"
- << "Accept: application/json\r\n";
- BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders)
- s << item.first << ": " << item.second << "\r\n";
- s << "\r\n" << strMsg;
-
- return s.str();
-}
-
-static string rfc1123Time()
-{
- return DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", GetTime());
-}
-
-static const char *httpStatusDescription(int nStatus)
-{
- switch (nStatus) {
- case HTTP_OK: return "OK";
- case HTTP_BAD_REQUEST: return "Bad Request";
- case HTTP_FORBIDDEN: return "Forbidden";
- case HTTP_NOT_FOUND: return "Not Found";
- case HTTP_INTERNAL_SERVER_ERROR: return "Internal Server Error";
- default: return "";
- }
-}
-
-string HTTPError(int nStatus, bool keepalive, bool headersOnly)
-{
- if (nStatus == HTTP_UNAUTHORIZED)
- return strprintf("HTTP/1.0 401 Authorization Required\r\n"
- "Date: %s\r\n"
- "Server: bitcoin-json-rpc/%s\r\n"
- "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
- "Content-Type: text/html\r\n"
- "Content-Length: 296\r\n"
- "\r\n"
- "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
- "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
- "<HTML>\r\n"
- "<HEAD>\r\n"
- "<TITLE>Error</TITLE>\r\n"
- "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
- "</HEAD>\r\n"
- "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
- "</HTML>\r\n", rfc1123Time(), FormatFullVersion());
-
- return HTTPReply(nStatus, httpStatusDescription(nStatus), keepalive,
- headersOnly, "text/plain");
-}
-
-string HTTPReplyHeader(int nStatus, bool keepalive, size_t contentLength, const char *contentType)
-{
- return strprintf(
- "HTTP/1.1 %d %s\r\n"
- "Date: %s\r\n"
- "Connection: %s\r\n"
- "Content-Length: %u\r\n"
- "Content-Type: %s\r\n"
- "Server: bitcoin-json-rpc/%s\r\n"
- "\r\n",
- nStatus,
- httpStatusDescription(nStatus),
- rfc1123Time(),
- keepalive ? "keep-alive" : "close",
- contentLength,
- contentType,
- FormatFullVersion());
-}
-
-string HTTPReply(int nStatus, const string& strMsg, bool keepalive,
- bool headersOnly, const char *contentType)
-{
- if (headersOnly)
- {
- return HTTPReplyHeader(nStatus, keepalive, 0, contentType);
- } else {
- return HTTPReplyHeader(nStatus, keepalive, strMsg.size(), contentType) + strMsg;
- }
-}
-
-bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto,
- string& http_method, string& http_uri)
-{
- string str;
- getline(stream, str);
-
- // HTTP request line is space-delimited
- vector<string> vWords;
- boost::split(vWords, str, boost::is_any_of(" "));
- if (vWords.size() < 2)
- return false;
-
- // HTTP methods permitted: GET, POST
- http_method = vWords[0];
- if (http_method != "GET" && http_method != "POST")
- return false;
-
- // HTTP URI must be an absolute path, relative to current host
- http_uri = vWords[1];
- if (http_uri.size() == 0 || http_uri[0] != '/')
- return false;
-
- // parse proto, if present
- string strProto = "";
- if (vWords.size() > 2)
- strProto = vWords[2];
-
- proto = 0;
- const char *ver = strstr(strProto.c_str(), "HTTP/1.");
- if (ver != NULL)
- proto = atoi(ver+7);
-
- return true;
-}
-
-int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto)
-{
- string str;
- getline(stream, str);
- vector<string> vWords;
- boost::split(vWords, str, boost::is_any_of(" "));
- if (vWords.size() < 2)
- return HTTP_INTERNAL_SERVER_ERROR;
- proto = 0;
- const char *ver = strstr(str.c_str(), "HTTP/1.");
- if (ver != NULL)
- proto = atoi(ver+7);
- return atoi(vWords[1].c_str());
-}
-
-int ReadHTTPHeaders(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet)
-{
- int nLen = 0;
- while (true)
- {
- string str;
- std::getline(stream, str);
- if (str.empty() || str == "\r")
- break;
- string::size_type nColon = str.find(":");
- if (nColon != string::npos)
- {
- string strHeader = str.substr(0, nColon);
- boost::trim(strHeader);
- boost::to_lower(strHeader);
- string strValue = str.substr(nColon+1);
- boost::trim(strValue);
- mapHeadersRet[strHeader] = strValue;
- if (strHeader == "content-length")
- nLen = atoi(strValue.c_str());
- }
- }
- return nLen;
-}
-
-
-int ReadHTTPMessage(std::basic_istream<char>& stream, map<string,
- string>& mapHeadersRet, string& strMessageRet,
- int nProto, size_t max_size)
-{
- mapHeadersRet.clear();
- strMessageRet = "";
-
- // Read header
- int nLen = ReadHTTPHeaders(stream, mapHeadersRet);
- if (nLen < 0 || (size_t)nLen > max_size)
- return HTTP_INTERNAL_SERVER_ERROR;
-
- // Read message
- if (nLen > 0)
- {
- vector<char> vch;
- size_t ptr = 0;
- while (ptr < (size_t)nLen)
- {
- size_t bytes_to_read = std::min((size_t)nLen - ptr, POST_READ_SIZE);
- vch.resize(ptr + bytes_to_read);
- stream.read(&vch[ptr], bytes_to_read);
- if (!stream) // Connection lost while reading
- return HTTP_INTERNAL_SERVER_ERROR;
- ptr += bytes_to_read;
- }
- strMessageRet = string(vch.begin(), vch.end());
- }
-
- string sConHdr = mapHeadersRet["connection"];
-
- if ((sConHdr != "close") && (sConHdr != "keep-alive"))
- {
- if (nProto >= 1)
- mapHeadersRet["connection"] = "keep-alive";
- else
- mapHeadersRet["connection"] = "close";
- }
-
- return HTTP_OK;
-}
-
/**
* JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility,
* but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h
index 2360ec2c60..9cf1ab6d99 100644
--- a/src/rpcprotocol.h
+++ b/src/rpcprotocol.h
@@ -10,13 +10,9 @@
#include <map>
#include <stdint.h>
#include <string>
-#include <boost/iostreams/concepts.hpp>
-#include <boost/iostreams/stream.hpp>
-#include <boost/asio.hpp>
-#include <boost/asio/ssl.hpp>
#include <boost/filesystem.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
//! HTTP status codes
enum HTTPStatusCode
@@ -26,6 +22,7 @@ enum HTTPStatusCode
HTTP_UNAUTHORIZED = 401,
HTTP_FORBIDDEN = 403,
HTTP_NOT_FOUND = 404,
+ HTTP_BAD_METHOD = 405,
HTTP_INTERNAL_SERVER_ERROR = 500,
HTTP_SERVICE_UNAVAILABLE = 503,
};
@@ -79,88 +76,6 @@ enum RPCErrorCode
RPC_WALLET_ALREADY_UNLOCKED = -17, //! Wallet is already unlocked
};
-/**
- * IOStream device that speaks SSL but can also speak non-SSL
- */
-template <typename Protocol>
-class SSLIOStreamDevice : public boost::iostreams::device<boost::iostreams::bidirectional> {
-public:
- SSLIOStreamDevice(boost::asio::ssl::stream<typename Protocol::socket> &streamIn, bool fUseSSLIn) : stream(streamIn)
- {
- fUseSSL = fUseSSLIn;
- fNeedHandshake = fUseSSLIn;
- }
-
- void handshake(boost::asio::ssl::stream_base::handshake_type role)
- {
- if (!fNeedHandshake) return;
- fNeedHandshake = false;
- stream.handshake(role);
- }
- std::streamsize read(char* s, std::streamsize n)
- {
- handshake(boost::asio::ssl::stream_base::server); // HTTPS servers read first
- if (fUseSSL) return stream.read_some(boost::asio::buffer(s, n));
- return stream.next_layer().read_some(boost::asio::buffer(s, n));
- }
- std::streamsize write(const char* s, std::streamsize n)
- {
- handshake(boost::asio::ssl::stream_base::client); // HTTPS clients write first
- if (fUseSSL) return boost::asio::write(stream, boost::asio::buffer(s, n));
- return boost::asio::write(stream.next_layer(), boost::asio::buffer(s, n));
- }
- bool connect(const std::string& server, const std::string& port)
- {
- using namespace boost::asio::ip;
- tcp::resolver resolver(stream.get_io_service());
- tcp::resolver::iterator endpoint_iterator;
-#if BOOST_VERSION >= 104300
- try {
-#endif
- // The default query (flags address_configured) tries IPv6 if
- // non-localhost IPv6 configured, and IPv4 if non-localhost IPv4
- // configured.
- tcp::resolver::query query(server.c_str(), port.c_str());
- endpoint_iterator = resolver.resolve(query);
-#if BOOST_VERSION >= 104300
- } catch (const boost::system::system_error&) {
- // If we at first don't succeed, try blanket lookup (IPv4+IPv6 independent of configured interfaces)
- tcp::resolver::query query(server.c_str(), port.c_str(), resolver_query_base::flags());
- endpoint_iterator = resolver.resolve(query);
- }
-#endif
- boost::system::error_code error = boost::asio::error::host_not_found;
- tcp::resolver::iterator end;
- while (error && endpoint_iterator != end)
- {
- stream.lowest_layer().close();
- stream.lowest_layer().connect(*endpoint_iterator++, error);
- }
- if (error)
- return false;
- return true;
- }
-
-private:
- bool fNeedHandshake;
- bool fUseSSL;
- boost::asio::ssl::stream<typename Protocol::socket>& stream;
-};
-
-std::string HTTPPost(const std::string& strMsg, const std::map<std::string,std::string>& mapRequestHeaders);
-std::string HTTPError(int nStatus, bool keepalive,
- bool headerOnly = false);
-std::string HTTPReplyHeader(int nStatus, bool keepalive, size_t contentLength,
- const char *contentType = "application/json");
-std::string HTTPReply(int nStatus, const std::string& strMsg, bool keepalive,
- bool headerOnly = false,
- const char *contentType = "application/json");
-bool ReadHTTPRequestLine(std::basic_istream<char>& stream, int &proto,
- std::string& http_method, std::string& http_uri);
-int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto);
-int ReadHTTPHeaders(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet);
-int ReadHTTPMessage(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet,
- std::string& strMessageRet, int nProto, size_t max_size);
std::string JSONRPCRequest(const std::string& strMethod, const UniValue& params, const UniValue& id);
UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id);
std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id);
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index 7d1db0b60e..5f3363d097 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -4,6 +4,8 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "base58.h"
+#include "chain.h"
+#include "coins.h"
#include "consensus/validation.h"
#include "core_io.h"
#include "init.h"
@@ -18,7 +20,9 @@
#include "script/script_error.h"
#include "script/sign.h"
#include "script/standard.h"
+#include "txmempool.h"
#include "uint256.h"
+#include "utilstrencodings.h"
#ifdef ENABLE_WALLET
#include "wallet/wallet.h"
#endif
@@ -27,7 +31,7 @@
#include <boost/assign/list_of.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -37,7 +41,7 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud
vector<CTxDestination> addresses;
int nRequired;
- out.push_back(Pair("asm", scriptPubKey.ToString()));
+ out.push_back(Pair("asm", ScriptToAsmStr(scriptPubKey)));
if (fIncludeHex)
out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
@@ -69,7 +73,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
in.push_back(Pair("vout", (int64_t)txin.prevout.n));
UniValue o(UniValue::VOBJ);
- o.push_back(Pair("asm", txin.scriptSig.ToString()));
+ o.push_back(Pair("asm", ScriptToAsmStr(txin.scriptSig, true)));
o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
in.push_back(Pair("scriptSig", o));
}
@@ -145,7 +149,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp)
" ],\n"
" \"vout\" : [ (array of json objects)\n"
" {\n"
- " \"value\" : x.xxx, (numeric) The value in btc\n"
+ " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
" \"n\" : n, (numeric) index\n"
" \"scriptPubKey\" : { (json object)\n"
" \"asm\" : \"asm\", (string) the asm\n"
@@ -312,10 +316,11 @@ 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,...}\n"
- "\nCreate a transaction spending the given inputs and sending to the given addresses.\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"
"Note that the transaction's inputs are not signed, and\n"
"it is not stored in the wallet or transmitted to the network.\n"
@@ -324,33 +329,45 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp)
"1. \"transactions\" (string, required) A json array of json objects\n"
" [\n"
" {\n"
- " \"txid\":\"id\", (string, required) The transaction id\n"
+ " \"txid\":\"id\", (string, required) The transaction id\n"
" \"vout\":n (numeric, required) The output number\n"
" }\n"
" ,...\n"
" ]\n"
- "2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n"
+ "2. \"outputs\" (string, required) a json object with outputs\n"
" {\n"
- " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the btc amount\n"
- " ,...\n"
+ " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the " + CURRENCY_UNIT + " amount\n"
+ " \"data\": \"hex\", (string, required) The key is \"data\", the value is hex encoded data\n"
+ " ...\n"
" }\n"
-
+ "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"
"\nExamples\n"
+ HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"address\\\":0.01}\"")
+ + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"{\\\"data\\\":\\\"00010203\\\"}\"")
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
+ + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"")
);
LOCK(cs_main);
- RPCTypeCheck(params, boost::assign::list_of(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();
@@ -364,26 +381,36 @@ 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);
}
set<CBitcoinAddress> setAddress;
vector<string> addrList = sendTo.getKeys();
BOOST_FOREACH(const string& name_, addrList) {
- CBitcoinAddress address(name_);
- if (!address.IsValid())
- throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_);
- if (setAddress.count(address))
- throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_);
- setAddress.insert(address);
+ if (name_ == "data") {
+ std::vector<unsigned char> data = ParseHexV(sendTo[name_].getValStr(),"Data");
+
+ CTxOut out(0, CScript() << OP_RETURN << data);
+ rawTx.vout.push_back(out);
+ } else {
+ CBitcoinAddress address(name_);
+ if (!address.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_);
- CScript scriptPubKey = GetScriptForDestination(address.Get());
- CAmount nAmount = AmountFromValue(sendTo[name_]);
+ if (setAddress.count(address))
+ throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_);
+ setAddress.insert(address);
- CTxOut out(nAmount, scriptPubKey);
- rawTx.vout.push_back(out);
+ CScript scriptPubKey = GetScriptForDestination(address.Get());
+ CAmount nAmount = AmountFromValue(sendTo[name_]);
+
+ CTxOut out(nAmount, scriptPubKey);
+ rawTx.vout.push_back(out);
+ }
}
return EncodeHexTx(rawTx);
@@ -418,7 +445,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp)
" ],\n"
" \"vout\" : [ (array of json objects)\n"
" {\n"
- " \"value\" : x.xxx, (numeric) The value in btc\n"
+ " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
" \"n\" : n, (numeric) index\n"
" \"scriptPubKey\" : { (json object)\n"
" \"asm\" : \"asm\", (string) the asm\n"
@@ -661,8 +688,8 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
CCoinsModifier coins = view.ModifyCoins(txid);
if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) {
string err("Previous output scriptPubKey mismatch:\n");
- err = err + coins->vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+
- scriptPubKey.ToString();
+ err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+
+ ScriptToAsmStr(scriptPubKey);
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
}
if ((unsigned int)nOut >= coins->vout.size())
@@ -794,7 +821,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 bcad06a0c1..fa60f8c833 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -11,15 +11,10 @@
#include "sync.h"
#include "ui_interface.h"
#include "util.h"
-#include "utilmoneystr.h"
#include "utilstrencodings.h"
-#ifdef ENABLE_WALLET
-#include "wallet/wallet.h"
-#endif
-#include <boost/algorithm/string.hpp>
-#include <boost/asio.hpp>
-#include <boost/asio/ssl.hpp>
+#include <univalue.h>
+
#include <boost/bind.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
@@ -28,28 +23,20 @@
#include <boost/shared_ptr.hpp>
#include <boost/signals2/signal.hpp>
#include <boost/thread.hpp>
+#include <boost/algorithm/string/case_conv.hpp> // for to_upper()
-#include "univalue/univalue.h"
-
-using namespace boost::asio;
using namespace RPCServer;
using namespace std;
-static std::string strRPCUserColonPass;
-
static bool fRPCRunning = false;
static bool fRPCInWarmup = true;
static std::string rpcWarmupStatus("RPC server started");
static CCriticalSection cs_rpcWarmup;
-
-//! These are created by StartRPCThreads, destroyed in StopRPCThreads
-static boost::asio::io_service* rpc_io_service = NULL;
-static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers;
-static ssl::context* rpc_ssl_context = NULL;
-static boost::thread_group* rpc_worker_group = NULL;
-static boost::asio::io_service::work *rpc_dummy_work = NULL;
-static std::vector<CSubNet> rpc_allow_subnets; //!< List of subnets to allow RPC connections from
-static std::vector< boost::shared_ptr<ip::tcp::acceptor> > rpc_acceptors;
+/* Timer-creating functions */
+static std::vector<RPCTimerInterface*> timerInterfaces;
+/* Map of name to timer.
+ * @note Can be changed to std::unique_ptr when C++11 */
+static std::map<std::string, boost::shared_ptr<RPCTimerBase> > deadlineTimers;
static struct CRPCSignals
{
@@ -121,8 +108,8 @@ void RPCTypeCheckObj(const UniValue& o,
CAmount AmountFromValue(const UniValue& value)
{
- if (!value.isReal() && !value.isNum())
- throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number");
+ if (!value.isNum() && !value.isStr())
+ throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string");
CAmount amount;
if (!ParseFixedPoint(value.getValStr(), 8, &amount))
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
@@ -133,7 +120,12 @@ CAmount AmountFromValue(const UniValue& value)
UniValue ValueFromAmount(const CAmount& amount)
{
- return UniValue(UniValue::VREAL, FormatMoney(amount));
+ bool sign = amount < 0;
+ int64_t n_abs = (sign ? -amount : amount);
+ int64_t quotient = n_abs / COIN;
+ int64_t remainder = n_abs % COIN;
+ return UniValue(UniValue::VNUM,
+ strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder));
}
uint256 ParseHashV(const UniValue& v, string strName)
@@ -165,7 +157,6 @@ vector<unsigned char> ParseHexO(const UniValue& o, string strKey)
return ParseHexV(find_value(o, strKey), strKey);
}
-
/**
* Note: This interface may still be subject to change.
*/
@@ -252,13 +243,12 @@ UniValue stop(const UniValue& params, bool fHelp)
throw runtime_error(
"stop\n"
"\nStop Bitcoin server.");
- // Shutdown will take long enough that the response should get back
+ // Event loop will exit after current HTTP requests have been handled, so
+ // this reply will get back to the client.
StartShutdown();
return "Bitcoin server stopping";
}
-
-
/**
* Call Table
*/
@@ -359,6 +349,7 @@ static const CRPCCommand vRPCCommands[] =
{ "wallet", "importprivkey", &importprivkey, true },
{ "wallet", "importwallet", &importwallet, true },
{ "wallet", "importaddress", &importaddress, true },
+ { "wallet", "importpubkey", &importpubkey, true },
{ "wallet", "keypoolrefill", &keypoolrefill, true },
{ "wallet", "listaccounts", &listaccounts, false },
{ "wallet", "listaddressgroupings", &listaddressgroupings, false },
@@ -394,7 +385,7 @@ CRPCTable::CRPCTable()
}
}
-const CRPCCommand *CRPCTable::operator[](const std::string& name) const
+const CRPCCommand *CRPCTable::operator[](const std::string &name) const
{
map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
if (it == mapCommands.end())
@@ -402,373 +393,26 @@ const CRPCCommand *CRPCTable::operator[](const std::string& name) const
return (*it).second;
}
-
-bool HTTPAuthorized(map<string, string>& mapHeaders)
-{
- string strAuth = mapHeaders["authorization"];
- if (strAuth.substr(0,6) != "Basic ")
- return false;
- string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
- string strUserPass = DecodeBase64(strUserPass64);
- return TimingResistantEqual(strUserPass, strRPCUserColonPass);
-}
-
-void ErrorReply(std::ostream& stream, const UniValue& objError, const UniValue& id)
-{
- // Send error reply from json-rpc error object
- int nStatus = HTTP_INTERNAL_SERVER_ERROR;
- int code = find_value(objError, "code").get_int();
- if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST;
- else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND;
- string strReply = JSONRPCReply(NullUniValue, objError, id);
- stream << HTTPReply(nStatus, strReply, false) << std::flush;
-}
-
-CNetAddr BoostAsioToCNetAddr(boost::asio::ip::address address)
-{
- CNetAddr netaddr;
- // Make sure that IPv4-compatible and IPv4-mapped IPv6 addresses are treated as IPv4 addresses
- if (address.is_v6()
- && (address.to_v6().is_v4_compatible()
- || address.to_v6().is_v4_mapped()))
- address = address.to_v6().to_v4();
-
- if(address.is_v4())
- {
- boost::asio::ip::address_v4::bytes_type bytes = address.to_v4().to_bytes();
- netaddr.SetRaw(NET_IPV4, &bytes[0]);
- }
- else
- {
- boost::asio::ip::address_v6::bytes_type bytes = address.to_v6().to_bytes();
- netaddr.SetRaw(NET_IPV6, &bytes[0]);
- }
- return netaddr;
-}
-
-bool ClientAllowed(const boost::asio::ip::address& address)
-{
- CNetAddr netaddr = BoostAsioToCNetAddr(address);
- BOOST_FOREACH(const CSubNet &subnet, rpc_allow_subnets)
- if (subnet.Match(netaddr))
- return true;
- return false;
-}
-
-template <typename Protocol>
-class AcceptedConnectionImpl : public AcceptedConnection
+bool StartRPC()
{
-public:
- AcceptedConnectionImpl(
- boost::asio::io_service& io_service,
- ssl::context &context,
- bool fUseSSL) :
- sslStream(io_service, context),
- _d(sslStream, fUseSSL),
- _stream(_d)
- {
- }
-
- virtual std::iostream& stream()
- {
- return _stream;
- }
-
- virtual std::string peer_address_to_string() const
- {
- return peer.address().to_string();
- }
-
- virtual void close()
- {
- _stream.close();
- }
-
- typename Protocol::endpoint peer;
- boost::asio::ssl::stream<typename Protocol::socket> sslStream;
-
-private:
- SSLIOStreamDevice<Protocol> _d;
- boost::iostreams::stream< SSLIOStreamDevice<Protocol> > _stream;
-};
-
-void ServiceConnection(AcceptedConnection *conn);
-
-//! Forward declaration required for RPCListen
-template <typename Protocol, typename SocketAcceptorService>
-static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
- ssl::context& context,
- bool fUseSSL,
- boost::shared_ptr< AcceptedConnection > conn,
- const boost::system::error_code& error);
-
-/**
- * Sets up I/O resources to accept and handle a new connection.
- */
-template <typename Protocol, typename SocketAcceptorService>
-static void RPCListen(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
- ssl::context& context,
- const bool fUseSSL)
-{
- // Accept connection
- boost::shared_ptr< AcceptedConnectionImpl<Protocol> > conn(new AcceptedConnectionImpl<Protocol>(acceptor->get_io_service(), context, fUseSSL));
-
- acceptor->async_accept(
- conn->sslStream.lowest_layer(),
- conn->peer,
- boost::bind(&RPCAcceptHandler<Protocol, SocketAcceptorService>,
- acceptor,
- boost::ref(context),
- fUseSSL,
- conn,
- _1));
-}
-
-
-/**
- * Accept and handle incoming connection.
- */
-template <typename Protocol, typename SocketAcceptorService>
-static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
- ssl::context& context,
- const bool fUseSSL,
- boost::shared_ptr< AcceptedConnection > conn,
- const boost::system::error_code& error)
-{
- // Immediately start accepting new connections, except when we're cancelled or our socket is closed.
- if (error != boost::asio::error::operation_aborted && acceptor->is_open())
- RPCListen(acceptor, context, fUseSSL);
-
- AcceptedConnectionImpl<ip::tcp>* tcp_conn = dynamic_cast< AcceptedConnectionImpl<ip::tcp>* >(conn.get());
-
- if (error)
- {
- // TODO: Actually handle errors
- LogPrintf("%s: Error: %s\n", __func__, error.message());
- }
- // Restrict callers by IP. It is important to
- // do this before starting client thread, to filter out
- // certain DoS and misbehaving clients.
- else if (tcp_conn && !ClientAllowed(tcp_conn->peer.address()))
- {
- // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
- if (!fUseSSL)
- conn->stream() << HTTPError(HTTP_FORBIDDEN, false) << std::flush;
- conn->close();
- }
- else {
- ServiceConnection(conn.get());
- conn->close();
- }
-}
-
-static ip::tcp::endpoint ParseEndpoint(const std::string &strEndpoint, int defaultPort)
-{
- std::string addr;
- int port = defaultPort;
- SplitHostPort(strEndpoint, port, addr);
- return ip::tcp::endpoint(boost::asio::ip::address::from_string(addr), port);
-}
-
-void StartRPCThreads()
-{
- rpc_allow_subnets.clear();
- rpc_allow_subnets.push_back(CSubNet("127.0.0.0/8")); // always allow IPv4 local subnet
- rpc_allow_subnets.push_back(CSubNet("::1")); // always allow IPv6 localhost
- if (mapMultiArgs.count("-rpcallowip"))
- {
- const vector<string>& vAllow = mapMultiArgs["-rpcallowip"];
- BOOST_FOREACH(string strAllow, vAllow)
- {
- CSubNet subnet(strAllow);
- if(!subnet.IsValid())
- {
- uiInterface.ThreadSafeMessageBox(
- strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow),
- "", CClientUIInterface::MSG_ERROR);
- StartShutdown();
- return;
- }
- rpc_allow_subnets.push_back(subnet);
- }
- }
- std::string strAllowed;
- BOOST_FOREACH(const CSubNet &subnet, rpc_allow_subnets)
- strAllowed += subnet.ToString() + " ";
- LogPrint("rpc", "Allowing RPC connections from: %s\n", strAllowed);
-
- if (mapArgs["-rpcpassword"] == "")
- {
- LogPrintf("No rpcpassword set - using random cookie authentication\n");
- if (!GenerateAuthCookie(&strRPCUserColonPass)) {
- uiInterface.ThreadSafeMessageBox(
- _("Error: A fatal internal error occured, see debug.log for details"), // Same message as AbortNode
- "", CClientUIInterface::MSG_ERROR);
- StartShutdown();
- return;
- }
- } else {
- strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
- }
-
- assert(rpc_io_service == NULL);
- rpc_io_service = new boost::asio::io_service();
- rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23);
-
- const bool fUseSSL = GetBoolArg("-rpcssl", false);
-
- if (fUseSSL)
- {
- rpc_ssl_context->set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3);
-
- boost::filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
- if (!pathCertFile.is_complete()) pathCertFile = boost::filesystem::path(GetDataDir()) / pathCertFile;
- if (boost::filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string());
- else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string());
-
- boost::filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
- if (!pathPKFile.is_complete()) pathPKFile = boost::filesystem::path(GetDataDir()) / pathPKFile;
- if (boost::filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem);
- else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string());
-
- string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH");
- SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str());
- }
-
- std::vector<ip::tcp::endpoint> vEndpoints;
- bool bBindAny = false;
- int defaultPort = GetArg("-rpcport", BaseParams().RPCPort());
- if (!mapArgs.count("-rpcallowip")) // Default to loopback if not allowing external IPs
- {
- vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::loopback(), defaultPort));
- vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::loopback(), defaultPort));
- if (mapArgs.count("-rpcbind"))
- {
- LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n");
- }
- } else if (mapArgs.count("-rpcbind")) // Specific bind address
- {
- BOOST_FOREACH(const std::string &addr, mapMultiArgs["-rpcbind"])
- {
- try {
- vEndpoints.push_back(ParseEndpoint(addr, defaultPort));
- }
- catch (const boost::system::system_error&)
- {
- uiInterface.ThreadSafeMessageBox(
- strprintf(_("Could not parse -rpcbind value %s as network address"), addr),
- "", CClientUIInterface::MSG_ERROR);
- StartShutdown();
- return;
- }
- }
- } else { // No specific bind address specified, bind to any
- vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::any(), defaultPort));
- vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::any(), defaultPort));
- // Prefer making the socket dual IPv6/IPv4 instead of binding
- // to both addresses seperately.
- bBindAny = true;
- }
-
- bool fListening = false;
- std::string strerr;
- std::string straddress;
- BOOST_FOREACH(const ip::tcp::endpoint &endpoint, vEndpoints)
- {
- try {
- boost::asio::ip::address bindAddress = endpoint.address();
- straddress = bindAddress.to_string();
- LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", straddress, endpoint.port(), bBindAny);
- boost::system::error_code v6_only_error;
- boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service));
-
- acceptor->open(endpoint.protocol());
- acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
-
- // Try making the socket dual IPv6/IPv4 when listening on the IPv6 "any" address
- acceptor->set_option(boost::asio::ip::v6_only(
- !bBindAny || bindAddress != boost::asio::ip::address_v6::any()), v6_only_error);
-
- acceptor->bind(endpoint);
- acceptor->listen(socket_base::max_connections);
-
- RPCListen(acceptor, *rpc_ssl_context, fUseSSL);
-
- fListening = true;
- rpc_acceptors.push_back(acceptor);
- // If dual IPv6/IPv4 bind successful, skip binding to IPv4 separately
- if(bBindAny && bindAddress == boost::asio::ip::address_v6::any() && !v6_only_error)
- break;
- }
- catch (const boost::system::system_error& e)
- {
- LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", straddress, endpoint.port(), e.what());
- strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), straddress, endpoint.port(), e.what());
- }
- }
-
- if (!fListening) {
- uiInterface.ThreadSafeMessageBox(strerr, "", CClientUIInterface::MSG_ERROR);
- StartShutdown();
- return;
- }
-
- rpc_worker_group = new boost::thread_group();
- for (int i = 0; i < GetArg("-rpcthreads", 4); i++)
- rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service));
+ LogPrint("rpc", "Starting RPC\n");
fRPCRunning = true;
g_rpcSignals.Started();
+ return true;
}
-void StartDummyRPCThread()
+void InterruptRPC()
{
- if(rpc_io_service == NULL)
- {
- rpc_io_service = new boost::asio::io_service();
- /* Create dummy "work" to keep the thread from exiting when no timeouts active,
- * see http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.stopping_the_io_service_from_running_out_of_work */
- rpc_dummy_work = new boost::asio::io_service::work(*rpc_io_service);
- rpc_worker_group = new boost::thread_group();
- rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service));
- fRPCRunning = true;
- }
+ LogPrint("rpc", "Interrupting RPC\n");
+ // Interrupt e.g. running longpolls
+ fRPCRunning = false;
}
-void StopRPCThreads()
+void StopRPC()
{
- if (rpc_io_service == NULL) return;
- // Set this to false first, so that longpolling loops will exit when woken up
- fRPCRunning = false;
-
- // First, cancel all timers and acceptors
- // This is not done automatically by ->stop(), and in some cases the destructor of
- // boost::asio::io_service can hang if this is skipped.
- boost::system::error_code ec;
- BOOST_FOREACH(const boost::shared_ptr<ip::tcp::acceptor> &acceptor, rpc_acceptors)
- {
- acceptor->cancel(ec);
- if (ec)
- LogPrintf("%s: Warning: %s when cancelling acceptor", __func__, ec.message());
- }
- rpc_acceptors.clear();
- BOOST_FOREACH(const PAIRTYPE(std::string, boost::shared_ptr<deadline_timer>) &timer, deadlineTimers)
- {
- timer.second->cancel(ec);
- if (ec)
- LogPrintf("%s: Warning: %s when cancelling timer", __func__, ec.message());
- }
+ LogPrint("rpc", "Stopping RPC\n");
deadlineTimers.clear();
-
- DeleteAuthCookie();
-
- rpc_io_service->stop();
g_rpcSignals.Stopped();
- if (rpc_worker_group != NULL)
- rpc_worker_group->join_all();
- delete rpc_dummy_work; rpc_dummy_work = NULL;
- delete rpc_worker_group; rpc_worker_group = NULL;
- delete rpc_ssl_context; rpc_ssl_context = NULL;
- delete rpc_io_service; rpc_io_service = NULL;
}
bool IsRPCRunning()
@@ -797,36 +441,6 @@ bool RPCIsInWarmup(std::string *outStatus)
return fRPCInWarmup;
}
-void RPCRunHandler(const boost::system::error_code& err, boost::function<void(void)> func)
-{
- if (!err)
- func();
-}
-
-void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds)
-{
- assert(rpc_io_service != NULL);
-
- if (deadlineTimers.count(name) == 0)
- {
- deadlineTimers.insert(make_pair(name,
- boost::shared_ptr<deadline_timer>(new deadline_timer(*rpc_io_service))));
- }
- deadlineTimers[name]->expires_from_now(boost::posix_time::seconds(nSeconds));
- deadlineTimers[name]->async_wait(boost::bind(RPCRunHandler, _1, func));
-}
-
-class JSONRequest
-{
-public:
- UniValue id;
- string strMethod;
- UniValue params;
-
- JSONRequest() { id = NullUniValue; }
- void parse(const UniValue& valRequest);
-};
-
void JSONRequest::parse(const UniValue& valRequest)
{
// Parse request
@@ -857,7 +471,6 @@ void JSONRequest::parse(const UniValue& valRequest)
throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array");
}
-
static UniValue JSONRPCExecOne(const UniValue& req)
{
UniValue rpc_result(UniValue::VOBJ);
@@ -882,7 +495,7 @@ static UniValue JSONRPCExecOne(const UniValue& req)
return rpc_result;
}
-static string JSONRPCExecBatch(const UniValue& vReq)
+std::string JSONRPCExecBatch(const UniValue& vReq)
{
UniValue ret(UniValue::VARR);
for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++)
@@ -891,107 +504,6 @@ static string JSONRPCExecBatch(const UniValue& vReq)
return ret.write() + "\n";
}
-static bool HTTPReq_JSONRPC(AcceptedConnection *conn,
- string& strRequest,
- map<string, string>& mapHeaders,
- bool fRun)
-{
- // Check authorization
- if (mapHeaders.count("authorization") == 0)
- {
- conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush;
- return false;
- }
-
- if (!HTTPAuthorized(mapHeaders))
- {
- LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string());
- /* Deter brute-forcing
- We don't support exposing the RPC port, so this shouldn't result
- in a DoS. */
- MilliSleep(250);
-
- conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush;
- return false;
- }
-
- JSONRequest jreq;
- try
- {
- // Parse request
- UniValue valRequest;
- if (!valRequest.read(strRequest))
- throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
-
- string strReply;
-
- // singleton request
- if (valRequest.isObject()) {
- jreq.parse(valRequest);
-
- UniValue result = tableRPC.execute(jreq.strMethod, jreq.params);
-
- // Send reply
- strReply = JSONRPCReply(result, NullUniValue, jreq.id);
-
- // array of requests
- } else if (valRequest.isArray())
- strReply = JSONRPCExecBatch(valRequest.get_array());
- else
- throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
-
- conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, strReply.size()) << strReply << std::flush;
- }
- catch (const UniValue& objError)
- {
- ErrorReply(conn->stream(), objError, jreq.id);
- return false;
- }
- catch (const std::exception& e)
- {
- ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
- return false;
- }
- return true;
-}
-
-void ServiceConnection(AcceptedConnection *conn)
-{
- bool fRun = true;
- while (fRun && !ShutdownRequested())
- {
- int nProto = 0;
- map<string, string> mapHeaders;
- string strRequest, strMethod, strURI;
-
- // Read HTTP request line
- if (!ReadHTTPRequestLine(conn->stream(), nProto, strMethod, strURI))
- break;
-
- // Read HTTP message headers and body
- ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto, MAX_SIZE);
-
- // HTTP Keep-Alive is false; close connection immediately
- if ((mapHeaders["connection"] == "close") || (!GetBoolArg("-rpckeepalive", true)))
- fRun = false;
-
- // Process via JSON-RPC API
- if (strURI == "/") {
- if (!HTTPReq_JSONRPC(conn, strRequest, mapHeaders, fRun))
- break;
-
- // Process via HTTP REST API
- } else if (strURI.substr(0, 6) == "/rest/" && GetBoolArg("-rest", false)) {
- if (!HTTPReq_REST(conn, strURI, strRequest, mapHeaders, fRun))
- break;
-
- } else {
- conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush;
- break;
- }
- }
-}
-
UniValue CRPCTable::execute(const std::string &strMethod, const UniValue &params) const
{
// Return immediately if in warmup
@@ -1032,4 +544,26 @@ 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)
+{
+ timerInterfaces.push_back(iface);
+}
+
+void RPCUnregisterTimerInterface(RPCTimerInterface *iface)
+{
+ std::vector<RPCTimerInterface*>::iterator i = std::find(timerInterfaces.begin(), timerInterfaces.end(), iface);
+ assert(i != timerInterfaces.end());
+ timerInterfaces.erase(i);
+}
+
+void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds)
+{
+ if (timerInterfaces.empty())
+ throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC");
+ deadlineTimers.erase(name);
+ RPCTimerInterface* timerInterface = timerInterfaces[0];
+ LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name());
+ deadlineTimers.insert(std::make_pair(name, timerInterface->NewTimer(func, nSeconds*1000)));
+}
+
const CRPCTable tableRPC;
diff --git a/src/rpcserver.h b/src/rpcserver.h
index 89d3980223..dde8dfdcc3 100644
--- a/src/rpcserver.h
+++ b/src/rpcserver.h
@@ -17,7 +17,7 @@
#include <boost/function.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
class CRPCCommand;
@@ -32,26 +32,17 @@ namespace RPCServer
class CBlockIndex;
class CNetAddr;
-class AcceptedConnection
+class JSONRequest
{
public:
- virtual ~AcceptedConnection() {}
+ UniValue id;
+ std::string strMethod;
+ UniValue params;
- virtual std::iostream& stream() = 0;
- virtual std::string peer_address_to_string() const = 0;
- virtual void close() = 0;
+ JSONRequest() { id = NullUniValue; }
+ void parse(const UniValue& valRequest);
};
-/** Start RPC threads */
-void StartRPCThreads();
-/**
- * Alternative to StartRPCThreads for the GUI, when no server is
- * used. The RPC thread in this case is only used to handle timeouts.
- * If real RPC threads have already been started this is a no-op.
- */
-void StartDummyRPCThread();
-/** Stop RPC threads */
-void StopRPCThreads();
/** Query whether RPC is running */
bool IsRPCRunning();
@@ -81,15 +72,45 @@ void RPCTypeCheck(const UniValue& params,
void RPCTypeCheckObj(const UniValue& o,
const std::map<std::string, UniValue::VType>& typesExpected, bool fAllowNull=false);
+/** Opaque base class for timers returned by NewTimerFunc.
+ * This provides no methods at the moment, but makes sure that delete
+ * cleans up the whole state.
+ */
+class RPCTimerBase
+{
+public:
+ virtual ~RPCTimerBase() {}
+};
+
/**
- * Run func nSeconds from now. Uses boost deadline timers.
+ * RPC timer "driver".
+ */
+class RPCTimerInterface
+{
+public:
+ virtual ~RPCTimerInterface() {}
+ /** Implementation name */
+ virtual const char *Name() = 0;
+ /** Factory function for timers.
+ * RPC will call the function to create a timer that will call func in *millis* milliseconds.
+ * @note As the RPC mechanism is backend-neutral, it can use different implementations of timers.
+ * This is needed to cope with the case in which there is no HTTP server, but
+ * only GUI RPC console, and to break the dependency of pcserver on httprpc.
+ */
+ virtual RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis) = 0;
+};
+
+/** Register factory function for timers */
+void RPCRegisterTimerInterface(RPCTimerInterface *iface);
+/** Unregister factory function for timers */
+void RPCUnregisterTimerInterface(RPCTimerInterface *iface);
+
+/**
+ * Run func nSeconds from now.
* Overrides previous timer <name> (if any).
*/
void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds);
-//! Convert boost::asio address to CNetAddr
-extern CNetAddr BoostAsioToCNetAddr(boost::asio::ip::address address);
-
typedef UniValue(*rpcfn_type)(const UniValue& params, bool fHelp);
class CRPCCommand
@@ -134,9 +155,6 @@ extern uint256 ParseHashO(const UniValue& o, std::string strKey);
extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName);
extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
-extern void InitRPCMining();
-extern void ShutdownRPCMining();
-
extern int64_t nWalletUnlockTime;
extern CAmount AmountFromValue(const UniValue& value);
extern UniValue ValueFromAmount(const CAmount& amount);
@@ -161,6 +179,7 @@ extern UniValue clearbanned(const UniValue& params, bool fHelp);
extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
extern UniValue importprivkey(const UniValue& params, bool fHelp);
extern UniValue importaddress(const UniValue& params, bool fHelp);
+extern UniValue importpubkey(const UniValue& params, bool fHelp);
extern UniValue dumpwallet(const UniValue& params, bool fHelp);
extern UniValue importwallet(const UniValue& params, bool fHelp);
@@ -243,11 +262,9 @@ extern UniValue getchaintips(const UniValue& params, bool fHelp);
extern UniValue invalidateblock(const UniValue& params, bool fHelp);
extern UniValue reconsiderblock(const UniValue& params, bool fHelp);
-// in rest.cpp
-extern bool HTTPReq_REST(AcceptedConnection *conn,
- const std::string& strURI,
- const std::string& strRequest,
- const std::map<std::string, std::string>& mapHeaders,
- bool fRun);
+bool StartRPC();
+void InterruptRPC();
+void StopRPC();
+std::string JSONRPCExecBatch(const UniValue& vReq);
#endif // BITCOIN_RPCSERVER_H
diff --git a/src/scheduler.cpp b/src/scheduler.cpp
index d5bb588b71..184ddc28ab 100644
--- a/src/scheduler.cpp
+++ b/src/scheduler.cpp
@@ -4,6 +4,8 @@
#include "scheduler.h"
+#include "reverselock.h"
+
#include <assert.h>
#include <boost/bind.hpp>
#include <utility>
@@ -65,11 +67,12 @@ void CScheduler::serviceQueue()
Function f = taskQueue.begin()->second;
taskQueue.erase(taskQueue.begin());
- // Unlock before calling f, so it can reschedule itself or another task
- // without deadlocking:
- lock.unlock();
- f();
- lock.lock();
+ {
+ // Unlock before calling f, so it can reschedule itself or another task
+ // without deadlocking:
+ reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
+ f();
+ }
} catch (...) {
--nThreadsServicingQueue;
throw;
diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h
index 0320577797..a48ff1e18d 100644
--- a/src/script/bitcoinconsensus.h
+++ b/src/script/bitcoinconsensus.h
@@ -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 0b78fdf5a8..6a20d497c0 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -188,7 +188,7 @@ bool static IsDefinedHashtypeSignature(const valtype &vchSig) {
return true;
}
-bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) {
+bool CheckSignatureEncoding(const vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror) {
// Empty signature. Not strictly DER encoded, but allowed to provide a
// compact way to provide an invalid signature for use with CHECK(MULTI)SIG
if (vchSig.size() == 0) {
@@ -273,7 +273,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 +869,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;
@@ -1128,7 +1128,7 @@ bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn
bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const
{
- // There are two times of nLockTime: lock-by-blockheight
+ // There are two kinds of nLockTime: lock-by-blockheight
// and lock-by-blocktime, distinguished by whether
// nLockTime < LOCKTIME_THRESHOLD.
//
diff --git a/src/script/interpreter.h b/src/script/interpreter.h
index 35d572f0ad..213e8c7651 100644
--- a/src/script/interpreter.h
+++ b/src/script/interpreter.h
@@ -83,6 +83,8 @@ enum
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9),
};
+bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror);
+
uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
class BaseSignatureChecker
diff --git a/src/script/script.cpp b/src/script/script.cpp
index fd33924732..263c89defe 100644
--- a/src/script/script.cpp
+++ b/src/script/script.cpp
@@ -8,16 +8,6 @@
#include "tinyformat.h"
#include "utilstrencodings.h"
-namespace {
-inline std::string ValueString(const std::vector<unsigned char>& vch)
-{
- if (vch.size() <= 4)
- return strprintf("%d", CScriptNum(vch, false).getint());
- else
- return HexStr(vch);
-}
-} // anon namespace
-
using namespace std;
const char* GetOpName(opcodetype opcode)
@@ -154,7 +144,7 @@ const char* GetOpName(opcodetype opcode)
case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE";
// Note:
- // The template matching params OP_SMALLDATA/etc are defined in opcodetype enum
+ // The template matching params OP_SMALLINTEGER/etc are defined in opcodetype enum
// as kind of implementation hack, they are *NOT* real opcodes. If found in real
// Script, just let the default: case deal with them.
@@ -180,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;
}
@@ -220,9 +210,8 @@ bool CScript::IsPayToScriptHash() const
this->at(22) == OP_EQUAL);
}
-bool CScript::IsPushOnly() const
+bool CScript::IsPushOnly(const_iterator pc) const
{
- const_iterator pc = begin();
while (pc < end())
{
opcodetype opcode;
@@ -238,25 +227,7 @@ bool CScript::IsPushOnly() const
return true;
}
-std::string CScript::ToString() const
+bool CScript::IsPushOnly() const
{
- std::string str;
- opcodetype opcode;
- std::vector<unsigned char> vch;
- const_iterator pc = begin();
- while (pc < end())
- {
- if (!str.empty())
- str += " ";
- if (!GetOp(pc, opcode, vch))
- {
- str += "[error]";
- return str;
- }
- if (0 <= opcode && opcode <= OP_PUSHDATA4)
- str += ValueString(vch);
- else
- str += GetOpName(opcode);
- }
- return str;
+ return this->IsPushOnly(begin());
}
diff --git a/src/script/script.h b/src/script/script.h
index e39ca57f4f..a38d33a189 100644
--- a/src/script/script.h
+++ b/src/script/script.h
@@ -17,7 +17,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.
@@ -167,7 +174,6 @@ enum opcodetype
// template matching params
- OP_SMALLDATA = 0xf9,
OP_SMALLINTEGER = 0xfa,
OP_PUBKEYS = 0xfb,
OP_PUBKEYHASH = 0xfd,
@@ -589,6 +595,7 @@ public:
bool IsPayToScriptHash() const;
/** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */
+ bool IsPushOnly(const_iterator pc) const;
bool IsPushOnly() const;
/**
@@ -601,7 +608,6 @@ public:
return (size() > 0 && *begin() == OP_RETURN);
}
- std::string ToString() const;
void clear()
{
// The default std::vector::clear() does not release memory.
diff --git a/src/script/standard.cpp b/src/script/standard.cpp
index 66657127ab..bfef8afa17 100644
--- a/src/script/standard.cpp
+++ b/src/script/standard.cpp
@@ -51,13 +51,10 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
// Sender provides N pubkeys, receivers provides M signatures
mTemplates.insert(make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG));
-
- // Empty, provably prunable, data-carrying output
- if (GetBoolArg("-datacarrier", true))
- mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN << OP_SMALLDATA));
- mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN));
}
+ vSolutionsRet.clear();
+
// Shortcut for pay-to-script-hash, which are more constrained than the other types:
// it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
if (scriptPubKey.IsPayToScriptHash())
@@ -68,6 +65,16 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
return true;
}
+ // Provably prunable, data-carrying output
+ //
+ // So long as script passes the IsUnspendable() test and all but the first
+ // byte passes the IsPushOnly() test we don't care what exactly is in the
+ // script.
+ if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) {
+ typeRet = TX_NULL_DATA;
+ return true;
+ }
+
// Scan templates
const CScript& script1 = scriptPubKey;
BOOST_FOREACH(const PAIRTYPE(txnouttype, CScript)& tplate, mTemplates)
@@ -140,12 +147,6 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
else
break;
}
- else if (opcode2 == OP_SMALLDATA)
- {
- // small pushdata, <= nMaxDatacarrierBytes
- if (vch1.size() > nMaxDatacarrierBytes)
- break;
- }
else if (opcode1 != opcode2 || vch1 != vch2)
{
// Others must match exactly
@@ -286,6 +287,11 @@ CScript GetScriptForDestination(const CTxDestination& dest)
return script;
}
+CScript GetScriptForRawPubKey(const CPubKey& pubKey)
+{
+ return CScript() << std::vector<unsigned char>(pubKey.begin(), pubKey.end()) << OP_CHECKSIG;
+}
+
CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
{
CScript script;
diff --git a/src/script/standard.h b/src/script/standard.h
index 46ae5f9f10..ae1bbecca0 100644
--- a/src/script/standard.h
+++ b/src/script/standard.h
@@ -25,7 +25,7 @@ public:
CScriptID(const uint160& in) : uint160(in) {}
};
-static const unsigned int MAX_OP_RETURN_RELAY = 80; //! bytes
+static const unsigned int MAX_OP_RETURN_RELAY = 83; //! bytes (+1 for OP_RETURN, +2 for the pushdata opcodes)
extern unsigned nMaxDatacarrierBytes;
/**
@@ -73,6 +73,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
CScript GetScriptForDestination(const CTxDestination& dest);
+CScript GetScriptForRawPubKey(const CPubKey& pubkey);
CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys);
#endif // BITCOIN_SCRIPT_STANDARD_H
diff --git a/src/streams.h b/src/streams.h
index fa1e18defe..8610e4d18e 100644
--- a/src/streams.h
+++ b/src/streams.h
@@ -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/sync.cpp b/src/sync.cpp
index a422939964..1837e8d53d 100644
--- a/src/sync.cpp
+++ b/src/sync.cpp
@@ -33,20 +33,22 @@ void PrintLockContention(const char* pszName, const char* pszFile, int nLine)
//
struct CLockLocation {
- CLockLocation(const char* pszName, const char* pszFile, int nLine)
+ CLockLocation(const char* pszName, const char* pszFile, int nLine, bool fTryIn)
{
mutexName = pszName;
sourceFile = pszFile;
sourceLine = nLine;
+ fTry = fTryIn;
}
std::string ToString() const
{
- return mutexName + " " + sourceFile + ":" + itostr(sourceLine);
+ return mutexName + " " + sourceFile + ":" + itostr(sourceLine) + (fTry ? " (TRY)" : "");
}
std::string MutexName() const { return mutexName; }
+ bool fTry;
private:
std::string mutexName;
std::string sourceFile;
@@ -62,23 +64,52 @@ static boost::thread_specific_ptr<LockStack> lockstack;
static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
{
+ // We attempt to not assert on probably-not deadlocks by assuming that
+ // a try lock will immediately have otherwise bailed if it had
+ // failed to get the lock
+ // We do this by, for the locks which triggered the potential deadlock,
+ // in either lockorder, checking that the second of the two which is locked
+ // is only a TRY_LOCK, ignoring locks if they are reentrant.
+ bool firstLocked = false;
+ bool secondLocked = false;
+ bool onlyMaybeDeadlock = false;
+
LogPrintf("POTENTIAL DEADLOCK DETECTED\n");
LogPrintf("Previous lock order was:\n");
BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s2) {
- if (i.first == mismatch.first)
+ if (i.first == mismatch.first) {
LogPrintf(" (1)");
- if (i.first == mismatch.second)
+ if (!firstLocked && secondLocked && i.second.fTry)
+ onlyMaybeDeadlock = true;
+ firstLocked = true;
+ }
+ if (i.first == mismatch.second) {
LogPrintf(" (2)");
+ if (!secondLocked && firstLocked && i.second.fTry)
+ onlyMaybeDeadlock = true;
+ secondLocked = true;
+ }
LogPrintf(" %s\n", i.second.ToString());
}
+ firstLocked = false;
+ secondLocked = false;
LogPrintf("Current lock order is:\n");
BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s1) {
- if (i.first == mismatch.first)
+ if (i.first == mismatch.first) {
LogPrintf(" (1)");
- if (i.first == mismatch.second)
+ if (!firstLocked && secondLocked && i.second.fTry)
+ onlyMaybeDeadlock = true;
+ firstLocked = true;
+ }
+ if (i.first == mismatch.second) {
LogPrintf(" (2)");
+ if (!secondLocked && firstLocked && i.second.fTry)
+ onlyMaybeDeadlock = true;
+ secondLocked = true;
+ }
LogPrintf(" %s\n", i.second.ToString());
}
+ assert(onlyMaybeDeadlock);
}
static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
@@ -101,10 +132,8 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
lockorders[p1] = (*lockstack);
std::pair<void*, void*> p2 = std::make_pair(c, i.first);
- if (lockorders.count(p2)) {
+ if (lockorders.count(p2))
potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
- break;
- }
}
}
dd_mutex.unlock();
@@ -119,7 +148,7 @@ static void pop_lock()
void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry)
{
- push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry);
+ push_lock(cs, CLockLocation(pszName, pszFile, nLine, fTry), fTry);
}
void LeaveCritical()
diff --git a/src/sync.h b/src/sync.h
index 78b9043477..68a9443084 100644
--- a/src/sync.h
+++ b/src/sync.h
@@ -16,7 +16,7 @@
////////////////////////////////////////////////
// //
-// THE SIMPLE DEFINITON, EXCLUDING DEBUG CODE //
+// THE SIMPLE DEFINITION, EXCLUDING DEBUG CODE //
// //
////////////////////////////////////////////////
@@ -101,7 +101,7 @@ void PrintLockContention(const char* pszName, const char* pszFile, int nLine);
/** Wrapper around boost::unique_lock<Mutex> */
template <typename Mutex>
-class CMutexLock
+class SCOPED_LOCKABLE CMutexLock
{
private:
boost::unique_lock<Mutex> lock;
@@ -129,7 +129,7 @@ private:
}
public:
- CMutexLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) : lock(mutexIn, boost::defer_lock)
+ CMutexLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : lock(mutexIn, boost::defer_lock)
{
if (fTry)
TryEnter(pszName, pszFile, nLine);
@@ -137,7 +137,7 @@ public:
Enter(pszName, pszFile, nLine);
}
- CMutexLock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false)
+ CMutexLock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn)
{
if (!pmutexIn) return;
@@ -148,7 +148,7 @@ public:
Enter(pszName, pszFile, nLine);
}
- ~CMutexLock()
+ ~CMutexLock() UNLOCK_FUNCTION()
{
if (lock.owns_lock())
LeaveCritical();
diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp
index 703cf307d1..0a23c430ed 100644
--- a/src/test/Checkpoints_tests.cpp
+++ b/src/test/Checkpoints_tests.cpp
@@ -20,7 +20,7 @@ BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(sanity)
{
- const Checkpoints::CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints();
+ const CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints();
BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate(checkpoints) >= 134444);
}
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index bf25548755..da296a0461 100644
--- a/src/test/DoS_tests.cpp
+++ b/src/test/DoS_tests.cpp
@@ -2,12 +2,9 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-//
// Unit tests for denial-of-service detection/prevention code
-//
-
-
+#include "chainparams.h"
#include "keystore.h"
#include "main.h"
#include "net.h"
diff --git a/src/test/README.md b/src/test/README.md
index 7efce6f052..b2d6be14f1 100644
--- a/src/test/README.md
+++ b/src/test/README.md
@@ -16,6 +16,20 @@ 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/). \ No newline at end of file
+[http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/](http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/).
+
+test_bitcoin has some built-in command-line arguments; for
+example, to run just the getarg_tests verbosely:
+
+ test_bitcoin --log_level=all --run_test=getarg_tests
+
+... or to run just the doubledash test:
+
+ test_bitcoin --run_test=getarg_tests/doubledash
+
+Run test_bitcoin --help for the full list.
+
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp
new file mode 100644
index 0000000000..cfcdd9abb2
--- /dev/null
+++ b/src/test/addrman_tests.cpp
@@ -0,0 +1,180 @@
+// 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 "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 38dcc6023c..468eda1c9b 100644
--- a/src/test/alert_tests.cpp
+++ b/src/test/alert_tests.cpp
@@ -2,17 +2,14 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-//
// Unit tests for alert system
-//
#include "alert.h"
#include "chain.h"
#include "chainparams.h"
#include "clientversion.h"
#include "data/alertTests.raw.h"
-
-#include "main.h"
+#include "main.h" // For PartitionCheck
#include "serialize.h"
#include "streams.h"
#include "util.h"
@@ -165,8 +162,8 @@ BOOST_AUTO_TEST_CASE(AlertNotify)
SetMockTime(11);
const std::vector<unsigned char>& alertKey = Params(CBaseChainParams::MAIN).AlertKey();
- boost::filesystem::path temp = GetTempPath() / "alertnotify.txt";
- boost::filesystem::remove(temp);
+ boost::filesystem::path temp = GetTempPath() /
+ boost::filesystem::unique_path("alertnotify-%%%%.txt");
mapArgs["-alertnotify"] = std::string("echo %s >> ") + temp.string();
@@ -220,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/base58_tests.cpp b/src/test/base58_tests.cpp
index 9e74f5f427..9845df697f 100644
--- a/src/test/base58_tests.cpp
+++ b/src/test/base58_tests.cpp
@@ -18,7 +18,7 @@
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
extern UniValue read_json(const std::string& jsondata);
diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp
index 0d815c27fd..69084213a2 100644
--- a/src/test/bip32_tests.cpp
+++ b/src/test/bip32_tests.cpp
@@ -88,12 +88,23 @@ void RunTest(const TestVector &test) {
unsigned char data[74];
key.Encode(data);
pubkey.Encode(data);
+
// Test private key
CBitcoinExtKey b58key; b58key.SetKey(key);
BOOST_CHECK(b58key.ToString() == derive.prv);
+
+ CBitcoinExtKey b58keyDecodeCheck(derive.prv);
+ CExtKey checkKey = b58keyDecodeCheck.GetKey();
+ assert(checkKey == key); //ensure a base58 decoded key also matches
+
// Test public key
CBitcoinExtPubKey b58pubkey; b58pubkey.SetKey(pubkey);
BOOST_CHECK(b58pubkey.ToString() == derive.pub);
+
+ CBitcoinExtPubKey b58PubkeyDecodeCheck(derive.pub);
+ CExtPubKey checkPubKey = b58PubkeyDecodeCheck.GetKey();
+ assert(checkPubKey == pubkey); //ensure a base58 decoded pubkey also matches
+
// Derive new keys
CExtKey keyNew;
BOOST_CHECK(key.Derive(keyNew, derive.nChild));
diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp
index 1bda8a7ea1..6b30d6aa8a 100644
--- a/src/test/bloom_tests.cpp
+++ b/src/test/bloom_tests.cpp
@@ -469,7 +469,7 @@ static std::vector<unsigned char> RandomData()
BOOST_AUTO_TEST_CASE(rolling_bloom)
{
// last-100-entry, 1% false positive:
- CRollingBloomFilter rb1(100, 0.01, 0);
+ CRollingBloomFilter rb1(100, 0.01);
// Overfill:
static const int DATASIZE=399;
@@ -500,7 +500,7 @@ BOOST_AUTO_TEST_CASE(rolling_bloom)
BOOST_CHECK(nHits < 175);
BOOST_CHECK(rb1.contains(data[DATASIZE-1]));
- rb1.clear();
+ rb1.reset();
BOOST_CHECK(!rb1.contains(data[DATASIZE-1]));
// Now roll through data, make sure last 100 entries
@@ -527,7 +527,7 @@ BOOST_AUTO_TEST_CASE(rolling_bloom)
BOOST_CHECK(nHits < 100);
// last-1000-entry, 0.01% false positive:
- CRollingBloomFilter rb2(1000, 0.001, 0);
+ CRollingBloomFilter rb2(1000, 0.001);
for (int i = 0; i < DATASIZE; i++) {
rb2.insert(data[i]);
}
diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp
index 51530c4de5..f7e2470617 100644
--- a/src/test/checkblock_tests.cpp
+++ b/src/test/checkblock_tests.cpp
@@ -4,7 +4,8 @@
#include "clientversion.h"
#include "consensus/validation.h"
-#include "main.h"
+#include "main.h" // For CheckBlock
+#include "primitives/block.h"
#include "test/test_bitcoin.h"
#include "utiltime.h"
diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json
index afd35af503..3bf80ca434 100644
--- a/src/test/data/bitcoin-util-test.json
+++ b/src/test/data/bitcoin-util-test.json
@@ -56,5 +56,35 @@
"sign=ALL",
"outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
"output_cmp": "txcreatesign.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
+ "outdata=4:badhexdata"],
+ "return_code": 1
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
+ "outdata=badhexdata"],
+ "return_code": 1
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
+ "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
+ "outdata=4:54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"],
+ "output_cmp": "txcreatedata1.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
+ "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
+ "outdata=54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"],
+ "output_cmp": "txcreatedata2.hex"
}
]
diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json
index 20bdbd08a5..d3c8594342 100644
--- a/src/test/data/tx_invalid.json
+++ b/src/test/data/tx_invalid.json
@@ -128,7 +128,7 @@
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000fe64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
-["By-time locks, with argument just beyond tx nLockTime (but within numerical boundries)"],
+["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 NOP2 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
@@ -181,7 +181,7 @@
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP2 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffff7f", "P2SH,CHECKLOCKTIMEVERIFY"],
-["6 byte non-minimally-encoded arguments are invalid even in their contents are valid"],
+["6 byte non-minimally-encoded arguments are invalid even if their contents are valid"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP2 1"]],
"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"],
@@ -193,5 +193,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 24fff575c1..0dfef73ae5 100644
--- a/src/test/data/tx_valid.json
+++ b/src/test/data/tx_valid.json
@@ -197,7 +197,7 @@
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]],
"0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
-["By-time locks, with argument just beyond tx nLockTime (but within numerical boundries)"],
+["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]],
@@ -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/data/txcreatedata1.hex b/src/test/data/txcreatedata1.hex
new file mode 100644
index 0000000000..eccc7604e6
--- /dev/null
+++ b/src/test/data/txcreatedata1.hex
@@ -0,0 +1 @@
+01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d71700000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000
diff --git a/src/test/data/txcreatedata2.hex b/src/test/data/txcreatedata2.hex
new file mode 100644
index 0000000000..3c7644c297
--- /dev/null
+++ b/src/test/data/txcreatedata2.hex
@@ -0,0 +1 @@
+01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0000000000000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000
diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp
new file mode 100644
index 0000000000..8b6b0697ab
--- /dev/null
+++ b/src/test/dbwrapper_tests.cpp
@@ -0,0 +1,207 @@
+// 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 "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 a0c5592a95..eb61a2884d 100644
--- a/src/test/getarg_tests.cpp
+++ b/src/test/getarg_tests.cpp
@@ -60,18 +60,18 @@ BOOST_AUTO_TEST_CASE(boolarg)
BOOST_CHECK(!GetBoolArg("-foo", false));
BOOST_CHECK(!GetBoolArg("-foo", true));
- ResetArgs("-foo -nofoo"); // -foo should win
- BOOST_CHECK(GetBoolArg("-foo", false));
- BOOST_CHECK(GetBoolArg("-foo", true));
-
- ResetArgs("-foo=1 -nofoo=1"); // -foo should win
- BOOST_CHECK(GetBoolArg("-foo", false));
- BOOST_CHECK(GetBoolArg("-foo", true));
+ ResetArgs("-foo -nofoo"); // -nofoo should win
+ BOOST_CHECK(!GetBoolArg("-foo", false));
+ BOOST_CHECK(!GetBoolArg("-foo", true));
- ResetArgs("-foo=0 -nofoo=0"); // -foo should win
+ ResetArgs("-foo=1 -nofoo=1"); // -nofoo should win
BOOST_CHECK(!GetBoolArg("-foo", false));
BOOST_CHECK(!GetBoolArg("-foo", true));
+ ResetArgs("-foo=0 -nofoo=0"); // -nofoo=0 should win
+ BOOST_CHECK(GetBoolArg("-foo", false));
+ BOOST_CHECK(GetBoolArg("-foo", true));
+
// New 0.6 feature: treat -- same as -:
ResetArgs("--foo=1");
BOOST_CHECK(GetBoolArg("-foo", false));
@@ -150,9 +150,9 @@ BOOST_AUTO_TEST_CASE(boolargno)
BOOST_CHECK(GetBoolArg("-foo", true));
BOOST_CHECK(GetBoolArg("-foo", false));
- ResetArgs("-foo --nofoo");
- BOOST_CHECK(GetBoolArg("-foo", true));
- BOOST_CHECK(GetBoolArg("-foo", false));
+ ResetArgs("-foo --nofoo"); // --nofoo should win
+ BOOST_CHECK(!GetBoolArg("-foo", true));
+ BOOST_CHECK(!GetBoolArg("-foo", false));
ResetArgs("-nofoo -foo"); // foo always wins:
BOOST_CHECK(GetBoolArg("-foo", true));
diff --git a/src/test/limitedmap_tests.cpp b/src/test/limitedmap_tests.cpp
new file mode 100644
index 0000000000..faaddffad8
--- /dev/null
+++ b/src/test/limitedmap_tests.cpp
@@ -0,0 +1,101 @@
+// Copyright (c) 2012-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "limitedmap.h"
+
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(limitedmap_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(limitedmap_test)
+{
+ // create a limitedmap capped at 10 items
+ limitedmap<int, int> map(10);
+
+ // check that the max size is 10
+ BOOST_CHECK(map.max_size() == 10);
+
+ // check that it's empty
+ BOOST_CHECK(map.size() == 0);
+
+ // insert (-1, -1)
+ map.insert(std::pair<int, int>(-1, -1));
+
+ // make sure that the size is updated
+ BOOST_CHECK(map.size() == 1);
+
+ // make sure that the new items is in the map
+ BOOST_CHECK(map.count(-1) == 1);
+
+ // insert 10 new items
+ for (int i = 0; i < 10; i++) {
+ map.insert(std::pair<int, int>(i, i + 1));
+ }
+
+ // make sure that the map now contains 10 items...
+ BOOST_CHECK(map.size() == 10);
+
+ // ...and that the first item has been discarded
+ BOOST_CHECK(map.count(-1) == 0);
+
+ // iterate over the map, both with an index and an iterator
+ limitedmap<int, int>::const_iterator it = map.begin();
+ for (int i = 0; i < 10; i++) {
+ // make sure the item is present
+ BOOST_CHECK(map.count(i) == 1);
+
+ // use the iterator to check for the expected key adn value
+ BOOST_CHECK(it->first == i);
+ BOOST_CHECK(it->second == i + 1);
+
+ // use find to check for the value
+ BOOST_CHECK(map.find(i)->second == i + 1);
+
+ // update and recheck
+ map.update(it, i + 2);
+ BOOST_CHECK(map.find(i)->second == i + 2);
+
+ it++;
+ }
+
+ // check that we've exhausted the iterator
+ BOOST_CHECK(it == map.end());
+
+ // resize the map to 5 items
+ map.max_size(5);
+
+ // check that the max size and size are now 5
+ BOOST_CHECK(map.max_size() == 5);
+ BOOST_CHECK(map.size() == 5);
+
+ // check that items less than 5 have been discarded
+ // and items greater than 5 are retained
+ for (int i = 0; i < 10; i++) {
+ if (i < 5) {
+ BOOST_CHECK(map.count(i) == 0);
+ } else {
+ BOOST_CHECK(map.count(i) == 1);
+ }
+ }
+
+ // erase some items not in the map
+ for (int i = 100; i < 1000; i += 100) {
+ map.erase(i);
+ }
+
+ // check that the size is unaffected
+ BOOST_CHECK(map.size() == 5);
+
+ // erase the remaining elements
+ for (int i = 5; i < 10; i++) {
+ map.erase(i);
+ }
+
+ // check that the map is now empty
+ BOOST_CHECK(map.empty());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp
index 0996e13c48..0cf906a259 100644
--- a/src/test/mempool_tests.cpp
+++ b/src/test/mempool_tests.cpp
@@ -2,7 +2,6 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "main.h"
#include "txmempool.h"
#include "util.h"
@@ -10,6 +9,7 @@
#include <boost/test/unit_test.hpp>
#include <list>
+#include <vector>
BOOST_FIXTURE_TEST_SUITE(mempool_tests, TestingSetup)
@@ -101,4 +101,337 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
removed.clear();
}
+void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder)
+{
+ BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size());
+ CTxMemPool::indexed_transaction_set::nth_index<1>::type::iterator it = pool.mapTx.get<1>().begin();
+ int count=0;
+ for (; it != pool.mapTx.get<1>().end(); ++it, ++count) {
+ BOOST_CHECK_EQUAL(it->GetTx().GetHash().ToString(), sortedOrder[count]);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
+{
+ CTxMemPool pool(CFeeRate(0));
+
+ /* 3rd highest fee */
+ CMutableTransaction tx1 = CMutableTransaction();
+ tx1.vout.resize(1);
+ tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx1.vout[0].nValue = 10 * COIN;
+ pool.addUnchecked(tx1.GetHash(), CTxMemPoolEntry(tx1, 10000LL, 0, 10.0, 1, true));
+
+ /* highest fee */
+ CMutableTransaction tx2 = CMutableTransaction();
+ tx2.vout.resize(1);
+ tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx2.vout[0].nValue = 2 * COIN;
+ pool.addUnchecked(tx2.GetHash(), CTxMemPoolEntry(tx2, 20000LL, 0, 9.0, 1, true));
+
+ /* lowest fee */
+ CMutableTransaction tx3 = CMutableTransaction();
+ tx3.vout.resize(1);
+ tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx3.vout[0].nValue = 5 * COIN;
+ pool.addUnchecked(tx3.GetHash(), CTxMemPoolEntry(tx3, 0LL, 0, 100.0, 1, true));
+
+ /* 2nd highest fee */
+ CMutableTransaction tx4 = CMutableTransaction();
+ tx4.vout.resize(1);
+ tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx4.vout[0].nValue = 6 * COIN;
+ pool.addUnchecked(tx4.GetHash(), CTxMemPoolEntry(tx4, 15000LL, 0, 1.0, 1, true));
+
+ /* equal fee rate to tx1, but newer */
+ CMutableTransaction tx5 = CMutableTransaction();
+ tx5.vout.resize(1);
+ tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx5.vout[0].nValue = 11 * COIN;
+ pool.addUnchecked(tx5.GetHash(), CTxMemPoolEntry(tx5, 10000LL, 1, 10.0, 1, true));
+ BOOST_CHECK_EQUAL(pool.size(), 5);
+
+ std::vector<std::string> sortedOrder;
+ sortedOrder.resize(5);
+ sortedOrder[0] = tx3.GetHash().ToString(); // 0
+ sortedOrder[1] = tx5.GetHash().ToString(); // 10000
+ sortedOrder[2] = tx1.GetHash().ToString(); // 10000
+ sortedOrder[3] = tx4.GetHash().ToString(); // 15000
+ sortedOrder[4] = tx2.GetHash().ToString(); // 20000
+ CheckSort(pool, sortedOrder);
+
+ /* low fee but with high fee child */
+ /* tx6 -> tx7 -> tx8, tx9 -> tx10 */
+ CMutableTransaction tx6 = CMutableTransaction();
+ tx6.vout.resize(1);
+ tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx6.vout[0].nValue = 20 * COIN;
+ pool.addUnchecked(tx6.GetHash(), CTxMemPoolEntry(tx6, 0LL, 1, 10.0, 1, true));
+ BOOST_CHECK_EQUAL(pool.size(), 6);
+ // Check that at this point, tx6 is sorted low
+ sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString());
+ CheckSort(pool, sortedOrder);
+
+ CTxMemPool::setEntries setAncestors;
+ setAncestors.insert(pool.mapTx.find(tx6.GetHash()));
+ CMutableTransaction tx7 = CMutableTransaction();
+ tx7.vin.resize(1);
+ tx7.vin[0].prevout = COutPoint(tx6.GetHash(), 0);
+ tx7.vin[0].scriptSig = CScript() << OP_11;
+ tx7.vout.resize(2);
+ tx7.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx7.vout[0].nValue = 10 * COIN;
+ tx7.vout[1].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx7.vout[1].nValue = 1 * COIN;
+
+ CTxMemPool::setEntries setAncestorsCalculated;
+ std::string dummy;
+ CTxMemPoolEntry entry7(tx7, 2000000LL, 1, 10.0, 1, true);
+ BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry7, setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true);
+ BOOST_CHECK(setAncestorsCalculated == setAncestors);
+
+ pool.addUnchecked(tx7.GetHash(), CTxMemPoolEntry(tx7, 2000000LL, 1, 10.0, 1, true), setAncestors);
+ BOOST_CHECK_EQUAL(pool.size(), 7);
+
+ // Now tx6 should be sorted higher (high fee child): tx7, tx6, tx2, ...
+ sortedOrder.erase(sortedOrder.begin());
+ sortedOrder.push_back(tx6.GetHash().ToString());
+ sortedOrder.push_back(tx7.GetHash().ToString());
+ CheckSort(pool, sortedOrder);
+
+ /* low fee child of tx7 */
+ CMutableTransaction tx8 = CMutableTransaction();
+ tx8.vin.resize(1);
+ tx8.vin[0].prevout = COutPoint(tx7.GetHash(), 0);
+ tx8.vin[0].scriptSig = CScript() << OP_11;
+ tx8.vout.resize(1);
+ tx8.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx8.vout[0].nValue = 10 * COIN;
+ setAncestors.insert(pool.mapTx.find(tx7.GetHash()));
+ pool.addUnchecked(tx8.GetHash(), CTxMemPoolEntry(tx8, 0LL, 2, 10.0, 1, true), setAncestors);
+
+ // Now tx8 should be sorted low, but tx6/tx both high
+ sortedOrder.insert(sortedOrder.begin(), tx8.GetHash().ToString());
+ CheckSort(pool, sortedOrder);
+
+ /* low fee child of tx7 */
+ CMutableTransaction tx9 = CMutableTransaction();
+ tx9.vin.resize(1);
+ tx9.vin[0].prevout = COutPoint(tx7.GetHash(), 1);
+ tx9.vin[0].scriptSig = CScript() << OP_11;
+ tx9.vout.resize(1);
+ tx9.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx9.vout[0].nValue = 1 * COIN;
+ pool.addUnchecked(tx9.GetHash(), CTxMemPoolEntry(tx9, 0LL, 3, 10.0, 1, true), setAncestors);
+
+ // tx9 should be sorted low
+ BOOST_CHECK_EQUAL(pool.size(), 9);
+ sortedOrder.insert(sortedOrder.begin(), tx9.GetHash().ToString());
+ CheckSort(pool, sortedOrder);
+
+ std::vector<std::string> snapshotOrder = sortedOrder;
+
+ setAncestors.insert(pool.mapTx.find(tx8.GetHash()));
+ setAncestors.insert(pool.mapTx.find(tx9.GetHash()));
+ /* tx10 depends on tx8 and tx9 and has a high fee*/
+ CMutableTransaction tx10 = CMutableTransaction();
+ tx10.vin.resize(2);
+ tx10.vin[0].prevout = COutPoint(tx8.GetHash(), 0);
+ tx10.vin[0].scriptSig = CScript() << OP_11;
+ tx10.vin[1].prevout = COutPoint(tx9.GetHash(), 0);
+ tx10.vin[1].scriptSig = CScript() << OP_11;
+ tx10.vout.resize(1);
+ tx10.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx10.vout[0].nValue = 10 * COIN;
+
+ setAncestorsCalculated.clear();
+ CTxMemPoolEntry entry10(tx10, 200000LL, 4, 10.0, 1, true);
+ BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry10, setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true);
+ BOOST_CHECK(setAncestorsCalculated == setAncestors);
+
+ pool.addUnchecked(tx10.GetHash(), CTxMemPoolEntry(tx10, 200000LL, 4, 10.0, 1, true), setAncestors);
+
+ /**
+ * tx8 and tx9 should both now be sorted higher
+ * Final order after tx10 is added:
+ *
+ * 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.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(pool, sortedOrder);
+
+ // there should be 10 transactions in the mempool
+ BOOST_CHECK_EQUAL(pool.size(), 10);
+
+ // Now try removing tx10 and verify the sort order returns to normal
+ std::list<CTransaction> removed;
+ pool.remove(pool.mapTx.find(tx10.GetHash())->GetTx(), removed, true);
+ CheckSort(pool, snapshotOrder);
+}
+
+BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
+{
+ CTxMemPool pool(CFeeRate(1000));
+
+ 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(), CTxMemPoolEntry(tx1, 10000LL, 0, 10.0, 1, pool.HasNoInputsOf(tx1)));
+
+ 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(), CTxMemPoolEntry(tx2, 5000LL, 0, 10.0, 1, pool.HasNoInputsOf(tx2)));
+
+ 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(), CTxMemPoolEntry(tx2, 5000LL, 0, 10.0, 1, pool.HasNoInputsOf(tx2)));
+ 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(), CTxMemPoolEntry(tx3, 20000LL, 0, 10.0, 1, pool.HasNoInputsOf(tx3)));
+
+ 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[0].scriptPubKey = CScript() << OP_7 << OP_EQUAL;
+ tx7.vout[0].nValue = 10 * COIN;
+
+ pool.addUnchecked(tx4.GetHash(), CTxMemPoolEntry(tx4, 7000LL, 0, 10.0, 1, pool.HasNoInputsOf(tx4)));
+ pool.addUnchecked(tx5.GetHash(), CTxMemPoolEntry(tx5, 1000LL, 0, 10.0, 1, pool.HasNoInputsOf(tx5)));
+ pool.addUnchecked(tx6.GetHash(), CTxMemPoolEntry(tx6, 1100LL, 0, 10.0, 1, pool.HasNoInputsOf(tx6)));
+ pool.addUnchecked(tx7.GetHash(), CTxMemPoolEntry(tx7, 9000LL, 0, 10.0, 1, pool.HasNoInputsOf(tx7)));
+
+ // 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(), CTxMemPoolEntry(tx5, 1000LL, 0, 10.0, 1, pool.HasNoInputsOf(tx5)));
+ pool.addUnchecked(tx7.GetHash(), CTxMemPoolEntry(tx7, 9000LL, 0, 10.0, 1, pool.HasNoInputsOf(tx7)));
+
+ 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(), CTxMemPoolEntry(tx5, 1000LL, 0, 10.0, 1, pool.HasNoInputsOf(tx5)));
+ pool.addUnchecked(tx7.GetHash(), CTxMemPoolEntry(tx7, 9000LL, 0, 10.0, 1, pool.HasNoInputsOf(tx7)));
+
+ 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/miner_tests.cpp b/src/test/miner_tests.cpp
index 212be0d2d6..827525783a 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -2,12 +2,18 @@
// 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/validation.h"
#include "main.h"
#include "miner.h"
#include "pubkey.h"
+#include "script/standard.h"
+#include "txmempool.h"
#include "uint256.h"
#include "util.h"
+#include "utilstrencodings.h"
#include "test/test_bitcoin.h"
@@ -82,7 +88,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
pblock->vtx[0] = CTransaction(txCoinbase);
if (txFirst.size() < 2)
txFirst.push_back(new CTransaction(pblock->vtx[0]));
- pblock->hashMerkleRoot = pblock->BuildMerkleTree();
+ pblock->hashMerkleRoot = pblock->ComputeMerkleRoot();
pblock->nNonce = blockinfo[i].nonce;
CValidationState state;
BOOST_CHECK(ProcessNewBlock(state, NULL, pblock, true, NULL));
@@ -224,7 +230,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx.nLockTime = chainActive.Tip()->nHeight+1;
hash = tx.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
- BOOST_CHECK(!CheckFinalTx(tx));
+ BOOST_CHECK(!CheckFinalTx(tx, LOCKTIME_MEDIAN_TIME_PAST));
// time locked
tx2.vin.resize(1);
@@ -238,7 +244,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
tx2.nLockTime = chainActive.Tip()->GetMedianTimePast()+1;
hash = tx2.GetHash();
mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11));
- BOOST_CHECK(!CheckFinalTx(tx2));
+ BOOST_CHECK(!CheckFinalTx(tx2, LOCKTIME_MEDIAN_TIME_PAST));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
@@ -256,7 +262,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
//BOOST_CHECK(CheckFinalTx(tx2));
BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey));
- BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3);
+ BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 2);
delete pblocktemplate;
chainActive.Tip()->nHeight--;
diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp
index 7154476c7c..b1ef0ed24a 100644
--- a/src/test/netbase_tests.cpp
+++ b/src/test/netbase_tests.cpp
@@ -7,6 +7,7 @@
#include <string>
+#include <boost/assign/list_of.hpp>
#include <boost/test/unit_test.hpp>
using namespace std;
@@ -148,12 +149,106 @@ BOOST_AUTO_TEST_CASE(subnet_test)
BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).IsValid());
BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).Match(CNetAddr("127.0.0.1")));
BOOST_CHECK(!CSubNet(CNetAddr("127.0.0.1")).Match(CNetAddr("127.0.0.2")));
- BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).ToString() == "127.0.0.1/255.255.255.255");
+ BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).ToString() == "127.0.0.1/32");
BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).IsValid());
BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).Match(CNetAddr("1:2:3:4:5:6:7:8")));
BOOST_CHECK(!CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).Match(CNetAddr("1:2:3:4:5:6:7:9")));
- BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).ToString() == "1:2:3:4:5:6:7:8/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
+ BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).ToString() == "1:2:3:4:5:6:7:8/128");
+
+ CSubNet subnet = CSubNet("1.2.3.4/255.255.255.255");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32");
+ subnet = CSubNet("1.2.3.4/255.255.255.254");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/31");
+ subnet = CSubNet("1.2.3.4/255.255.255.252");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/30");
+ subnet = CSubNet("1.2.3.4/255.255.255.248");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/29");
+ subnet = CSubNet("1.2.3.4/255.255.255.240");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/28");
+ subnet = CSubNet("1.2.3.4/255.255.255.224");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/27");
+ subnet = CSubNet("1.2.3.4/255.255.255.192");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/26");
+ subnet = CSubNet("1.2.3.4/255.255.255.128");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/25");
+ subnet = CSubNet("1.2.3.4/255.255.255.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/24");
+ subnet = CSubNet("1.2.3.4/255.255.254.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.2.0/23");
+ subnet = CSubNet("1.2.3.4/255.255.252.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/22");
+ subnet = CSubNet("1.2.3.4/255.255.248.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/21");
+ subnet = CSubNet("1.2.3.4/255.255.240.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/20");
+ subnet = CSubNet("1.2.3.4/255.255.224.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/19");
+ subnet = CSubNet("1.2.3.4/255.255.192.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/18");
+ subnet = CSubNet("1.2.3.4/255.255.128.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/17");
+ subnet = CSubNet("1.2.3.4/255.255.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/16");
+ subnet = CSubNet("1.2.3.4/255.254.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/15");
+ subnet = CSubNet("1.2.3.4/255.252.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/14");
+ subnet = CSubNet("1.2.3.4/255.248.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/13");
+ subnet = CSubNet("1.2.3.4/255.240.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/12");
+ subnet = CSubNet("1.2.3.4/255.224.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/11");
+ subnet = CSubNet("1.2.3.4/255.192.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/10");
+ subnet = CSubNet("1.2.3.4/255.128.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/9");
+ subnet = CSubNet("1.2.3.4/255.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8");
+ subnet = CSubNet("1.2.3.4/254.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/7");
+ subnet = CSubNet("1.2.3.4/252.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/6");
+ subnet = CSubNet("1.2.3.4/248.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/5");
+ subnet = CSubNet("1.2.3.4/240.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/4");
+ subnet = CSubNet("1.2.3.4/224.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/3");
+ subnet = CSubNet("1.2.3.4/192.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/2");
+ subnet = CSubNet("1.2.3.4/128.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/1");
+ subnet = CSubNet("1.2.3.4/0.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/0");
+
+ subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1:2:3:4:5:6:7:8/128");
+ subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:0000:0000:0000:0000:0000:0000:0000");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1::/16");
+ subnet = CSubNet("1:2:3:4:5:6:7:8/0000:0000:0000:0000:0000:0000:0000:0000");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "::/0");
+ subnet = CSubNet("1.2.3.4/255.255.232.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/255.255.232.0");
+ subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f");
+}
+
+BOOST_AUTO_TEST_CASE(netbase_getgroup)
+{
+ BOOST_CHECK(CNetAddr("127.0.0.1").GetGroup() == boost::assign::list_of(0)); // Local -> !Routable()
+ BOOST_CHECK(CNetAddr("257.0.0.1").GetGroup() == boost::assign::list_of(0)); // !Valid -> !Routable()
+ BOOST_CHECK(CNetAddr("10.0.0.1").GetGroup() == boost::assign::list_of(0)); // RFC1918 -> !Routable()
+ BOOST_CHECK(CNetAddr("169.254.1.1").GetGroup() == boost::assign::list_of(0)); // RFC3927 -> !Routable()
+ BOOST_CHECK(CNetAddr("1.2.3.4").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // IPv4
+ BOOST_CHECK(CNetAddr("::FFFF:0:102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6145
+ BOOST_CHECK(CNetAddr("64:FF9B::102:304").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC6052
+ BOOST_CHECK(CNetAddr("2002:102:304:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC3964
+ BOOST_CHECK(CNetAddr("2001:0:9999:9999:9999:9999:FEFD:FCFB").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV4)(1)(2)); // RFC4380
+ BOOST_CHECK(CNetAddr("FD87:D87E:EB43:edb1:8e4:3588:e546:35ca").GetGroup() == boost::assign::list_of((unsigned char)NET_TOR)(239)); // Tor
+ BOOST_CHECK(CNetAddr("2001:470:abcd:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(4)(112)(175)); //he.net
+ BOOST_CHECK(CNetAddr("2001:2001:9999:9999:9999:9999:9999:9999").GetGroup() == boost::assign::list_of((unsigned char)NET_IPV6)(32)(1)(32)(1)); //IPv6
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp
index f6d06d6805..d9f3c3e467 100644
--- a/src/test/pmt_tests.cpp
+++ b/src/test/pmt_tests.cpp
@@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
}
// calculate actual merkle root and height
- uint256 merkleRoot1 = block.BuildMerkleTree();
+ uint256 merkleRoot1 = block.ComputeMerkleRoot();
std::vector<uint256> vTxid(nTx, uint256());
for (unsigned int j=0; j<nTx; j++)
vTxid[j] = block.vtx[j].GetHash();
diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp
index a436749287..b6eb39bc38 100644
--- a/src/test/pow_tests.cpp
+++ b/src/test/pow_tests.cpp
@@ -2,8 +2,10 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "main.h"
+#include "chain.h"
+#include "chainparams.h"
#include "pow.h"
+#include "random.h"
#include "util.h"
#include "test/test_bitcoin.h"
diff --git a/src/test/reverselock_tests.cpp b/src/test/reverselock_tests.cpp
new file mode 100644
index 0000000000..e7e627ae0f
--- /dev/null
+++ b/src/test/reverselock_tests.cpp
@@ -0,0 +1,64 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "reverselock.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(reverselock_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(reverselock_basics)
+{
+ boost::mutex mutex;
+ boost::unique_lock<boost::mutex> lock(mutex);
+
+ BOOST_CHECK(lock.owns_lock());
+ {
+ reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
+ BOOST_CHECK(!lock.owns_lock());
+ }
+ BOOST_CHECK(lock.owns_lock());
+}
+
+BOOST_AUTO_TEST_CASE(reverselock_errors)
+{
+ boost::mutex mutex;
+ boost::unique_lock<boost::mutex> lock(mutex);
+
+ // Make sure trying to reverse lock an unlocked lock fails
+ lock.unlock();
+
+ BOOST_CHECK(!lock.owns_lock());
+
+ bool failed = false;
+ try {
+ reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
+ } catch(...) {
+ failed = true;
+ }
+
+ BOOST_CHECK(failed);
+ BOOST_CHECK(!lock.owns_lock());
+
+ // Make sure trying to lock a lock after it has been reverse locked fails
+ failed = false;
+ bool locked = false;
+
+ lock.lock();
+ BOOST_CHECK(lock.owns_lock());
+
+ try {
+ reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
+ lock.lock();
+ locked = true;
+ } catch(...) {
+ failed = true;
+ }
+
+ BOOST_CHECK(locked && failed);
+ BOOST_CHECK(lock.owns_lock());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
index 25599beafc..2a486f08e4 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -13,7 +13,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/test/unit_test.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -110,6 +110,24 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign)
BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == true);
}
+BOOST_AUTO_TEST_CASE(rpc_createraw_op_return)
+{
+ BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"68656c6c6f776f726c64\"}"));
+
+ // Allow more than one data transaction output
+ BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"68656c6c6f776f726c64\",\"data\":\"68656c6c6f776f726c64\"}"));
+
+ // Key not "data" (bad address)
+ BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"somedata\":\"68656c6c6f776f726c64\"}"), runtime_error);
+
+ // Bad hex encoding of data output
+ BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"12345\"}"), runtime_error);
+ BOOST_CHECK_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"12345g\"}"), runtime_error);
+
+ // Data 81 bytes long
+ BOOST_CHECK_NO_THROW(CallRPC("createrawtransaction [{\"txid\":\"a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed\",\"vout\":0}] {\"data\":\"010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081\"}"));
+}
+
BOOST_AUTO_TEST_CASE(rpc_format_monetary_values)
{
BOOST_CHECK(ValueFromAmount(0LL).write() == "0.00000000");
@@ -120,6 +138,29 @@ BOOST_AUTO_TEST_CASE(rpc_format_monetary_values)
BOOST_CHECK(ValueFromAmount(100000000LL).write() == "1.00000000");
BOOST_CHECK(ValueFromAmount(2099999999999990LL).write() == "20999999.99999990");
BOOST_CHECK(ValueFromAmount(2099999999999999LL).write() == "20999999.99999999");
+
+ BOOST_CHECK_EQUAL(ValueFromAmount(0).write(), "0.00000000");
+ BOOST_CHECK_EQUAL(ValueFromAmount((COIN/10000)*123456789).write(), "12345.67890000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(-COIN).write(), "-1.00000000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(-COIN/10).write(), "-0.10000000");
+
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN*100000000).write(), "100000000.00000000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN*10000000).write(), "10000000.00000000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN*1000000).write(), "1000000.00000000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN*100000).write(), "100000.00000000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN*10000).write(), "10000.00000000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN*1000).write(), "1000.00000000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN*100).write(), "100.00000000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN*10).write(), "10.00000000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN).write(), "1.00000000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN/10).write(), "0.10000000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN/100).write(), "0.01000000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN/1000).write(), "0.00100000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN/10000).write(), "0.00010000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN/100000).write(), "0.00001000");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN/1000000).write(), "0.00000100");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN/10000000).write(), "0.00000010");
+ BOOST_CHECK_EQUAL(ValueFromAmount(COIN/100000000).write(), "0.00000001");
}
static UniValue ValueFromString(const std::string &str)
@@ -183,21 +224,6 @@ BOOST_AUTO_TEST_CASE(json_parse_errors)
BOOST_CHECK_THROW(ParseNonRFCJSONValue("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"), std::runtime_error);
}
-BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr)
-{
- // Check IPv4 addresses
- BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("1.2.3.4")).ToString(), "1.2.3.4");
- BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("127.0.0.1")).ToString(), "127.0.0.1");
- // Check IPv6 addresses
- BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::1")).ToString(), "::1");
- BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("123:4567:89ab:cdef:123:4567:89ab:cdef")).ToString(),
- "123:4567:89ab:cdef:123:4567:89ab:cdef");
- // v4 compatible must be interpreted as IPv4
- BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::0:127.0.0.1")).ToString(), "127.0.0.1");
- // v4 mapped must be interpreted as IPv4
- BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::ffff:127.0.0.1")).ToString(), "127.0.0.1");
-}
-
BOOST_AUTO_TEST_CASE(rpc_ban)
{
BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned")));
@@ -209,7 +235,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
UniValue ar = r.get_array();
UniValue o1 = ar[0].get_obj();
UniValue adr = find_value(o1, "address");
- BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.255");
+ BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/32");
BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove")));;
BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned")));
ar = r.get_array();
@@ -221,7 +247,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
o1 = ar[0].get_obj();
adr = find_value(o1, "address");
UniValue banned_until = find_value(o1, "banned_until");
- BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.0");
+ BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24");
BOOST_CHECK_EQUAL(banned_until.get_int64(), 1607731200); // absolute time check
BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned")));
@@ -232,7 +258,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
o1 = ar[0].get_obj();
adr = find_value(o1, "address");
banned_until = find_value(o1, "banned_until");
- BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.0");
+ BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24");
int64_t now = GetTime();
BOOST_CHECK(banned_until.get_int64() > now);
BOOST_CHECK(banned_until.get_int64()-now <= 200);
@@ -262,15 +288,15 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
ar = r.get_array();
o1 = ar[0].get_obj();
adr = find_value(o1, "address");
- BOOST_CHECK_EQUAL(adr.get_str(), "fe80::202:b3ff:fe1e:8329/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
+ BOOST_CHECK_EQUAL(adr.get_str(), "fe80::202:b3ff:fe1e:8329/128");
BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned")));
- BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 2001:db8::/30 add")));
+ BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 2001:db8::/ffff:fffc:0:0:0:0:0:0 add")));
BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned")));
ar = r.get_array();
o1 = ar[0].get_obj();
adr = find_value(o1, "address");
- BOOST_CHECK_EQUAL(adr.get_str(), "2001:db8::/ffff:fffc:0:0:0:0:0:0");
+ BOOST_CHECK_EQUAL(adr.get_str(), "2001:db8::/30");
BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned")));
BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128 add")));
@@ -278,7 +304,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
ar = r.get_array();
o1 = ar[0].get_obj();
adr = find_value(o1, "address");
- BOOST_CHECK_EQUAL(adr.get_str(), "2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
+ BOOST_CHECK_EQUAL(adr.get_str(), "2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128");
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp
index 9368963ff2..2e652f76e2 100644
--- a/src/test/rpc_wallet_tests.cpp
+++ b/src/test/rpc_wallet_tests.cpp
@@ -14,7 +14,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/test/unit_test.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -27,8 +27,6 @@ BOOST_FIXTURE_TEST_SUITE(rpc_wallet_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(rpc_addmultisig)
{
- LOCK(pwalletMain->cs_wallet);
-
rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor;
// old, 65-byte-long:
@@ -68,25 +66,28 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
{
// Test RPC calls for various wallet statistics
UniValue r;
-
- LOCK2(cs_main, pwalletMain->cs_wallet);
-
- CPubKey demoPubkey = pwalletMain->GenerateNewKey();
- CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID()));
+ CPubKey demoPubkey;
+ CBitcoinAddress demoAddress;
UniValue retValue;
string strAccount = "walletDemoAccount";
- string strPurpose = "receive";
- BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */
- CWalletDB walletdb(pwalletMain->strWalletFile);
- CAccount account;
- account.vchPubKey = demoPubkey;
- pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, strPurpose);
- walletdb.WriteAccount(strAccount, account);
- });
-
- CPubKey setaccountDemoPubkey = pwalletMain->GenerateNewKey();
- CBitcoinAddress setaccountDemoAddress = CBitcoinAddress(CTxDestination(setaccountDemoPubkey.GetID()));
-
+ CBitcoinAddress setaccountDemoAddress;
+ {
+ LOCK(pwalletMain->cs_wallet);
+
+ demoPubkey = pwalletMain->GenerateNewKey();
+ demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID()));
+ string strPurpose = "receive";
+ BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */
+ CWalletDB walletdb(pwalletMain->strWalletFile);
+ CAccount account;
+ account.vchPubKey = demoPubkey;
+ pwalletMain->SetAddressBook(account.vchPubKey.GetID(), strAccount, strPurpose);
+ walletdb.WriteAccount(strAccount, account);
+ });
+
+ CPubKey setaccountDemoPubkey = pwalletMain->GenerateNewKey();
+ setaccountDemoAddress = CBitcoinAddress(CTxDestination(setaccountDemoPubkey.GetID()));
+ }
/*********************************
* setaccount
*********************************/
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 3733425699..882f9eb199 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -8,11 +8,11 @@
#include "core_io.h"
#include "key.h"
#include "keystore.h"
-#include "main.h"
#include "script/script.h"
#include "script/script_error.h"
#include "script/sign.h"
#include "util.h"
+#include "utilstrencodings.h"
#include "test/test_bitcoin.h"
#if defined(HAVE_CONSENSUS_LIB)
@@ -27,7 +27,7 @@
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -840,7 +840,7 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23);
BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
-}
+}
BOOST_AUTO_TEST_CASE(script_combineSigs)
{
@@ -983,4 +983,34 @@ BOOST_AUTO_TEST_CASE(script_IsPushOnly_on_invalid_scripts)
BOOST_CHECK(!CScript(direct, direct+sizeof(direct)).IsPushOnly());
}
+BOOST_AUTO_TEST_CASE(script_GetScriptAsm)
+{
+ BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2, true));
+ BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true));
+ BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2));
+ BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY));
+
+ string derSig("304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090");
+ string pubKey("03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2");
+ vector<unsigned char> vchPubKey = ToByteVector(ParseHex(pubKey));
+
+ BOOST_CHECK_EQUAL(derSig + "00 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "00")) << vchPubKey, true));
+ BOOST_CHECK_EQUAL(derSig + "80 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "80")) << vchPubKey, true));
+ BOOST_CHECK_EQUAL(derSig + "[ALL] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "01")) << vchPubKey, true));
+ BOOST_CHECK_EQUAL(derSig + "[NONE] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "02")) << vchPubKey, true));
+ BOOST_CHECK_EQUAL(derSig + "[SINGLE] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "03")) << vchPubKey, true));
+ BOOST_CHECK_EQUAL(derSig + "[ALL|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "81")) << vchPubKey, true));
+ BOOST_CHECK_EQUAL(derSig + "[NONE|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "82")) << vchPubKey, true));
+ BOOST_CHECK_EQUAL(derSig + "[SINGLE|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "83")) << vchPubKey, true));
+
+ BOOST_CHECK_EQUAL(derSig + "00 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "00")) << vchPubKey));
+ BOOST_CHECK_EQUAL(derSig + "80 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "80")) << vchPubKey));
+ BOOST_CHECK_EQUAL(derSig + "01 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "01")) << vchPubKey));
+ BOOST_CHECK_EQUAL(derSig + "02 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "02")) << vchPubKey));
+ BOOST_CHECK_EQUAL(derSig + "03 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "03")) << vchPubKey));
+ BOOST_CHECK_EQUAL(derSig + "81 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "81")) << vchPubKey));
+ BOOST_CHECK_EQUAL(derSig + "82 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "82")) << vchPubKey));
+ BOOST_CHECK_EQUAL(derSig + "83 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "83")) << vchPubKey));
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp
index a0797d5f3f..6fca64d5da 100644
--- a/src/test/sighash_tests.cpp
+++ b/src/test/sighash_tests.cpp
@@ -4,20 +4,23 @@
#include "consensus/validation.h"
#include "data/sighash.json.h"
-#include "main.h"
+#include "hash.h"
+#include "main.h" // For CheckTransaction
#include "random.h"
#include "script/interpreter.h"
#include "script/script.h"
#include "serialize.h"
+#include "streams.h"
#include "test/test_bitcoin.h"
#include "util.h"
+#include "utilstrencodings.h"
#include "version.h"
#include <iostream>
#include <boost/test/unit_test.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
extern UniValue read_json(const std::string& jsondata);
diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp
index 86a4bc6727..a904e3862f 100644
--- a/src/test/skiplist_tests.cpp
+++ b/src/test/skiplist_tests.cpp
@@ -2,7 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "main.h"
+#include "chain.h"
#include "random.h"
#include "util.h"
#include "test/test_bitcoin.h"
diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp
new file mode 100644
index 0000000000..0ed8f363d7
--- /dev/null
+++ b/src/test/streams_tests.cpp
@@ -0,0 +1,67 @@
+// 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 "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 c727303ea1..a74fbfc0d7 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -6,8 +6,13 @@
#include "test_bitcoin.h"
+#include "chainparams.h"
+#include "consensus/consensus.h"
+#include "consensus/validation.h"
#include "key.h"
#include "main.h"
+#include "miner.h"
+#include "pubkey.h"
#include "random.h"
#include "txdb.h"
#include "ui_interface.h"
@@ -27,20 +32,22 @@ CWallet* pwalletMain;
extern bool fPrintToConsole;
extern void noui_connect();
-BasicTestingSetup::BasicTestingSetup()
+BasicTestingSetup::BasicTestingSetup(const std::string& chainName)
{
ECC_Start();
SetupEnvironment();
fPrintToDebugLog = false; // don't want to write to debug.log file
fCheckBlockIndex = true;
- SelectParams(CBaseChainParams::MAIN);
+ SelectParams(chainName);
+ noui_connect();
}
+
BasicTestingSetup::~BasicTestingSetup()
{
ECC_Stop();
}
-TestingSetup::TestingSetup()
+TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName)
{
#ifdef ENABLE_WALLET
bitdb.MakeMock();
@@ -86,6 +93,51 @@ TestingSetup::~TestingSetup()
boost::filesystem::remove_all(pathTemp);
}
+TestChain100Setup::TestChain100Setup() : TestingSetup(CBaseChainParams::REGTEST)
+{
+ // Generate a 100-block chain:
+ coinbaseKey.MakeNewKey(true);
+ CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
+ for (int i = 0; i < COINBASE_MATURITY; i++)
+ {
+ std::vector<CMutableTransaction> noTxns;
+ CBlock b = CreateAndProcessBlock(noTxns, scriptPubKey);
+ coinbaseTxns.push_back(b.vtx[0]);
+ }
+}
+
+//
+// Create a new block with just given transactions, coinbase paying to
+// scriptPubKey, and try to add it to the current chain.
+//
+CBlock
+TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey)
+{
+ CBlockTemplate *pblocktemplate = CreateNewBlock(scriptPubKey);
+ CBlock& block = pblocktemplate->block;
+
+ // Replace mempool-selected txns with just coinbase plus passed-in txns:
+ block.vtx.resize(1);
+ BOOST_FOREACH(const CMutableTransaction& tx, txns)
+ block.vtx.push_back(tx);
+ // IncrementExtraNonce creates a valid coinbase and merkleRoot
+ unsigned int extraNonce = 0;
+ IncrementExtraNonce(&block, chainActive.Tip(), extraNonce);
+
+ while (!CheckProofOfWork(block.GetHash(), block.nBits, Params(CBaseChainParams::REGTEST).GetConsensus())) ++block.nNonce;
+
+ CValidationState state;
+ ProcessNewBlock(state, NULL, &block, true, NULL);
+
+ CBlock result = block;
+ delete pblocktemplate;
+ return result;
+}
+
+TestChain100Setup::~TestChain100Setup()
+{
+}
+
void Shutdown(void* parg)
{
exit(0);
diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h
index 2f75332d40..0bab4b6831 100644
--- a/src/test/test_bitcoin.h
+++ b/src/test/test_bitcoin.h
@@ -1,6 +1,8 @@
#ifndef BITCOIN_TEST_TEST_BITCOIN_H
#define BITCOIN_TEST_TEST_BITCOIN_H
+#include "chainparamsbase.h"
+#include "key.h"
#include "txdb.h"
#include <boost/filesystem.hpp>
@@ -10,7 +12,7 @@
* This just configures logging and chain parameters.
*/
struct BasicTestingSetup {
- BasicTestingSetup();
+ BasicTestingSetup(const std::string& chainName = CBaseChainParams::MAIN);
~BasicTestingSetup();
};
@@ -23,8 +25,30 @@ struct TestingSetup: public BasicTestingSetup {
boost::filesystem::path pathTemp;
boost::thread_group threadGroup;
- TestingSetup();
+ TestingSetup(const std::string& chainName = CBaseChainParams::MAIN);
~TestingSetup();
};
+class CBlock;
+struct CMutableTransaction;
+class CScript;
+
+//
+// Testing fixture that pre-creates a
+// 100-block REGTEST-mode block chain
+//
+struct TestChain100Setup : public TestingSetup {
+ TestChain100Setup();
+
+ // Create a new block with just given transactions, coinbase paying to
+ // scriptPubKey, and try to add it to the current chain.
+ CBlock CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns,
+ const CScript& scriptPubKey);
+
+ ~TestChain100Setup();
+
+ std::vector<CTransaction> coinbaseTxns; // For convenience, coinbase transactions
+ CKey coinbaseKey; // private/public key needed to spend coinbase transactions
+};
+
#endif
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 260524f7cc..f9423bc0de 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -11,10 +11,11 @@
#include "core_io.h"
#include "key.h"
#include "keystore.h"
-#include "main.h"
+#include "main.h" // For CheckTransaction
#include "policy/policy.h"
#include "script/script.h"
#include "script/script_error.h"
+#include "utilstrencodings.h"
#include <map>
#include <string>
@@ -25,7 +26,7 @@
#include <boost/test/unit_test.hpp>
#include <boost/assign/list_of.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -344,18 +345,35 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
t.vout[0].nValue = 501; // dust
BOOST_CHECK(!IsStandardTx(t, reason));
- t.vout[0].nValue = 601; // not dust
+ t.vout[0].nValue = 2730; // not dust
BOOST_CHECK(IsStandardTx(t, reason));
t.vout[0].scriptPubKey = CScript() << OP_1;
BOOST_CHECK(!IsStandardTx(t, reason));
- // 80-byte TX_NULL_DATA (standard)
+ // MAX_OP_RETURN_RELAY-byte TX_NULL_DATA (standard)
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
+ BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY, t.vout[0].scriptPubKey.size());
BOOST_CHECK(IsStandardTx(t, reason));
- // 81-byte TX_NULL_DATA (non-standard)
+ // MAX_OP_RETURN_RELAY+1-byte TX_NULL_DATA (non-standard)
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800");
+ BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
+ BOOST_CHECK(!IsStandardTx(t, reason));
+
+ // Data payload can be encoded in any way...
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("");
+ BOOST_CHECK(IsStandardTx(t, reason));
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("00") << ParseHex("01");
+ BOOST_CHECK(IsStandardTx(t, reason));
+ // OP_RESERVED *is* considered to be a PUSHDATA type opcode by IsPushOnly()!
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RESERVED << -1 << 0 << ParseHex("01") << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11 << 12 << 13 << 14 << 15 << 16;
+ BOOST_CHECK(IsStandardTx(t, reason));
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << 0 << ParseHex("01") << 2 << ParseHex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
+ BOOST_CHECK(IsStandardTx(t, reason));
+
+ // ...so long as it only contains PUSHDATA's
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RETURN;
BOOST_CHECK(!IsStandardTx(t, reason));
// TX_NULL_DATA w/o PUSHDATA
diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp
new file mode 100644
index 0000000000..9b8e1c088b
--- /dev/null
+++ b/src/test/txvalidationcache_tests.cpp
@@ -0,0 +1,86 @@
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "consensus/validation.h"
+#include "key.h"
+#include "main.h"
+#include "miner.h"
+#include "pubkey.h"
+#include "txmempool.h"
+#include "random.h"
+#include "script/standard.h"
+#include "test/test_bitcoin.h"
+#include "utiltime.h"
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_AUTO_TEST_SUITE(tx_validationcache_tests)
+
+static bool
+ToMemPool(CMutableTransaction& tx)
+{
+ LOCK(cs_main);
+
+ CValidationState state;
+ return AcceptToMemoryPool(mempool, state, tx, false, NULL, true, false);
+}
+
+BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
+{
+ // Make sure skipping validation of transctions that were
+ // validated going into the memory pool does not allow
+ // double-spends in blocks to pass validation when they should not.
+
+ CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
+
+ // Create a double-spend of mature coinbase txn:
+ std::vector<CMutableTransaction> spends;
+ spends.resize(2);
+ for (int i = 0; i < 2; i++)
+ {
+ spends[i].vin.resize(1);
+ spends[i].vin[0].prevout.hash = coinbaseTxns[0].GetHash();
+ spends[i].vin[0].prevout.n = 0;
+ spends[i].vout.resize(1);
+ spends[i].vout[0].nValue = 11*CENT;
+ spends[i].vout[0].scriptPubKey = scriptPubKey;
+
+ // Sign:
+ std::vector<unsigned char> vchSig;
+ uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL);
+ BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
+ vchSig.push_back((unsigned char)SIGHASH_ALL);
+ spends[i].vin[0].scriptSig << vchSig;
+ }
+
+ CBlock block;
+
+ // Test 1: block with both of those transactions should be rejected.
+ block = CreateAndProcessBlock(spends, scriptPubKey);
+ BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash());
+
+ // Test 2: ... and should be rejected if spend1 is in the memory pool
+ BOOST_CHECK(ToMemPool(spends[0]));
+ block = CreateAndProcessBlock(spends, scriptPubKey);
+ BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash());
+ mempool.clear();
+
+ // Test 3: ... and should be rejected if spend2 is in the memory pool
+ BOOST_CHECK(ToMemPool(spends[1]));
+ block = CreateAndProcessBlock(spends, scriptPubKey);
+ BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash());
+ mempool.clear();
+
+ // Final sanity test: first spend in mempool, second in block, that's OK:
+ std::vector<CMutableTransaction> oneSpend;
+ oneSpend.push_back(spends[0]);
+ BOOST_CHECK(ToMemPool(spends[1]));
+ block = CreateAndProcessBlock(oneSpend, scriptPubKey);
+ BOOST_CHECK(chainActive.Tip()->GetBlockHash() == block.GetHash());
+ // spends[1] should have been removed from the mempool when the
+ // block with spends[0] is accepted:
+ BOOST_CHECK_EQUAL(mempool.size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp
index 16bc8d30f6..945c1acbeb 100644
--- a/src/test/univalue_tests.cpp
+++ b/src/test/univalue_tests.cpp
@@ -6,7 +6,7 @@
#include <vector>
#include <string>
#include <map>
-#include "univalue/univalue.h"
+#include <univalue.h>
#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
@@ -49,7 +49,7 @@ BOOST_AUTO_TEST_CASE(univalue_constructor)
double vd = -7.21;
UniValue v7(vd);
- BOOST_CHECK(v7.isReal());
+ BOOST_CHECK(v7.isNum());
BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21");
string vs("yawn");
@@ -127,7 +127,7 @@ BOOST_AUTO_TEST_CASE(univalue_set)
BOOST_CHECK_EQUAL(v.getValStr(), "zum");
BOOST_CHECK(v.setFloat(-1.01));
- BOOST_CHECK(v.isReal());
+ BOOST_CHECK(v.isNum());
BOOST_CHECK_EQUAL(v.getValStr(), "-1.01");
BOOST_CHECK(v.setInt((int)1023));
@@ -272,7 +272,7 @@ BOOST_AUTO_TEST_CASE(univalue_object)
objTypes["distance"] = UniValue::VNUM;
objTypes["time"] = UniValue::VNUM;
objTypes["calories"] = UniValue::VNUM;
- objTypes["temperature"] = UniValue::VREAL;
+ objTypes["temperature"] = UniValue::VNUM;
objTypes["cat1"] = UniValue::VNUM;
objTypes["cat2"] = UniValue::VNUM;
BOOST_CHECK(obj.checkObject(objTypes));
@@ -314,6 +314,21 @@ BOOST_AUTO_TEST_CASE(univalue_readwrite)
BOOST_CHECK(obj["key3"].isObject());
BOOST_CHECK_EQUAL(strJson1, v.write());
+
+ /* Check for (correctly reporting) a parsing error if the initial
+ JSON construct is followed by more stuff. Note that whitespace
+ is, of course, exempt. */
+
+ BOOST_CHECK(v.read(" {}\n "));
+ BOOST_CHECK(v.isObject());
+ BOOST_CHECK(v.read(" []\n "));
+ BOOST_CHECK(v.isArray());
+
+ BOOST_CHECK(!v.read("@{}"));
+ BOOST_CHECK(!v.read("{} garbage"));
+ BOOST_CHECK(!v.read("[]{}"));
+ BOOST_CHECK(!v.read("{}[]"));
+ BOOST_CHECK(!v.read("{} 42"));
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index e956cc5b90..997dc31931 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -413,10 +413,10 @@ BOOST_AUTO_TEST_CASE(test_FormatSubVersion)
comments.push_back(std::string("comment1"));
std::vector<std::string> comments2;
comments2.push_back(std::string("comment1"));
- comments2.push_back(std::string("comment2"));
+ comments2.push_back(SanitizeString(std::string("Comment2; .,_?@-; !\"#$%&'()*+/<=>[]\\^`{|}~"), SAFE_CHARS_UA_COMMENT)); // Semicolon is discouraged but not forbidden by BIP-0014
BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector<std::string>()),std::string("/Test:0.9.99/"));
BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:0.9.99(comment1)/"));
- BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:0.9.99(comment1; comment2)/"));
+ BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:0.9.99(comment1; Comment2; .,_?@-; )/"));
}
BOOST_AUTO_TEST_CASE(test_ParseFixedPoint)
diff --git a/src/timedata.cpp b/src/timedata.cpp
index c3e9c75f6e..0641009537 100644
--- a/src/timedata.cpp
+++ b/src/timedata.cpp
@@ -40,16 +40,20 @@ static int64_t abs64(int64_t n)
return (n >= 0 ? n : -n);
}
+#define BITCOIN_TIMEDATA_MAX_SAMPLES 200
+
void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
{
LOCK(cs_nTimeOffset);
// Ignore duplicates
static set<CNetAddr> setKnown;
+ if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES)
+ return;
if (!setKnown.insert(ip).second)
return;
// Add data
- static CMedianFilter<int64_t> vTimeOffsets(200,0);
+ static CMedianFilter<int64_t> vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0);
vTimeOffsets.input(nOffsetSample);
LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
@@ -95,9 +99,8 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
if (!fMatch)
{
fDone = true;
- string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.");
+ string strMessage = _("Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.");
strMiscWarning = strMessage;
- LogPrintf("*** %s\n", strMessage);
uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
}
}
diff --git a/src/txdb.cpp b/src/txdb.cpp
index 935b784676..f0868a1ebf 100644
--- a/src/txdb.cpp
+++ b/src/txdb.cpp
@@ -5,6 +5,7 @@
#include "txdb.h"
+#include "chain.h"
#include "chainparams.h"
#include "hash.h"
#include "main.h"
@@ -28,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 {
@@ -58,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++;
@@ -71,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) {
@@ -104,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();
@@ -113,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];
@@ -139,13 +121,15 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
nTotalAmount += out.nValue;
}
}
- stats.nSerializedSize += 32 + slValue.size();
+ stats.nSerializedSize += 32 + pcursor->GetKeySize();
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);
@@ -157,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);
}
@@ -173,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);
@@ -193,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);
@@ -233,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..586ab55d0d 100644
--- a/src/txdb.h
+++ b/src/txdb.h
@@ -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 0e65aa1c59..47e8de5361 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -13,16 +13,11 @@
#include "streams.h"
#include "util.h"
#include "utilmoneystr.h"
+#include "utiltime.h"
#include "version.h"
using namespace std;
-CTxMemPoolEntry::CTxMemPoolEntry():
- nFee(0), nTxSize(0), nModSize(0), nUsageSize(0), nTime(0), dPriority(0.0), hadNoDependencies(false)
-{
- nHeight = MEMPOOL_HEIGHT;
-}
-
CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
int64_t _nTime, double _dPriority,
unsigned int _nHeight, bool poolHasNoInputsOf):
@@ -32,6 +27,10 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
nModSize = tx.CalculateModifiedSize(nTxSize);
nUsageSize = RecursiveDynamicUsage(tx);
+
+ nCountWithDescendants = 1;
+ nSizeWithDescendants = nTxSize;
+ nFeesWithDescendants = nFee;
}
CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other)
@@ -48,15 +47,277 @@ CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const
return dResult;
}
-CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) :
+// Update the given tx for any in-mempool descendants.
+// Assumes that setMemPoolChildren is correct for the given tx and all
+// descendants.
+bool CTxMemPool::UpdateForDescendants(txiter updateIt, int maxDescendantsToVisit, cacheMap &cachedDescendants, const std::set<uint256> &setExclude)
+{
+ // Track the number of entries (outside setExclude) that we'd need to visit
+ // (will bail out if it exceeds maxDescendantsToVisit)
+ int nChildrenToVisit = 0;
+
+ setEntries stageEntries, setAllDescendants;
+ stageEntries = GetMemPoolChildren(updateIt);
+
+ while (!stageEntries.empty()) {
+ const txiter cit = *stageEntries.begin();
+ if (cit->IsDirty()) {
+ // Don't consider any more children if any descendant is dirty
+ return false;
+ }
+ setAllDescendants.insert(cit);
+ stageEntries.erase(cit);
+ const setEntries &setChildren = GetMemPoolChildren(cit);
+ BOOST_FOREACH(const txiter childEntry, setChildren) {
+ cacheMap::iterator cacheIt = cachedDescendants.find(childEntry);
+ if (cacheIt != cachedDescendants.end()) {
+ // We've already calculated this one, just add the entries for this set
+ // but don't traverse again.
+ BOOST_FOREACH(const txiter cacheEntry, cacheIt->second) {
+ // update visit count only for new child transactions
+ // (outside of setExclude and stageEntries)
+ if (setAllDescendants.insert(cacheEntry).second &&
+ !setExclude.count(cacheEntry->GetTx().GetHash()) &&
+ !stageEntries.count(cacheEntry)) {
+ nChildrenToVisit++;
+ }
+ }
+ } else if (!setAllDescendants.count(childEntry)) {
+ // Schedule for later processing and update our visit count
+ if (stageEntries.insert(childEntry).second && !setExclude.count(childEntry->GetTx().GetHash())) {
+ nChildrenToVisit++;
+ }
+ }
+ if (nChildrenToVisit > maxDescendantsToVisit) {
+ return false;
+ }
+ }
+ }
+ // setAllDescendants now contains all in-mempool descendants of updateIt.
+ // Update and add to cached descendant map
+ int64_t modifySize = 0;
+ CAmount modifyFee = 0;
+ int64_t modifyCount = 0;
+ BOOST_FOREACH(txiter cit, setAllDescendants) {
+ if (!setExclude.count(cit->GetTx().GetHash())) {
+ modifySize += cit->GetTxSize();
+ modifyFee += cit->GetFee();
+ modifyCount++;
+ cachedDescendants[updateIt].insert(cit);
+ }
+ }
+ mapTx.modify(updateIt, update_descendant_state(modifySize, modifyFee, modifyCount));
+ return true;
+}
+
+// vHashesToUpdate is the set of transaction hashes from a disconnected block
+// which has been re-added to the mempool.
+// for each entry, look for descendants that are outside hashesToUpdate, and
+// add fee/size information for such descendants to the parent.
+void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashesToUpdate)
+{
+ LOCK(cs);
+ // For each entry in vHashesToUpdate, store the set of in-mempool, but not
+ // in-vHashesToUpdate transactions, so that we don't have to recalculate
+ // descendants when we come across a previously seen entry.
+ cacheMap mapMemPoolDescendantsToUpdate;
+
+ // Use a set for lookups into vHashesToUpdate (these entries are already
+ // accounted for in the state of their ancestors)
+ std::set<uint256> setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end());
+
+ // Iterate in reverse, so that whenever we are looking at at a transaction
+ // we are sure that all in-mempool descendants have already been processed.
+ // This maximizes the benefit of the descendant cache and guarantees that
+ // setMemPoolChildren will be updated, an assumption made in
+ // UpdateForDescendants.
+ BOOST_REVERSE_FOREACH(const uint256 &hash, vHashesToUpdate) {
+ // we cache the in-mempool children to avoid duplicate updates
+ setEntries setChildren;
+ // calculate children from mapNextTx
+ txiter it = mapTx.find(hash);
+ if (it == mapTx.end()) {
+ continue;
+ }
+ std::map<COutPoint, CInPoint>::iterator iter = mapNextTx.lower_bound(COutPoint(hash, 0));
+ // First calculate the children, and update setMemPoolChildren to
+ // include them, and update their setMemPoolParents to include this tx.
+ for (; iter != mapNextTx.end() && iter->first.hash == hash; ++iter) {
+ const uint256 &childHash = iter->second.ptx->GetHash();
+ txiter childIter = mapTx.find(childHash);
+ assert(childIter != mapTx.end());
+ // We can skip updating entries we've encountered before or that
+ // are in the block (which are already accounted for).
+ if (setChildren.insert(childIter).second && !setAlreadyIncluded.count(childHash)) {
+ UpdateChild(it, childIter, true);
+ UpdateParent(childIter, it, true);
+ }
+ }
+ if (!UpdateForDescendants(it, 100, mapMemPoolDescendantsToUpdate, setAlreadyIncluded)) {
+ // Mark as dirty if we can't do the calculation.
+ mapTx.modify(it, set_dirty());
+ }
+ }
+}
+
+bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */)
+{
+ setEntries parentHashes;
+ const CTransaction &tx = entry.GetTx();
+
+ if (fSearchForParents) {
+ // Get parents of this transaction that are in the mempool
+ // GetMemPoolParents() is only valid for entries in the mempool, so we
+ // iterate mapTx to find parents.
+ for (unsigned int i = 0; i < tx.vin.size(); i++) {
+ txiter piter = mapTx.find(tx.vin[i].prevout.hash);
+ if (piter != mapTx.end()) {
+ parentHashes.insert(piter);
+ if (parentHashes.size() + 1 > limitAncestorCount) {
+ errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount);
+ return false;
+ }
+ }
+ }
+ } else {
+ // If we're not searching for parents, we require this to be an
+ // entry in the mempool already.
+ txiter it = mapTx.iterator_to(entry);
+ parentHashes = GetMemPoolParents(it);
+ }
+
+ size_t totalSizeWithAncestors = entry.GetTxSize();
+
+ while (!parentHashes.empty()) {
+ txiter stageit = *parentHashes.begin();
+
+ setAncestors.insert(stageit);
+ parentHashes.erase(stageit);
+ totalSizeWithAncestors += stageit->GetTxSize();
+
+ if (stageit->GetSizeWithDescendants() + entry.GetTxSize() > limitDescendantSize) {
+ errString = strprintf("exceeds descendant size limit for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantSize);
+ return false;
+ } else if (stageit->GetCountWithDescendants() + 1 > limitDescendantCount) {
+ errString = strprintf("too many descendants for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantCount);
+ return false;
+ } else if (totalSizeWithAncestors > limitAncestorSize) {
+ errString = strprintf("exceeds ancestor size limit [limit: %u]", limitAncestorSize);
+ return false;
+ }
+
+ const setEntries & setMemPoolParents = GetMemPoolParents(stageit);
+ BOOST_FOREACH(const txiter &phash, setMemPoolParents) {
+ // If this is a new ancestor, add it.
+ if (setAncestors.count(phash) == 0) {
+ parentHashes.insert(phash);
+ }
+ if (parentHashes.size() + setAncestors.size() + 1 > limitAncestorCount) {
+ errString = strprintf("too many unconfirmed ancestors [limit: %u]", limitAncestorCount);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, setEntries &setAncestors)
+{
+ setEntries parentIters = GetMemPoolParents(it);
+ // add or remove this tx as a child of each parent
+ BOOST_FOREACH(txiter piter, parentIters) {
+ UpdateChild(piter, it, add);
+ }
+ const int64_t updateCount = (add ? 1 : -1);
+ const int64_t updateSize = updateCount * it->GetTxSize();
+ const CAmount updateFee = updateCount * it->GetFee();
+ BOOST_FOREACH(txiter ancestorIt, setAncestors) {
+ mapTx.modify(ancestorIt, update_descendant_state(updateSize, updateFee, updateCount));
+ }
+}
+
+void CTxMemPool::UpdateChildrenForRemoval(txiter it)
+{
+ const setEntries &setMemPoolChildren = GetMemPoolChildren(it);
+ BOOST_FOREACH(txiter updateIt, setMemPoolChildren) {
+ UpdateParent(updateIt, it, false);
+ }
+}
+
+void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove)
+{
+ // For each entry, walk back all ancestors and decrement size associated with this
+ // transaction
+ const uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
+ BOOST_FOREACH(txiter removeIt, entriesToRemove) {
+ setEntries setAncestors;
+ const CTxMemPoolEntry &entry = *removeIt;
+ std::string dummy;
+ // Since this is a tx that is already in the mempool, we can call CMPA
+ // with fSearchForParents = false. If the mempool is in a consistent
+ // state, then using true or false should both be correct, though false
+ // should be a bit faster.
+ // However, if we happen to be in the middle of processing a reorg, then
+ // the mempool can be in an inconsistent state. In this case, the set
+ // of ancestors reachable via mapLinks will be the same as the set of
+ // ancestors whose packages include this transaction, because when we
+ // add a new transaction to the mempool in addUnchecked(), we assume it
+ // has no children, and in the case of a reorg where that assumption is
+ // false, the in-mempool children aren't linked to the in-block tx's
+ // until UpdateTransactionsFromBlock() is called.
+ // So if we're being called during a reorg, ie before
+ // UpdateTransactionsFromBlock() has been called, then mapLinks[] will
+ // differ from the set of mempool parents we'd calculate by searching,
+ // and it's important that we use the mapLinks[] notion of ancestor
+ // transactions as the set of things to update for removal.
+ CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false);
+ // Note that UpdateAncestorsOf severs the child links that point to
+ // removeIt in the entries for the parents of removeIt. This is
+ // fine since we don't need to use the mempool children of any entries
+ // to walk back over our ancestors (but we do need the mempool
+ // parents!)
+ UpdateAncestorsOf(false, removeIt, setAncestors);
+ }
+ // After updating all the ancestor sizes, we can now sever the link between each
+ // transaction being removed and any mempool children (ie, update setMemPoolParents
+ // for each direct child of a transaction being removed).
+ BOOST_FOREACH(txiter removeIt, entriesToRemove) {
+ UpdateChildrenForRemoval(removeIt);
+ }
+}
+
+void CTxMemPoolEntry::SetDirty()
+{
+ nCountWithDescendants = 0;
+ nSizeWithDescendants = nTxSize;
+ nFeesWithDescendants = nFee;
+}
+
+void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount)
+{
+ if (!IsDirty()) {
+ nSizeWithDescendants += modifySize;
+ assert(int64_t(nSizeWithDescendants) > 0);
+ nFeesWithDescendants += modifyFee;
+ assert(nFeesWithDescendants >= 0);
+ nCountWithDescendants += modifyCount;
+ assert(int64_t(nCountWithDescendants) > 0);
+ }
+}
+
+CTxMemPool::CTxMemPool(const CFeeRate& _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;
- minerPolicyEstimator = new CBlockPolicyEstimator(_minRelayFee);
+ minerPolicyEstimator = new CBlockPolicyEstimator(_minReasonableRelayFee);
+ minReasonableRelayFee = _minReasonableRelayFee;
}
CTxMemPool::~CTxMemPool()
@@ -89,34 +350,103 @@ void CTxMemPool::AddTransactionsUpdated(unsigned int n)
nTransactionsUpdated += n;
}
-
-bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate)
+bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate)
{
// Add to memory pool without checking anything.
// Used by main.cpp AcceptToMemoryPool(), which DOES do
// all the appropriate checks.
LOCK(cs);
- mapTx[hash] = entry;
- const CTransaction& tx = mapTx[hash].GetTx();
- for (unsigned int i = 0; i < tx.vin.size(); i++)
+ indexed_transaction_set::iterator newit = mapTx.insert(entry).first;
+ mapLinks.insert(make_pair(newit, TxLinks()));
+
+ // Update cachedInnerUsage to include contained transaction's usage.
+ // (When we update the entry for in-mempool parents, memory usage will be
+ // further updated.)
+ cachedInnerUsage += entry.DynamicMemoryUsage();
+
+ const CTransaction& tx = newit->GetTx();
+ std::set<uint256> setParentTransactions;
+ for (unsigned int i = 0; i < tx.vin.size(); i++) {
mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i);
+ setParentTransactions.insert(tx.vin[i].prevout.hash);
+ }
+ // Don't bother worrying about child transactions of this one.
+ // Normal case of a new transaction arriving is that there can't be any
+ // children, because such children would be orphans.
+ // An exception to that is if a transaction enters that used to be in a block.
+ // In that case, our disconnect block logic will call UpdateTransactionsFromBlock
+ // to clean up the mess we're leaving here.
+
+ // Update ancestors with information about this tx
+ BOOST_FOREACH (const uint256 &phash, setParentTransactions) {
+ txiter pit = mapTx.find(phash);
+ if (pit != mapTx.end()) {
+ UpdateParent(newit, pit, true);
+ }
+ }
+ UpdateAncestorsOf(true, newit, setAncestors);
+
nTransactionsUpdated++;
totalTxSize += entry.GetTxSize();
- cachedInnerUsage += entry.DynamicMemoryUsage();
minerPolicyEstimator->processTransaction(entry, fCurrentEstimate);
return true;
}
+void CTxMemPool::removeUnchecked(txiter it)
+{
+ const uint256 hash = it->GetTx().GetHash();
+ BOOST_FOREACH(const CTxIn& txin, it->GetTx().vin)
+ mapNextTx.erase(txin.prevout);
+
+ totalTxSize -= it->GetTxSize();
+ cachedInnerUsage -= it->DynamicMemoryUsage();
+ cachedInnerUsage -= memusage::DynamicUsage(mapLinks[it].parents) + memusage::DynamicUsage(mapLinks[it].children);
+ mapLinks.erase(it);
+ mapTx.erase(it);
+ nTransactionsUpdated++;
+ minerPolicyEstimator->removeTx(hash);
+}
+
+// Calculates descendants of entry that are not already in setDescendants, and adds to
+// setDescendants. Assumes entryit is already a tx in the mempool and setMemPoolChildren
+// is correct for tx and all descendants.
+// Also assumes that if an entry is in setDescendants already, then all
+// in-mempool descendants of it are already in setDescendants as well, so that we
+// can save time by not iterating over those entries.
+void CTxMemPool::CalculateDescendants(txiter entryit, setEntries &setDescendants)
+{
+ setEntries stage;
+ if (setDescendants.count(entryit) == 0) {
+ stage.insert(entryit);
+ }
+ // Traverse down the children of entry, only adding children that are not
+ // accounted for in setDescendants already (because those children have either
+ // already been walked, or will be walked in this iteration).
+ while (!stage.empty()) {
+ txiter it = *stage.begin();
+ setDescendants.insert(it);
+ stage.erase(it);
+
+ const setEntries &setChildren = GetMemPoolChildren(it);
+ BOOST_FOREACH(const txiter &childiter, setChildren) {
+ if (!setDescendants.count(childiter)) {
+ stage.insert(childiter);
+ }
+ }
+ }
+}
void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& removed, bool fRecursive)
{
// Remove transaction from memory pool
{
LOCK(cs);
- std::deque<uint256> txToRemove;
- txToRemove.push_back(origTx.GetHash());
- if (fRecursive && !mapTx.count(origTx.GetHash())) {
+ setEntries txToRemove;
+ txiter origit = mapTx.find(origTx.GetHash());
+ if (origit != mapTx.end()) {
+ txToRemove.insert(origit);
+ } else if (fRecursive) {
// If recursively removing but origTx isn't in the mempool
// be sure to remove any children that are in the pool. This can
// happen during chain re-orgs if origTx isn't re-accepted into
@@ -125,34 +455,23 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem
std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(origTx.GetHash(), i));
if (it == mapNextTx.end())
continue;
- txToRemove.push_back(it->second.ptx->GetHash());
+ txiter nextit = mapTx.find(it->second.ptx->GetHash());
+ assert(nextit != mapTx.end());
+ txToRemove.insert(nextit);
}
}
- while (!txToRemove.empty())
- {
- uint256 hash = txToRemove.front();
- txToRemove.pop_front();
- if (!mapTx.count(hash))
- continue;
- const CTransaction& tx = mapTx[hash].GetTx();
- if (fRecursive) {
- for (unsigned int i = 0; i < tx.vout.size(); i++) {
- std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(hash, i));
- if (it == mapNextTx.end())
- continue;
- txToRemove.push_back(it->second.ptx->GetHash());
- }
+ setEntries setAllRemoves;
+ if (fRecursive) {
+ BOOST_FOREACH(txiter it, txToRemove) {
+ CalculateDescendants(it, setAllRemoves);
}
- BOOST_FOREACH(const CTxIn& txin, tx.vin)
- mapNextTx.erase(txin.prevout);
-
- removed.push_back(tx);
- totalTxSize -= mapTx[hash].GetTxSize();
- cachedInnerUsage -= mapTx[hash].DynamicMemoryUsage();
- mapTx.erase(hash);
- nTransactionsUpdated++;
- minerPolicyEstimator->removeTx(hash);
+ } else {
+ setAllRemoves.swap(txToRemove);
+ }
+ BOOST_FOREACH(txiter it, setAllRemoves) {
+ removed.push_back(it->GetTx());
}
+ RemoveStaged(setAllRemoves);
}
}
@@ -161,10 +480,10 @@ void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned in
// Remove transactions spending a coinbase which are now immature
LOCK(cs);
list<CTransaction> transactionsToRemove;
- for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
- const CTransaction& tx = it->second.GetTx();
+ for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
+ const CTransaction& tx = it->GetTx();
BOOST_FOREACH(const CTxIn& txin, tx.vin) {
- std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash);
+ indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
if (it2 != mapTx.end())
continue;
const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
@@ -210,8 +529,10 @@ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned i
BOOST_FOREACH(const CTransaction& tx, vtx)
{
uint256 hash = tx.GetHash();
- if (mapTx.count(hash))
- entries.push_back(mapTx[hash]);
+
+ indexed_transaction_set::iterator i = mapTx.find(hash);
+ if (i != mapTx.end())
+ entries.push_back(*i);
}
BOOST_FOREACH(const CTransaction& tx, vtx)
{
@@ -222,18 +543,29 @@ 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)
@@ -248,19 +580,25 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
LOCK(cs);
list<const CTxMemPoolEntry*> waitingOnDependants;
- for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
+ for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
unsigned int i = 0;
- checkTotal += it->second.GetTxSize();
- innerUsage += it->second.DynamicMemoryUsage();
- const CTransaction& tx = it->second.GetTx();
+ checkTotal += it->GetTxSize();
+ innerUsage += it->DynamicMemoryUsage();
+ const CTransaction& tx = it->GetTx();
+ txlinksMap::const_iterator linksiter = mapLinks.find(it);
+ assert(linksiter != mapLinks.end());
+ const TxLinks &links = linksiter->second;
+ innerUsage += memusage::DynamicUsage(links.parents) + memusage::DynamicUsage(links.children);
bool fDependsWait = false;
+ setEntries setParentCheck;
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
// Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
- std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash);
+ indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
if (it2 != mapTx.end()) {
- const CTransaction& tx2 = it2->second.GetTx();
+ const CTransaction& tx2 = it2->GetTx();
assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
fDependsWait = true;
+ setParentCheck.insert(it2);
} else {
const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash);
assert(coins && coins->IsAvailable(txin.prevout.n));
@@ -272,8 +610,35 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
assert(it3->second.n == i);
i++;
}
+ assert(setParentCheck == GetMemPoolParents(it));
+ // Check children against mapNextTx
+ CTxMemPool::setEntries setChildrenCheck;
+ std::map<COutPoint, CInPoint>::const_iterator iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0));
+ int64_t childSizes = 0;
+ CAmount childFees = 0;
+ for (; iter != mapNextTx.end() && iter->first.hash == it->GetTx().GetHash(); ++iter) {
+ txiter childit = mapTx.find(iter->second.ptx->GetHash());
+ assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions
+ if (setChildrenCheck.insert(childit).second) {
+ childSizes += childit->GetTxSize();
+ childFees += childit->GetFee();
+ }
+ }
+ assert(setChildrenCheck == GetMemPoolChildren(it));
+ // Also check to make sure size/fees is greater than sum with immediate children.
+ // just a sanity check, not definitive that this calc is correct...
+ // also check that the size is less than the size of the entire mempool.
+ if (!it->IsDirty()) {
+ assert(it->GetSizeWithDescendants() >= childSizes + it->GetTxSize());
+ assert(it->GetFeesWithDescendants() >= childFees + it->GetFee());
+ } else {
+ assert(it->GetSizeWithDescendants() == it->GetTxSize());
+ assert(it->GetFeesWithDescendants() == it->GetFee());
+ }
+ assert(it->GetFeesWithDescendants() >= 0);
+
if (fDependsWait)
- waitingOnDependants.push_back(&it->second);
+ waitingOnDependants.push_back(&(*it));
else {
CValidationState state;
assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL));
@@ -297,8 +662,8 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
}
for (std::map<COutPoint, CInPoint>::const_iterator it = mapNextTx.begin(); it != mapNextTx.end(); it++) {
uint256 hash = it->second.ptx->GetHash();
- map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(hash);
- const CTransaction& tx = it2->second.GetTx();
+ indexed_transaction_set::const_iterator it2 = mapTx.find(hash);
+ const CTransaction& tx = it2->GetTx();
assert(it2 != mapTx.end());
assert(&tx == it->second.ptx);
assert(tx.vin.size() > it->second.n);
@@ -315,16 +680,16 @@ void CTxMemPool::queryHashes(vector<uint256>& vtxid)
LOCK(cs);
vtxid.reserve(mapTx.size());
- for (map<uint256, CTxMemPoolEntry>::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi)
- vtxid.push_back((*mi).first);
+ for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi)
+ vtxid.push_back(mi->GetTx().GetHash());
}
bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const
{
LOCK(cs);
- map<uint256, CTxMemPoolEntry>::const_iterator i = mapTx.find(hash);
+ indexed_transaction_set::const_iterator i = mapTx.find(hash);
if (i == mapTx.end()) return false;
- result = i->second.GetTx();
+ result = i->GetTx();
return true;
}
@@ -349,7 +714,7 @@ CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const
minerPolicyEstimator->Write(fileout);
}
catch (const std::exception&) {
- LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)");
+ LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)\n");
return false;
}
return true;
@@ -368,7 +733,7 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
minerPolicyEstimator->Read(filein);
}
catch (const std::exception&) {
- LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)");
+ LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)\n");
return false;
}
return true;
@@ -385,10 +750,10 @@ void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash,
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;
@@ -430,5 +795,135 @@ bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const {
size_t CTxMemPool::DynamicMemoryUsage() const {
LOCK(cs);
- return memusage::DynamicUsage(mapTx) + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + cachedInnerUsage;
+ // Estimate the overhead of mapTx to be 9 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented.
+ return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 9 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + cachedInnerUsage;
+}
+
+void CTxMemPool::RemoveStaged(setEntries &stage) {
+ AssertLockHeld(cs);
+ UpdateForRemoveFromMempool(stage);
+ BOOST_FOREACH(const txiter& it, stage) {
+ removeUnchecked(it);
+ }
+}
+
+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);
+ setEntries setAncestors;
+ uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
+ std::string dummy;
+ CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy);
+ return addUnchecked(hash, entry, setAncestors, fCurrentEstimate);
+}
+
+void CTxMemPool::UpdateChild(txiter entry, txiter child, bool add)
+{
+ setEntries s;
+ if (add && mapLinks[entry].children.insert(child).second) {
+ cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
+ } else if (!add && mapLinks[entry].children.erase(child)) {
+ cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
+ }
+}
+
+void CTxMemPool::UpdateParent(txiter entry, txiter parent, bool add)
+{
+ setEntries s;
+ if (add && mapLinks[entry].parents.insert(parent).second) {
+ cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
+ } else if (!add && mapLinks[entry].parents.erase(parent)) {
+ cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
+ }
+}
+
+const CTxMemPool::setEntries & CTxMemPool::GetMemPoolParents(txiter entry) const
+{
+ assert (entry != mapTx.end());
+ txlinksMap::const_iterator it = mapLinks.find(entry);
+ assert(it != mapLinks.end());
+ return it->second.parents;
+}
+
+const CTxMemPool::setEntries & CTxMemPool::GetMemPoolChildren(txiter entry) const
+{
+ assert (entry != mapTx.end());
+ txlinksMap::const_iterator it = mapLinks.find(entry);
+ assert(it != mapLinks.end());
+ return it->second.children;
+}
+
+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) {
+ 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->GetFeesWithDescendants(), it->GetSizeWithDescendants());
+ removed += minReasonableRelayFee;
+ trackPackageRemoved(removed);
+ maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
+
+ setEntries stage;
+ CalculateDescendants(mapTx.project<0>(it), stage);
+ RemoveStaged(stage);
+ nTxnRemoved += stage.size();
+ }
+
+ 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 ea36ce1ad5..dedc7ba72c 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -7,12 +7,17 @@
#define BITCOIN_TXMEMPOOL_H
#include <list>
+#include <set>
#include "amount.h"
#include "coins.h"
#include "primitives/transaction.h"
#include "sync.h"
+#undef foreach
+#include "boost/multi_index_container.hpp"
+#include "boost/multi_index/ordered_index.hpp"
+
class CAutoFile;
inline double AllowFreeThreshold()
@@ -30,9 +35,25 @@ inline bool AllowFree(double dPriority)
/** Fake height value used in CCoins to signify they are only in the memory pool (since 0.8) */
static const unsigned int MEMPOOL_HEIGHT = 0x7FFFFFFF;
-/**
- * CTxMemPool stores these:
+class CTxMemPool;
+
+/** \class CTxMemPoolEntry
+ *
+ * CTxMemPoolEntry stores data about the correponding transaction, as well
+ * as data about all in-mempool transactions that depend on the transaction
+ * ("descendant" transactions).
+ *
+ * When a new entry is added to the mempool, we update the descendant state
+ * (nCountWithDescendants, nSizeWithDescendants, and nFeesWithDescendants) for
+ * all ancestors of the newly added transaction.
+ *
+ * If updating the descendant state is skipped, we can mark the entry as
+ * "dirty", and set nSizeWithDescendants/nFeesWithDescendants to equal nTxSize/
+ * nTxFee. (This can potentially happen during a reorg, where we limit the
+ * amount of work we're willing to do to avoid consuming too much CPU.)
+ *
*/
+
class CTxMemPoolEntry
{
private:
@@ -46,20 +67,120 @@ private:
unsigned int nHeight; //! Chain height when entering the mempool
bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool
+ // Information about descendants of this transaction that are in the
+ // mempool; if we remove this transaction we must remove all of these
+ // descendants as well. if nCountWithDescendants is 0, treat this entry as
+ // dirty, and nSizeWithDescendants and nFeesWithDescendants will not be
+ // correct.
+ uint64_t nCountWithDescendants; //! number of descendant transactions
+ uint64_t nSizeWithDescendants; //! ... and size
+ CAmount nFeesWithDescendants; //! ... and total fees (all including us)
+
public:
CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
int64_t _nTime, double _dPriority, unsigned int _nHeight, bool poolHasNoInputsOf = false);
- CTxMemPoolEntry();
CTxMemPoolEntry(const CTxMemPoolEntry& other);
const CTransaction& GetTx() const { return this->tx; }
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; }
bool WasClearAtEntry() const { return hadNoDependencies; }
size_t DynamicMemoryUsage() const { return nUsageSize; }
+
+ // Adjusts the descendant state, if this entry is not dirty.
+ void UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount);
+
+ /** We can set the entry to be dirty if doing the full calculation of in-
+ * mempool descendants will be too expensive, which can potentially happen
+ * when re-adding transactions from a block back to the mempool.
+ */
+ void SetDirty();
+ bool IsDirty() const { return nCountWithDescendants == 0; }
+
+ uint64_t GetCountWithDescendants() const { return nCountWithDescendants; }
+ uint64_t GetSizeWithDescendants() const { return nSizeWithDescendants; }
+ CAmount GetFeesWithDescendants() const { return nFeesWithDescendants; }
+};
+
+// Helpers for modifying CTxMemPool::mapTx, which is a boost multi_index.
+struct update_descendant_state
+{
+ update_descendant_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount) :
+ modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount)
+ {}
+
+ void operator() (CTxMemPoolEntry &e)
+ { e.UpdateState(modifySize, modifyFee, modifyCount); }
+
+ private:
+ int64_t modifySize;
+ CAmount modifyFee;
+ int64_t modifyCount;
+};
+
+struct set_dirty
+{
+ void operator() (CTxMemPoolEntry &e)
+ { e.SetDirty(); }
+};
+
+// extracts a TxMemPoolEntry's transaction hash
+struct mempoolentry_txid
+{
+ typedef uint256 result_type;
+ result_type operator() (const CTxMemPoolEntry &entry) const
+ {
+ return entry.GetTx().GetHash();
+ }
+};
+
+/** \class CompareTxMemPoolEntryByFee
+ *
+ * Sort an entry by max(feerate of entry's tx, feerate with all descendants).
+ */
+class CompareTxMemPoolEntryByFee
+{
+public:
+ bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b)
+ {
+ bool fUseADescendants = UseDescendantFeeRate(a);
+ bool fUseBDescendants = UseDescendantFeeRate(b);
+
+ double aFees = fUseADescendants ? a.GetFeesWithDescendants() : a.GetFee();
+ double aSize = fUseADescendants ? a.GetSizeWithDescendants() : a.GetTxSize();
+
+ double bFees = fUseBDescendants ? b.GetFeesWithDescendants() : b.GetFee();
+ double bSize = fUseBDescendants ? b.GetSizeWithDescendants() : b.GetTxSize();
+
+ // Avoid division by rewriting (a/b > c/d) as (a*d > c*b).
+ double f1 = aFees * bSize;
+ double f2 = aSize * bFees;
+
+ if (f1 == f2) {
+ return a.GetTime() >= b.GetTime();
+ }
+ return f1 < f2;
+ }
+
+ // Calculate which feerate to use for an entry (avoiding division).
+ bool UseDescendantFeeRate(const CTxMemPoolEntry &a)
+ {
+ double f1 = (double)a.GetFee() * a.GetSizeWithDescendants();
+ double f2 = (double)a.GetFeesWithDescendants() * a.GetTxSize();
+ return f2 > f1;
+ }
+};
+
+class CompareTxMemPoolEntryByEntryTime
+{
+public:
+ bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b)
+ {
+ return a.GetTime() < b.GetTime();
+ }
};
class CBlockPolicyEstimator;
@@ -87,6 +208,72 @@ public:
* are added to the pool: if a new transaction double-spends
* an input of a transaction in the pool, it is dropped,
* as are non-standard transactions.
+ *
+ * CTxMemPool::mapTx, and CTxMemPoolEntry bookkeeping:
+ *
+ * mapTx is a boost::multi_index that sorts the mempool on 3 criteria:
+ * - transaction hash
+ * - feerate [we use max(feerate of tx, feerate of tx with all descendants)]
+ * - time in mempool
+ *
+ * Note: the term "descendant" refers to in-mempool transactions that depend on
+ * this one, while "ancestor" refers to in-mempool transactions that a given
+ * transaction depends on.
+ *
+ * In order for the feerate sort to remain correct, we must update transactions
+ * in the mempool when new descendants arrive. To facilitate this, we track
+ * the set of in-mempool direct parents and direct children in mapLinks. Within
+ * each CTxMemPoolEntry, we track the size and fees of all descendants.
+ *
+ * Usually when a new transaction is added to the mempool, it has no in-mempool
+ * children (because any such children would be an orphan). So in
+ * addUnchecked(), we:
+ * - update a new entry's setMemPoolParents to include all in-mempool parents
+ * - update the new entry's direct parents to include the new tx as a child
+ * - update all ancestors of the transaction to include the new tx's size/fee
+ *
+ * When a transaction is removed from the mempool, we must:
+ * - update all in-mempool parents to not track the tx in setMemPoolChildren
+ * - update all ancestors to not include the tx's size/fees in descendant state
+ * - update all in-mempool children to not include it as a parent
+ *
+ * These happen in UpdateForRemoveFromMempool(). (Note that when removing a
+ * transaction along with its descendants, we must calculate that set of
+ * transactions to be removed before doing the removal, or else the mempool can
+ * be in an inconsistent state where it's impossible to walk the ancestors of
+ * a transaction.)
+ *
+ * In the event of a reorg, the assumption that a newly added tx has no
+ * in-mempool children is false. In particular, the mempool is in an
+ * inconsistent state while new transactions are being added, because there may
+ * be descendant transactions of a tx coming from a disconnected block that are
+ * unreachable from just looking at transactions in the mempool (the linking
+ * transactions may also be in the disconnected block, waiting to be added).
+ * Because of this, there's not much benefit in trying to search for in-mempool
+ * children in addUnchecked(). Instead, in the special case of transactions
+ * being added from a disconnected block, we require the caller to clean up the
+ * state, to account for in-mempool, out-of-block descendants for all the
+ * in-block transactions by calling UpdateTransactionsFromBlock(). Note that
+ * until this is called, the mempool state is not consistent, and in particular
+ * mapLinks may not be correct (and therefore functions like
+ * CalculateMemPoolAncestors() and CalculateDescendants() that rely
+ * on them to walk the mempool are not generally safe to use).
+ *
+ * Computational limits:
+ *
+ * Updating all in-mempool ancestors of a newly added transaction can be slow,
+ * if no bound exists on how many in-mempool ancestors there may be.
+ * CalculateMemPoolAncestors() takes configurable limits that are designed to
+ * prevent these calculations from being too CPU intensive.
+ *
+ * Adding transactions from a disconnected block can be very time consuming,
+ * because we don't have a way to limit the number of in-mempool descendants.
+ * To bound CPU processing, we limit the amount of work we're willing to do
+ * to properly update the descendant information for a tx being added from
+ * a disconnected block. If we would exceed the limit, then we instead mark
+ * the entry as "dirty", and set the feerate for sorting purposes to be equal
+ * the feerate of the transaction without any descendants.
+ *
*/
class CTxMemPool
{
@@ -98,13 +285,72 @@ private:
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<
+ // sorted by txid
+ boost::multi_index::ordered_unique<mempoolentry_txid>,
+ // sorted by fee rate
+ boost::multi_index::ordered_non_unique<
+ boost::multi_index::identity<CTxMemPoolEntry>,
+ CompareTxMemPoolEntryByFee
+ >,
+ // sorted by entry time
+ boost::multi_index::ordered_non_unique<
+ boost::multi_index::identity<CTxMemPoolEntry>,
+ CompareTxMemPoolEntryByEntryTime
+ >
+ >
+ > indexed_transaction_set;
+
mutable CCriticalSection cs;
- std::map<uint256, CTxMemPoolEntry> mapTx;
+ indexed_transaction_set mapTx;
+ typedef indexed_transaction_set::nth_index<0>::type::iterator txiter;
+ struct CompareIteratorByHash {
+ bool operator()(const txiter &a, const txiter &b) const {
+ return a->GetTx().GetHash() < b->GetTx().GetHash();
+ }
+ };
+ typedef std::set<txiter, CompareIteratorByHash> setEntries;
+
+private:
+ typedef std::map<txiter, setEntries, CompareIteratorByHash> cacheMap;
+
+ struct TxLinks {
+ setEntries parents;
+ setEntries children;
+ };
+
+ typedef std::map<txiter, TxLinks, CompareIteratorByHash> txlinksMap;
+ txlinksMap mapLinks;
+
+ const setEntries & GetMemPoolParents(txiter entry) const;
+ const setEntries & GetMemPoolChildren(txiter entry) const;
+ void UpdateParent(txiter entry, txiter parent, bool add);
+ void UpdateChild(txiter entry, txiter child, bool add);
+
+public:
std::map<COutPoint, CInPoint> mapNextTx;
std::map<uint256, std::pair<double, CAmount> > mapDeltas;
- 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();
/**
@@ -116,13 +362,20 @@ public:
void check(const CCoinsViewCache *pcoins) const;
void setSanityCheck(bool _fSanityCheck) { fSanityCheck = _fSanityCheck; }
+ // addUnchecked must updated state for all ancestors of a given transaction,
+ // to track size/count of descendant transactions. First version of
+ // addUnchecked can be used to have it call CalculateMemPoolAncestors(), and
+ // then invoke the second version.
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true);
+ bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate = true);
+
void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false);
void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight);
void removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed);
void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
std::list<CTransaction>& conflicts, 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;
@@ -135,9 +388,52 @@ 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:
+ /** Remove a set of transactions from the mempool.
+ * If a transaction is in this set, then all in-mempool descendants must
+ * also be in the set.*/
+ void RemoveStaged(setEntries &stage);
+
+ /** When adding transactions from a disconnected block back to the mempool,
+ * new mempool entries may have children in the mempool (which is generally
+ * not the case when otherwise adding transactions).
+ * UpdateTransactionsFromBlock() will find child transactions and update the
+ * descendant state for each transaction in hashesToUpdate (excluding any
+ * child transactions present in hashesToUpdate, which are already accounted
+ * for). Note: hashesToUpdate should be the set of transactions from the
+ * disconnected block that have been accepted back into the mempool.
+ */
+ void UpdateTransactionsFromBlock(const std::vector<uint256> &hashesToUpdate);
+
+ /** Try to calculate all in-mempool ancestors of entry.
+ * (these are all calculated including the tx itself)
+ * limitAncestorCount = max number of ancestors
+ * limitAncestorSize = max size of ancestors
+ * limitDescendantCount = max number of descendants any ancestor can have
+ * limitDescendantSize = max size of descendants any ancestor can have
+ * errString = populated with error reason if any limits are hit
+ * fSearchForParents = whether to search a tx's vin for in-mempool parents, or
+ * look up parents from mapLinks. Must be true for entries not in the mempool
+ */
+ bool CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents = true);
+
+ /** 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. */
+ void TrimToSize(size_t sizelimit);
+
+ /** 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);
@@ -169,6 +465,48 @@ public:
bool ReadFeeEstimates(CAutoFile& filein);
size_t DynamicMemoryUsage() const;
+
+private:
+ /** UpdateForDescendants is used by UpdateTransactionsFromBlock to update
+ * the descendants for a single transaction that has been added to the
+ * mempool but may have child transactions in the mempool, eg during a
+ * chain reorg. setExclude is the set of descendant transactions in the
+ * mempool that must not be accounted for (because any descendants in
+ * setExclude were added to the mempool after the transaction being
+ * updated and hence their state is already reflected in the parent
+ * state).
+ *
+ * If updating an entry requires looking at more than maxDescendantsToVisit
+ * transactions, outside of the ones in setExclude, then give up.
+ *
+ * cachedDescendants will be updated with the descendants of the transaction
+ * being updated, so that future invocations don't need to walk the
+ * same transaction again, if encountered in another transaction chain.
+ */
+ bool UpdateForDescendants(txiter updateIt,
+ int maxDescendantsToVisit,
+ cacheMap &cachedDescendants,
+ const std::set<uint256> &setExclude);
+ /** Update ancestors of hash to add/remove it as a descendant transaction. */
+ void UpdateAncestorsOf(bool add, txiter hash, setEntries &setAncestors);
+ /** For each transaction being removed, update ancestors and any direct children. */
+ void UpdateForRemoveFromMempool(const setEntries &entriesToRemove);
+ /** Sever link between specified transaction and direct children. */
+ void UpdateChildrenForRemoval(txiter entry);
+ /** Populate setDescendants with all in-mempool descendants of hash.
+ * Assumes that setDescendants includes all in-mempool descendants of anything
+ * already in it. */
+ void CalculateDescendants(txiter it, setEntries &setDescendants);
+
+ /** Before calling removeUnchecked for a given transaction,
+ * UpdateForRemoveFromMempool must be called on the entire (dependent) set
+ * of transactions being removed at the same time. We use each
+ * CTxMemPoolEntry's setMemPoolParents in order to walk ancestors of a
+ * given transaction that is removed, so we can't remove intermediate
+ * transactions in a chain before we've updated all the state for the
+ * removal.
+ */
+ void removeUnchecked(txiter entry);
};
/**
diff --git a/src/ui_interface.h b/src/ui_interface.h
index 32a92a4b81..e402479933 100644
--- a/src/ui_interface.h
+++ b/src/ui_interface.h
@@ -95,6 +95,9 @@ public:
/** New block has been accepted */
boost::signals2::signal<void (const uint256& hash)> NotifyBlockTip;
+
+ /** Banlist did change. */
+ boost::signals2::signal<void (void)> BannedListChanged;
};
extern CClientUIInterface uiInterface;
diff --git a/src/univalue/.gitignore b/src/univalue/.gitignore
new file mode 100644
index 0000000000..a7a2ca9197
--- /dev/null
+++ b/src/univalue/.gitignore
@@ -0,0 +1,31 @@
+.deps/
+INSTALL
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache/
+compile
+config.log
+config.status
+config.guess
+config.sub
+configure
+depcomp
+install-sh
+missing
+stamp-h1
+univalue-config.h*
+test-driver
+libtool
+ltmain.sh
+
+*.a
+*.la
+*.lo
+*.logs
+*.o
+*.pc
+*.trs
+
+.dirstamp
+.libs
diff --git a/src/univalue/.travis.yml b/src/univalue/.travis.yml
new file mode 100644
index 0000000000..af632c78d9
--- /dev/null
+++ b/src/univalue/.travis.yml
@@ -0,0 +1,52 @@
+
+language: cpp
+
+compiler:
+ - clang
+ - gcc
+
+os:
+ - linux
+ - osx
+
+sudo: false
+
+env:
+ global:
+ - MAKEJOBS=-j3
+ - RUN_TESTS=true
+ - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out
+
+cache:
+ apt: true
+
+addons:
+ apt:
+ packages:
+ - pkg-config
+
+before_script:
+ - if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi
+ - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh
+
+script:
+ - if [ -n "$UNIVALUE_CONFIG" ]; then unset CC; unset CXX; fi
+ - OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST
+ - UNIVALUE_CONFIG_ALL="--prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib"
+ - ./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
+
+matrix:
+ fast_finish: true
+ include:
+ - os: linux
+ compiler: gcc
+ env: UNIVALUE_CONFIG=--host=x86_64-w64-mingw32 RUN_TESTS=false
+ addons:
+ apt:
+ packages:
+ - g++-mingw-w64-x86-64
+ - gcc-mingw-w64-x86-64
+ - binutils-mingw-w64-x86-64
diff --git a/src/univalue/COPYING b/src/univalue/COPYING
new file mode 100644
index 0000000000..1fb429f356
--- /dev/null
+++ b/src/univalue/COPYING
@@ -0,0 +1,19 @@
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/src/univalue/Makefile.am b/src/univalue/Makefile.am
new file mode 100644
index 0000000000..df9e66229c
--- /dev/null
+++ b/src/univalue/Makefile.am
@@ -0,0 +1,84 @@
+ACLOCAL_AMFLAGS = -I build-aux/m4
+.PHONY: gen
+.INTERMEDIATE: $(GENBIN)
+
+include_HEADERS = include/univalue.h
+noinst_HEADERS = lib/univalue_escapes.h
+
+lib_LTLIBRARIES = libunivalue.la
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = pc/libunivalue.pc
+
+libunivalue_la_SOURCES = \
+ lib/univalue.cpp \
+ lib/univalue_read.cpp \
+ lib/univalue_write.cpp
+
+libunivalue_la_LDFLAGS = \
+ -version-info $(LIBUNIVALUE_CURRENT):$(LIBUNIVALUE_REVISION):$(LIBUNIVALUE_AGE) \
+ -no-undefined
+libunivalue_la_CXXFLAGS = -I$(top_srcdir)/include
+
+TESTS = test/unitester
+
+GENBIN = gen/gen$(BUILD_EXEEXT)
+GEN_SRCS = gen/gen.cpp
+
+$(GENBIN): $(GEN_SRCS)
+ @echo Building $@
+ $(AM_V_at)c++ -I$(top_srcdir)/include -o $@ $<
+
+gen: lib/univalue_escapes.h $(GENBIN)
+ @echo Updating $<
+ $(AM_V_at)$(GENBIN) > lib/univalue_escapes.h
+
+noinst_PROGRAMS = $(TESTS)
+
+TEST_DATA_DIR=test
+
+test_unitester_SOURCES = test/unitester.cpp
+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)
+
+TEST_FILES = \
+ $(TEST_DATA_DIR)/fail10.json \
+ $(TEST_DATA_DIR)/fail11.json \
+ $(TEST_DATA_DIR)/fail12.json \
+ $(TEST_DATA_DIR)/fail13.json \
+ $(TEST_DATA_DIR)/fail14.json \
+ $(TEST_DATA_DIR)/fail15.json \
+ $(TEST_DATA_DIR)/fail16.json \
+ $(TEST_DATA_DIR)/fail17.json \
+ $(TEST_DATA_DIR)/fail18.json \
+ $(TEST_DATA_DIR)/fail19.json \
+ $(TEST_DATA_DIR)/fail1.json \
+ $(TEST_DATA_DIR)/fail20.json \
+ $(TEST_DATA_DIR)/fail21.json \
+ $(TEST_DATA_DIR)/fail22.json \
+ $(TEST_DATA_DIR)/fail23.json \
+ $(TEST_DATA_DIR)/fail24.json \
+ $(TEST_DATA_DIR)/fail25.json \
+ $(TEST_DATA_DIR)/fail26.json \
+ $(TEST_DATA_DIR)/fail27.json \
+ $(TEST_DATA_DIR)/fail28.json \
+ $(TEST_DATA_DIR)/fail29.json \
+ $(TEST_DATA_DIR)/fail2.json \
+ $(TEST_DATA_DIR)/fail30.json \
+ $(TEST_DATA_DIR)/fail31.json \
+ $(TEST_DATA_DIR)/fail32.json \
+ $(TEST_DATA_DIR)/fail33.json \
+ $(TEST_DATA_DIR)/fail34.json \
+ $(TEST_DATA_DIR)/fail3.json \
+ $(TEST_DATA_DIR)/fail4.json \
+ $(TEST_DATA_DIR)/fail5.json \
+ $(TEST_DATA_DIR)/fail6.json \
+ $(TEST_DATA_DIR)/fail7.json \
+ $(TEST_DATA_DIR)/fail8.json \
+ $(TEST_DATA_DIR)/fail9.json \
+ $(TEST_DATA_DIR)/pass1.json \
+ $(TEST_DATA_DIR)/pass2.json \
+ $(TEST_DATA_DIR)/pass3.json
+
+EXTRA_DIST=$(TEST_FILES) $(GEN_SRCS)
diff --git a/src/univalue/README b/src/univalue/README
new file mode 100644
index 0000000000..48167b083b
--- /dev/null
+++ b/src/univalue/README
@@ -0,0 +1,7 @@
+
+ UniValue
+
+A universal value object, with JSON encoding (output) and decoding (input).
+
+Built as a single dynamic RAII C++ object class, and no templates.
+
diff --git a/src/univalue/TODO b/src/univalue/TODO
new file mode 100644
index 0000000000..5530048e92
--- /dev/null
+++ b/src/univalue/TODO
@@ -0,0 +1,10 @@
+
+Rearrange tree for easier 'git subtree' style use
+
+Move towards C++11 etc.
+
+Namespace support - must come up with useful shorthand, avoiding
+long Univalue::Univalue::Univalue usages forced upon library users.
+
+Improve test suite
+
diff --git a/src/univalue/autogen.sh b/src/univalue/autogen.sh
new file mode 100755
index 0000000000..4b38721faa
--- /dev/null
+++ b/src/univalue/autogen.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+set -e
+srcdir="$(dirname $0)"
+cd "$srcdir"
+if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="`which glibtoolize 2>/dev/null`"; then
+ LIBTOOLIZE="${GLIBTOOLIZE}"
+ export LIBTOOLIZE
+fi
+autoreconf --install --force
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
new file mode 100644
index 0000000000..6cd9516229
--- /dev/null
+++ b/src/univalue/configure.ac
@@ -0,0 +1,69 @@
+m4_define([libunivalue_major_version], [1])
+m4_define([libunivalue_minor_version], [1])
+m4_define([libunivalue_micro_version], [1])
+m4_define([libunivalue_interface_age], [1])
+# If you need a modifier for the version number.
+# Normally empty, but can be used to make "fixup" releases.
+m4_define([libunivalue_extraversion], [])
+
+dnl libtool versioning from libunivalue
+m4_define([libunivalue_current], [m4_eval(100 * libunivalue_minor_version + libunivalue_micro_version - libunivalue_interface_age)])
+m4_define([libunivalue_binary_age], [m4_eval(100 * libunivalue_minor_version + libunivalue_micro_version)])
+m4_define([libunivalue_revision], [libunivalue_interface_age])
+m4_define([libunivalue_age], [m4_eval(libunivalue_binary_age - libunivalue_interface_age)])
+m4_define([libunivalue_version], [libunivalue_major_version().libunivalue_minor_version().libunivalue_micro_version()libunivalue_extraversion()])
+
+
+AC_INIT([univalue], [1.0.0],
+ [http://github.com/jgarzik/univalue/])
+
+dnl make the compilation flags quiet unless V=1 is used
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+AC_PREREQ(2.60)
+AC_CONFIG_SRCDIR([lib/univalue.cpp])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_MACRO_DIR([build-aux/m4])
+AC_CONFIG_HEADERS([univalue-config.h])
+AM_INIT_AUTOMAKE([subdir-objects foreign])
+
+LIBUNIVALUE_MAJOR_VERSION=libunivalue_major_version
+LIBUNIVALUE_MINOR_VERSION=libunivalue_minor_version
+LIBUNIVALUE_MICRO_VERSION=libunivalue_micro_version
+LIBUNIVALUE_INTERFACE_AGE=libunivalue_interface_age
+
+# ABI version
+# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+LIBUNIVALUE_CURRENT=libunivalue_current
+LIBUNIVALUE_REVISION=libunivalue_revision
+LIBUNIVALUE_AGE=libunivalue_age
+
+AC_SUBST(LIBUNIVALUE_CURRENT)
+AC_SUBST(LIBUNIVALUE_REVISION)
+AC_SUBST(LIBUNIVALUE_AGE)
+
+LT_INIT
+LT_LANG([C++])
+
+case $host in
+ *mingw*)
+ LIBTOOL_APP_LDFLAGS="$LIBTOOL_APP_LDFLAGS -all-static"
+ ;;
+esac
+
+BUILD_EXEEXT=
+case $build in
+ *mingw*)
+ BUILD_EXEEXT=".exe"
+ ;;
+esac
+
+AC_CONFIG_FILES([
+ Makefile
+ pc/libunivalue.pc
+ pc/libunivalue-uninstalled.pc])
+
+AC_SUBST(LIBTOOL_APP_LDFLAGS)
+AC_SUBST(BUILD_EXEEXT)
+AC_OUTPUT
+
diff --git a/src/univalue/gen.cpp b/src/univalue/gen/gen.cpp
index 5e5a4d4aed..5e5a4d4aed 100644
--- a/src/univalue/gen.cpp
+++ b/src/univalue/gen/gen.cpp
diff --git a/src/univalue/univalue.h b/src/univalue/include/univalue.h
index 54239741e2..ac05116011 100644
--- a/src/univalue/univalue.h
+++ b/src/univalue/include/univalue.h
@@ -1,11 +1,13 @@
// Copyright 2014 BitPay Inc.
+// Copyright 2015 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_UNIVALUE_UNIVALUE_H
-#define BITCOIN_UNIVALUE_UNIVALUE_H
+#ifndef __UNIVALUE_H__
+#define __UNIVALUE_H__
#include <stdint.h>
+
#include <string>
#include <vector>
#include <map>
@@ -16,7 +18,7 @@
class UniValue {
public:
- enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VREAL, VBOOL, };
+ enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };
UniValue() { typ = VNULL; }
UniValue(UniValue::VType initialType, const std::string& initialStr = "") {
@@ -78,7 +80,6 @@ public:
bool isBool() const { return (typ == VBOOL); }
bool isStr() const { return (typ == VSTR); }
bool isNum() const { return (typ == VNUM); }
- bool isReal() const { return (typ == VREAL); }
bool isArray() const { return (typ == VARR); }
bool isObject() const { return (typ == VOBJ); }
@@ -246,4 +247,4 @@ extern const UniValue NullUniValue;
const UniValue& find_value( const UniValue& obj, const std::string& name);
-#endif // BITCOIN_UNIVALUE_UNIVALUE_H
+#endif // __UNIVALUE_H__ \ No newline at end of file
diff --git a/src/univalue/lib/.gitignore b/src/univalue/lib/.gitignore
new file mode 100644
index 0000000000..ee7fc2851c
--- /dev/null
+++ b/src/univalue/lib/.gitignore
@@ -0,0 +1,2 @@
+gen
+.libs
diff --git a/src/univalue/univalue.cpp b/src/univalue/lib/univalue.cpp
index 6920c44c96..883e8651fe 100644
--- a/src/univalue/univalue.cpp
+++ b/src/univalue/lib/univalue.cpp
@@ -1,16 +1,78 @@
// Copyright 2014 BitPay Inc.
+// Copyright 2015 Bitcoin Core Developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <stdint.h>
#include <ctype.h>
+#include <errno.h>
#include <iomanip>
+#include <limits>
#include <sstream>
-#include <stdexcept> // std::runtime_error
+#include <stdexcept>
+#include <stdlib.h>
+#include <string.h>
#include "univalue.h"
-#include "utilstrencodings.h" // ParseXX
+namespace
+{
+static bool ParsePrechecks(const std::string& str)
+{
+ if (str.empty()) // No empty string allowed
+ return false;
+ if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size()-1]))) // No padding allowed
+ return false;
+ if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
+ return false;
+ return true;
+}
+
+bool ParseInt32(const std::string& str, int32_t *out)
+{
+ if (!ParsePrechecks(str))
+ return false;
+ char *endp = NULL;
+ errno = 0; // strtol will not set errno if valid
+ long int n = strtol(str.c_str(), &endp, 10);
+ if(out) *out = (int32_t)n;
+ // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
+ // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
+ // platforms the size of these types may be different.
+ return endp && *endp == 0 && !errno &&
+ n >= std::numeric_limits<int32_t>::min() &&
+ n <= std::numeric_limits<int32_t>::max();
+}
+
+bool ParseInt64(const std::string& str, int64_t *out)
+{
+ if (!ParsePrechecks(str))
+ return false;
+ char *endp = NULL;
+ errno = 0; // strtoll will not set errno if valid
+ long long int n = strtoll(str.c_str(), &endp, 10);
+ if(out) *out = (int64_t)n;
+ // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow
+ // we still have to check that the returned value is within the range of an *int64_t*.
+ return endp && *endp == 0 && !errno &&
+ n >= std::numeric_limits<int64_t>::min() &&
+ n <= std::numeric_limits<int64_t>::max();
+}
+
+bool ParseDouble(const std::string& str, double *out)
+{
+ if (!ParsePrechecks(str))
+ return false;
+ if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
+ return false;
+ std::istringstream text(str);
+ text.imbue(std::locale::classic());
+ double result;
+ text >> result;
+ if(out) *out = result;
+ return text.eof() && !text.fail();
+}
+}
using namespace std;
@@ -86,7 +148,7 @@ bool UniValue::setFloat(double val)
oss << std::setprecision(16) << val;
bool ret = setNumStr(oss.str());
- typ = VREAL;
+ typ = VNUM;
return ret;
}
@@ -210,7 +272,6 @@ const char *uvTypeName(UniValue::VType t)
case UniValue::VARR: return "array";
case UniValue::VSTR: return "string";
case UniValue::VNUM: return "number";
- case UniValue::VREAL: return "number";
}
// not reached
@@ -280,7 +341,7 @@ int64_t UniValue::get_int64() const
double UniValue::get_real() const
{
- if (typ != VREAL && typ != VNUM)
+ if (typ != VNUM)
throw std::runtime_error("JSON value is not a number as expected");
double retval;
if (!ParseDouble(getValStr(), &retval))
diff --git a/src/univalue/univalue_escapes.h b/src/univalue/lib/univalue_escapes.h
index 4133b24ca1..4133b24ca1 100644
--- a/src/univalue/univalue_escapes.h
+++ b/src/univalue/lib/univalue_escapes.h
diff --git a/src/univalue/univalue_read.cpp b/src/univalue/lib/univalue_read.cpp
index 261771811d..64591234cb 100644
--- a/src/univalue/univalue_read.cpp
+++ b/src/univalue/lib/univalue_read.cpp
@@ -244,16 +244,16 @@ bool UniValue::read(const char *raw)
bool expectColon = false;
vector<UniValue*> stack;
+ string tokenVal;
+ unsigned int consumed;
enum jtokentype tok = JTOK_NONE;
enum jtokentype last_tok = JTOK_NONE;
- while (1) {
+ do {
last_tok = tok;
- string tokenVal;
- unsigned int consumed;
tok = getJsonToken(tokenVal, consumed, raw);
if (tok == JTOK_NONE || tok == JTOK_ERR)
- break;
+ return false;
raw += consumed;
switch (tok) {
@@ -377,9 +377,11 @@ bool UniValue::read(const char *raw)
default:
return false;
}
- }
+ } while (!stack.empty ());
- if (stack.size() != 0)
+ /* Check that nothing follows the initial construct (parsed above). */
+ tok = getJsonToken(tokenVal, consumed, raw);
+ if (tok != JTOK_NONE)
return false;
return true;
diff --git a/src/univalue/univalue_write.cpp b/src/univalue/lib/univalue_write.cpp
index d360c253b0..bce3997af7 100644
--- a/src/univalue/univalue_write.cpp
+++ b/src/univalue/lib/univalue_write.cpp
@@ -61,13 +61,6 @@ string UniValue::write(unsigned int prettyIndent,
case VSTR:
s += "\"" + json_escape(val) + "\"";
break;
- case VREAL:
- {
- std::stringstream ss;
- ss << std::showpoint << std::fixed << std::setprecision(8) << get_real();
- s += ss.str();
- }
- break;
case VNUM:
s += val;
break;
diff --git a/src/univalue/pc/libunivalue-uninstalled.pc.in b/src/univalue/pc/libunivalue-uninstalled.pc.in
new file mode 100644
index 0000000000..b7f53e875e
--- /dev/null
+++ b/src/univalue/pc/libunivalue-uninstalled.pc.in
@@ -0,0 +1,9 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libunivalue
+Description: libunivalue, C++ universal value object and JSON library
+Version: @VERSION@
+Libs: ${pc_top_builddir}/${pcfiledir}/libunivalue.la
diff --git a/src/univalue/pc/libunivalue.pc.in b/src/univalue/pc/libunivalue.pc.in
new file mode 100644
index 0000000000..358a2d5f73
--- /dev/null
+++ b/src/univalue/pc/libunivalue.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libunivalue
+Description: libunivalue, C++ universal value object and JSON library
+Version: @VERSION@
+Libs: -L${libdir} -lunivalue
+Cflags: -I${includedir}
diff --git a/src/univalue/test/.gitignore b/src/univalue/test/.gitignore
new file mode 100644
index 0000000000..4afa094b10
--- /dev/null
+++ b/src/univalue/test/.gitignore
@@ -0,0 +1 @@
+unitester
diff --git a/src/univalue/test/fail1.json b/src/univalue/test/fail1.json
new file mode 100644
index 0000000000..6216b865f1
--- /dev/null
+++ b/src/univalue/test/fail1.json
@@ -0,0 +1 @@
+"A JSON payload should be an object or array, not a string." \ No newline at end of file
diff --git a/src/univalue/test/fail10.json b/src/univalue/test/fail10.json
new file mode 100644
index 0000000000..5d8c0047bd
--- /dev/null
+++ b/src/univalue/test/fail10.json
@@ -0,0 +1 @@
+{"Extra value after close": true} "misplaced quoted value" \ No newline at end of file
diff --git a/src/univalue/test/fail11.json b/src/univalue/test/fail11.json
new file mode 100644
index 0000000000..76eb95b458
--- /dev/null
+++ b/src/univalue/test/fail11.json
@@ -0,0 +1 @@
+{"Illegal expression": 1 + 2} \ No newline at end of file
diff --git a/src/univalue/test/fail12.json b/src/univalue/test/fail12.json
new file mode 100644
index 0000000000..77580a4522
--- /dev/null
+++ b/src/univalue/test/fail12.json
@@ -0,0 +1 @@
+{"Illegal invocation": alert()} \ No newline at end of file
diff --git a/src/univalue/test/fail13.json b/src/univalue/test/fail13.json
new file mode 100644
index 0000000000..379406b59b
--- /dev/null
+++ b/src/univalue/test/fail13.json
@@ -0,0 +1 @@
+{"Numbers cannot have leading zeroes": 013} \ No newline at end of file
diff --git a/src/univalue/test/fail14.json b/src/univalue/test/fail14.json
new file mode 100644
index 0000000000..0ed366b38a
--- /dev/null
+++ b/src/univalue/test/fail14.json
@@ -0,0 +1 @@
+{"Numbers cannot be hex": 0x14} \ No newline at end of file
diff --git a/src/univalue/test/fail15.json b/src/univalue/test/fail15.json
new file mode 100644
index 0000000000..fc8376b605
--- /dev/null
+++ b/src/univalue/test/fail15.json
@@ -0,0 +1 @@
+["Illegal backslash escape: \x15"] \ No newline at end of file
diff --git a/src/univalue/test/fail16.json b/src/univalue/test/fail16.json
new file mode 100644
index 0000000000..3fe21d4b53
--- /dev/null
+++ b/src/univalue/test/fail16.json
@@ -0,0 +1 @@
+[\naked] \ No newline at end of file
diff --git a/src/univalue/test/fail17.json b/src/univalue/test/fail17.json
new file mode 100644
index 0000000000..62b9214aed
--- /dev/null
+++ b/src/univalue/test/fail17.json
@@ -0,0 +1 @@
+["Illegal backslash escape: \017"] \ No newline at end of file
diff --git a/src/univalue/test/fail18.json b/src/univalue/test/fail18.json
new file mode 100644
index 0000000000..edac92716f
--- /dev/null
+++ b/src/univalue/test/fail18.json
@@ -0,0 +1 @@
+[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]] \ No newline at end of file
diff --git a/src/univalue/test/fail19.json b/src/univalue/test/fail19.json
new file mode 100644
index 0000000000..3b9c46fa9a
--- /dev/null
+++ b/src/univalue/test/fail19.json
@@ -0,0 +1 @@
+{"Missing colon" null} \ No newline at end of file
diff --git a/src/univalue/test/fail2.json b/src/univalue/test/fail2.json
new file mode 100644
index 0000000000..6b7c11e5a5
--- /dev/null
+++ b/src/univalue/test/fail2.json
@@ -0,0 +1 @@
+["Unclosed array" \ No newline at end of file
diff --git a/src/univalue/test/fail20.json b/src/univalue/test/fail20.json
new file mode 100644
index 0000000000..27c1af3e72
--- /dev/null
+++ b/src/univalue/test/fail20.json
@@ -0,0 +1 @@
+{"Double colon":: null} \ No newline at end of file
diff --git a/src/univalue/test/fail21.json b/src/univalue/test/fail21.json
new file mode 100644
index 0000000000..62474573b2
--- /dev/null
+++ b/src/univalue/test/fail21.json
@@ -0,0 +1 @@
+{"Comma instead of colon", null} \ No newline at end of file
diff --git a/src/univalue/test/fail22.json b/src/univalue/test/fail22.json
new file mode 100644
index 0000000000..a7752581bc
--- /dev/null
+++ b/src/univalue/test/fail22.json
@@ -0,0 +1 @@
+["Colon instead of comma": false] \ No newline at end of file
diff --git a/src/univalue/test/fail23.json b/src/univalue/test/fail23.json
new file mode 100644
index 0000000000..494add1ca1
--- /dev/null
+++ b/src/univalue/test/fail23.json
@@ -0,0 +1 @@
+["Bad value", truth] \ No newline at end of file
diff --git a/src/univalue/test/fail24.json b/src/univalue/test/fail24.json
new file mode 100644
index 0000000000..caff239bfc
--- /dev/null
+++ b/src/univalue/test/fail24.json
@@ -0,0 +1 @@
+['single quote'] \ No newline at end of file
diff --git a/src/univalue/test/fail25.json b/src/univalue/test/fail25.json
new file mode 100644
index 0000000000..8b7ad23e01
--- /dev/null
+++ b/src/univalue/test/fail25.json
@@ -0,0 +1 @@
+[" tab character in string "] \ No newline at end of file
diff --git a/src/univalue/test/fail26.json b/src/univalue/test/fail26.json
new file mode 100644
index 0000000000..845d26a6a5
--- /dev/null
+++ b/src/univalue/test/fail26.json
@@ -0,0 +1 @@
+["tab\ character\ in\ string\ "] \ No newline at end of file
diff --git a/src/univalue/test/fail27.json b/src/univalue/test/fail27.json
new file mode 100644
index 0000000000..6b01a2ca4a
--- /dev/null
+++ b/src/univalue/test/fail27.json
@@ -0,0 +1,2 @@
+["line
+break"] \ No newline at end of file
diff --git a/src/univalue/test/fail28.json b/src/univalue/test/fail28.json
new file mode 100644
index 0000000000..621a0101c6
--- /dev/null
+++ b/src/univalue/test/fail28.json
@@ -0,0 +1,2 @@
+["line\
+break"] \ No newline at end of file
diff --git a/src/univalue/test/fail29.json b/src/univalue/test/fail29.json
new file mode 100644
index 0000000000..47ec421bb6
--- /dev/null
+++ b/src/univalue/test/fail29.json
@@ -0,0 +1 @@
+[0e] \ No newline at end of file
diff --git a/src/univalue/test/fail3.json b/src/univalue/test/fail3.json
new file mode 100644
index 0000000000..168c81eb78
--- /dev/null
+++ b/src/univalue/test/fail3.json
@@ -0,0 +1 @@
+{unquoted_key: "keys must be quoted"} \ No newline at end of file
diff --git a/src/univalue/test/fail30.json b/src/univalue/test/fail30.json
new file mode 100644
index 0000000000..8ab0bc4b8b
--- /dev/null
+++ b/src/univalue/test/fail30.json
@@ -0,0 +1 @@
+[0e+] \ No newline at end of file
diff --git a/src/univalue/test/fail31.json b/src/univalue/test/fail31.json
new file mode 100644
index 0000000000..1cce602b51
--- /dev/null
+++ b/src/univalue/test/fail31.json
@@ -0,0 +1 @@
+[0e+-1] \ No newline at end of file
diff --git a/src/univalue/test/fail32.json b/src/univalue/test/fail32.json
new file mode 100644
index 0000000000..45cba7396f
--- /dev/null
+++ b/src/univalue/test/fail32.json
@@ -0,0 +1 @@
+{"Comma instead if closing brace": true, \ No newline at end of file
diff --git a/src/univalue/test/fail33.json b/src/univalue/test/fail33.json
new file mode 100644
index 0000000000..ca5eb19dc9
--- /dev/null
+++ b/src/univalue/test/fail33.json
@@ -0,0 +1 @@
+["mismatch"} \ No newline at end of file
diff --git a/src/univalue/test/fail34.json b/src/univalue/test/fail34.json
new file mode 100644
index 0000000000..3f8be17286
--- /dev/null
+++ b/src/univalue/test/fail34.json
@@ -0,0 +1 @@
+{} garbage \ No newline at end of file
diff --git a/src/univalue/test/fail4.json b/src/univalue/test/fail4.json
new file mode 100644
index 0000000000..9de168bf34
--- /dev/null
+++ b/src/univalue/test/fail4.json
@@ -0,0 +1 @@
+["extra comma",] \ No newline at end of file
diff --git a/src/univalue/test/fail5.json b/src/univalue/test/fail5.json
new file mode 100644
index 0000000000..ddf3ce3d24
--- /dev/null
+++ b/src/univalue/test/fail5.json
@@ -0,0 +1 @@
+["double extra comma",,] \ No newline at end of file
diff --git a/src/univalue/test/fail6.json b/src/univalue/test/fail6.json
new file mode 100644
index 0000000000..ed91580e1b
--- /dev/null
+++ b/src/univalue/test/fail6.json
@@ -0,0 +1 @@
+[ , "<-- missing value"] \ No newline at end of file
diff --git a/src/univalue/test/fail7.json b/src/univalue/test/fail7.json
new file mode 100644
index 0000000000..8a96af3e4e
--- /dev/null
+++ b/src/univalue/test/fail7.json
@@ -0,0 +1 @@
+["Comma after the close"], \ No newline at end of file
diff --git a/src/univalue/test/fail8.json b/src/univalue/test/fail8.json
new file mode 100644
index 0000000000..b28479c6ec
--- /dev/null
+++ b/src/univalue/test/fail8.json
@@ -0,0 +1 @@
+["Extra close"]] \ No newline at end of file
diff --git a/src/univalue/test/fail9.json b/src/univalue/test/fail9.json
new file mode 100644
index 0000000000..5815574f36
--- /dev/null
+++ b/src/univalue/test/fail9.json
@@ -0,0 +1 @@
+{"Extra comma": true,} \ No newline at end of file
diff --git a/src/univalue/test/pass1.json b/src/univalue/test/pass1.json
new file mode 100644
index 0000000000..70e2685436
--- /dev/null
+++ b/src/univalue/test/pass1.json
@@ -0,0 +1,58 @@
+[
+ "JSON Test Pattern pass1",
+ {"object with 1 member":["array with 1 element"]},
+ {},
+ [],
+ -42,
+ true,
+ false,
+ null,
+ {
+ "integer": 1234567890,
+ "real": -9876.543210,
+ "e": 0.123456789e-12,
+ "E": 1.234567890E+34,
+ "": 23456789012E66,
+ "zero": 0,
+ "one": 1,
+ "space": " ",
+ "quote": "\"",
+ "backslash": "\\",
+ "controls": "\b\f\n\r\t",
+ "slash": "/ & \/",
+ "alpha": "abcdefghijklmnopqrstuvwyz",
+ "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
+ "digit": "0123456789",
+ "0123456789": "digit",
+ "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
+ "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
+ "true": true,
+ "false": false,
+ "null": null,
+ "array":[ ],
+ "object":{ },
+ "address": "50 St. James Street",
+ "url": "http://www.JSON.org/",
+ "comment": "// /* <!-- --",
+ "# -- --> */": " ",
+ " s p a c e d " :[1,2 , 3
+
+,
+
+4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
+ "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
+ "quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
+ "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
+: "A key can be any string"
+ },
+ 0.5 ,98.6
+,
+99.44
+,
+
+1066,
+1e1,
+0.1e1,
+1e-1,
+1e00,2e+00,2e-00
+,"rosebud"] \ No newline at end of file
diff --git a/src/univalue/test/pass2.json b/src/univalue/test/pass2.json
new file mode 100644
index 0000000000..d3c63c7ad8
--- /dev/null
+++ b/src/univalue/test/pass2.json
@@ -0,0 +1 @@
+[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] \ No newline at end of file
diff --git a/src/univalue/test/pass3.json b/src/univalue/test/pass3.json
new file mode 100644
index 0000000000..4528d51f1a
--- /dev/null
+++ b/src/univalue/test/pass3.json
@@ -0,0 +1,6 @@
+{
+ "JSON Test Pattern pass3": {
+ "The outermost value": "must be an object or array.",
+ "In this test": "It is an object."
+ }
+}
diff --git a/src/univalue/test/unitester.cpp b/src/univalue/test/unitester.cpp
new file mode 100644
index 0000000000..835556e031
--- /dev/null
+++ b/src/univalue/test/unitester.cpp
@@ -0,0 +1,115 @@
+// Copyright 2014 BitPay Inc.
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <cassert>
+#include <string>
+#include "univalue.h"
+
+#ifndef JSON_TEST_SRC
+#error JSON_TEST_SRC must point to test source directory
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#endif
+
+using namespace std;
+string srcdir(JSON_TEST_SRC);
+
+static void runtest(string filename, const string& jdata)
+{
+ fprintf(stderr, "test %s\n", filename.c_str());
+
+ string prefix = filename.substr(0, 4);
+
+ bool wantPass = (prefix == "pass");
+ bool wantFail = (prefix == "fail");
+ assert(wantPass || wantFail);
+
+ UniValue val;
+ bool testResult = val.read(jdata);
+
+ if (wantPass) {
+ assert(testResult == true);
+ } else {
+ assert(testResult == false);
+ }
+}
+
+static void runtest_file(const char *filename_)
+{
+ string basename(filename_);
+ string filename = srcdir + "/" + basename;
+ FILE *f = fopen(filename.c_str(), "r");
+ assert(f != NULL);
+
+ string jdata;
+
+ char buf[4096];
+ while (!feof(f)) {
+ int bread = fread(buf, 1, sizeof(buf), f);
+ assert(!ferror(f));
+
+ string s(buf, bread);
+ jdata += s;
+ }
+
+ assert(!ferror(f));
+ fclose(f);
+
+ runtest(basename, jdata);
+}
+
+static const char *filenames[] = {
+ "fail10.json",
+ "fail11.json",
+ "fail12.json",
+ "fail13.json",
+ "fail14.json",
+ "fail15.json",
+ "fail16.json",
+ "fail17.json",
+ //"fail18.json", // investigate
+ "fail19.json",
+ "fail1.json",
+ "fail20.json",
+ "fail21.json",
+ "fail22.json",
+ "fail23.json",
+ "fail24.json",
+ "fail25.json",
+ "fail26.json",
+ "fail27.json",
+ "fail28.json",
+ "fail29.json",
+ "fail2.json",
+ "fail30.json",
+ "fail31.json",
+ "fail32.json",
+ "fail33.json",
+ "fail34.json",
+ "fail3.json",
+ "fail4.json", // extra comma
+ "fail5.json",
+ "fail6.json",
+ "fail7.json",
+ "fail8.json",
+ "fail9.json", // extra comma
+ "pass1.json",
+ "pass2.json",
+ "pass3.json",
+};
+
+int main (int argc, char *argv[])
+{
+ for (unsigned int fidx = 0; fidx < ARRAY_SIZE(filenames); fidx++) {
+ runtest_file(filenames[fidx]);
+ }
+
+ return 0;
+}
+
diff --git a/src/util.cpp b/src/util.cpp
index 00d0f3a00d..e8514a2ef0 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -108,13 +108,14 @@ bool fDaemon = false;
bool fServer = false;
string strMiscWarning;
bool fLogTimestamps = false;
+bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS;
bool fLogIPs = false;
volatile bool fReopenDebugLog = false;
CTranslationInterface translationInterface;
/** Init OpenSSL library multithreading support */
static CCriticalSection** ppmutexOpenSSL;
-void locking_callback(int mode, int i, const char* file, int line)
+void locking_callback(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS
{
if (mode & CRYPTO_LOCK) {
ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]);
@@ -175,23 +176,51 @@ instance_of_cinit;
*/
static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT;
+
/**
- * We use boost::call_once() to make sure these are initialized
- * in a thread-safe manner the first time called:
+ * We use boost::call_once() to make sure mutexDebugLog and
+ * vMsgsBeforeOpenLog are initialized in a thread-safe manner.
+ *
+ * NOTE: fileout, mutexDebugLog and sometimes vMsgsBeforeOpenLog
+ * are leaked on exit. This is ugly, but will be cleaned up by
+ * the OS/libc. When the shutdown sequence is fully audited and
+ * tested, explicit destruction of these objects can be implemented.
*/
static FILE* fileout = NULL;
static boost::mutex* mutexDebugLog = NULL;
+static list<string> *vMsgsBeforeOpenLog;
+
+static int FileWriteStr(const std::string &str, FILE *fp)
+{
+ return fwrite(str.data(), 1, str.size(), fp);
+}
static void DebugPrintInit()
{
- assert(fileout == NULL);
assert(mutexDebugLog == NULL);
+ mutexDebugLog = new boost::mutex();
+ vMsgsBeforeOpenLog = new list<string>;
+}
+
+void OpenDebugLog()
+{
+ boost::call_once(&DebugPrintInit, debugPrintInitFlag);
+ boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
+ assert(fileout == NULL);
+ assert(vMsgsBeforeOpenLog);
boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
fileout = fopen(pathDebug.string().c_str(), "a");
if (fileout) setbuf(fileout, NULL); // unbuffered
- mutexDebugLog = new boost::mutex();
+ // dump buffered messages from before we opened the log
+ while (!vMsgsBeforeOpenLog->empty()) {
+ FileWriteStr(vMsgsBeforeOpenLog->front(), fileout);
+ vMsgsBeforeOpenLog->pop_front();
+ }
+
+ delete vMsgsBeforeOpenLog;
+ vMsgsBeforeOpenLog = NULL;
}
bool LogAcceptCategory(const char* category)
@@ -223,59 +252,90 @@ bool LogAcceptCategory(const char* category)
return true;
}
+/**
+ * fStartedNewLine is a state variable held by the calling context that will
+ * suppress printing of the timestamp when multiple calls are made that don't
+ * end in a newline. Initialize it to true, and hold it, in the calling context.
+ */
+static std::string LogTimestampStr(const std::string &str, bool *fStartedNewLine)
+{
+ string strStamped;
+
+ if (!fLogTimestamps)
+ return str;
+
+ if (*fStartedNewLine) {
+ 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')
+ *fStartedNewLine = true;
+ else
+ *fStartedNewLine = false;
+
+ return strStamped;
+}
+
int LogPrintStr(const std::string &str)
{
int ret = 0; // Returns total number of characters written
+ static bool fStartedNewLine = true;
+
+ 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 && AreBaseParamsConfigured())
+ else if (fPrintToDebugLog)
{
- static bool fStartedNewLine = true;
boost::call_once(&DebugPrintInit, debugPrintInitFlag);
-
- if (fileout == NULL)
- return ret;
-
boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);
- // reopen the log file, if requested
- if (fReopenDebugLog) {
- fReopenDebugLog = false;
- boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
- if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL)
- setbuf(fileout, NULL); // unbuffered
+ // buffer if we haven't opened the log yet
+ if (fileout == NULL) {
+ assert(vMsgsBeforeOpenLog);
+ ret = strTimestamped.length();
+ vMsgsBeforeOpenLog->push_back(strTimestamped);
}
-
- // Debug print useful for profiling
- if (fLogTimestamps && fStartedNewLine)
- ret += fprintf(fileout, "%s ", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str());
- if (!str.empty() && str[str.size()-1] == '\n')
- fStartedNewLine = true;
else
- fStartedNewLine = false;
-
- ret = fwrite(str.data(), 1, str.size(), fileout);
+ {
+ // reopen the log file, if requested
+ if (fReopenDebugLog) {
+ fReopenDebugLog = false;
+ boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
+ if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL)
+ setbuf(fileout, NULL); // unbuffered
+ }
+
+ ret = FileWriteStr(strTimestamped, fileout);
+ }
}
-
return ret;
}
-static void InterpretNegativeSetting(string name, map<string, string>& mapSettingsRet)
+/** Interpret string as boolean, for argument parsing */
+static bool InterpretBool(const std::string& strValue)
+{
+ if (strValue.empty())
+ return true;
+ return (atoi(strValue) != 0);
+}
+
+/** Turn -noX into -X=0 */
+static void InterpretNegativeSetting(std::string& strKey, std::string& strValue)
{
- // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
- if (name.find("-no") == 0)
+ if (strKey.length()>3 && strKey[0]=='-' && strKey[1]=='n' && strKey[2]=='o')
{
- std::string positive("-");
- positive.append(name.begin()+3, name.end());
- if (mapSettingsRet.count(positive) == 0)
- {
- bool value = !GetBoolArg(name, false);
- mapSettingsRet[positive] = (value ? "1" : "0");
- }
+ strKey = "-" + strKey.substr(3);
+ strValue = InterpretBool(strValue) ? "0" : "1";
}
}
@@ -307,17 +367,11 @@ void ParseParameters(int argc, const char* const argv[])
// If both --foo and -foo are set, the last takes effect.
if (str.length() > 1 && str[1] == '-')
str = str.substr(1);
+ InterpretNegativeSetting(str, strValue);
mapArgs[str] = strValue;
mapMultiArgs[str].push_back(strValue);
}
-
- // New 0.6 features:
- BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs)
- {
- // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
- InterpretNegativeSetting(entry.first, mapArgs);
- }
}
std::string GetArg(const std::string& strArg, const std::string& strDefault)
@@ -337,11 +391,7 @@ int64_t GetArg(const std::string& strArg, int64_t nDefault)
bool GetBoolArg(const std::string& strArg, bool fDefault)
{
if (mapArgs.count(strArg))
- {
- if (mapArgs[strArg].empty())
- return true;
- return (atoi(mapArgs[strArg]) != 0);
- }
+ return InterpretBool(mapArgs[strArg]);
return fDefault;
}
@@ -492,13 +542,11 @@ void ReadConfigFile(map<string, string>& mapSettingsRet,
{
// Don't overwrite existing settings so command line settings override bitcoin.conf
string strKey = string("-") + it->string_key;
+ string strValue = it->value[0];
+ InterpretNegativeSetting(strKey, strValue);
if (mapSettingsRet.count(strKey) == 0)
- {
- mapSettingsRet[strKey] = it->value[0];
- // interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set)
- InterpretNegativeSetting(strKey, mapSettingsRet);
- }
- mapMultiSettingsRet[strKey].push_back(it->value[0]);
+ mapSettingsRet[strKey] = strValue;
+ mapMultiSettingsRet[strKey].push_back(strValue);
}
// If datadir is changed in .conf file:
ClearDatadirCache();
@@ -752,6 +800,18 @@ void SetupEnvironment()
boost::filesystem::path::imbue(loc);
}
+bool SetupNetworking()
+{
+#ifdef WIN32
+ // Initialize Windows Sockets
+ WSADATA wsadata;
+ int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
+ if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2)
+ return false;
+#endif
+ return true;
+}
+
void SetThreadPriority(int nPriority)
{
#ifdef WIN32
diff --git a/src/util.h b/src/util.h
index 6019e25015..b2779fe782 100644
--- a/src/util.h
+++ b/src/util.h
@@ -28,6 +28,8 @@
#include <boost/signals2/signal.hpp>
#include <boost/thread/exceptions.hpp>
+static const bool DEFAULT_LOGTIMEMICROS = false;
+
/** Signals for translation. */
class CTranslationInterface
{
@@ -44,6 +46,7 @@ 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;
@@ -59,6 +62,7 @@ inline std::string _(const char* psz)
}
void SetupEnvironment();
+bool SetupNetworking();
/** Return true if log accepts specified category */
bool LogAcceptCategory(const char* category);
@@ -125,6 +129,7 @@ void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map
boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
#endif
boost::filesystem::path GetTempPath();
+void OpenDebugLog();
void ShrinkDebugFile();
void runCommand(const std::string& strCommand);
diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp
index 7208ca9474..c5a2b5cdbb 100644
--- a/src/utilstrencodings.cpp
+++ b/src/utilstrencodings.cpp
@@ -14,17 +14,20 @@
using namespace std;
-string SanitizeString(const string& str)
+static const string CHARS_ALPHA_NUM = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+static const string SAFE_CHARS[] =
+{
+ CHARS_ALPHA_NUM + " .,;-_/:?@()", // SAFE_CHARS_DEFAULT
+ CHARS_ALPHA_NUM + " .,;-_?@" // SAFE_CHARS_UA_COMMENT
+};
+
+string SanitizeString(const string& str, int rule)
{
- /**
- * safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything
- * even possibly remotely dangerous like & or >
- */
- static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@()");
string strResult;
for (std::string::size_type i = 0; i < str.size(); i++)
{
- if (safeChars.find(str[i]) != std::string::npos)
+ if (SAFE_CHARS[rule].find(str[i]) != std::string::npos)
strResult.push_back(str[i]);
}
return strResult;
@@ -464,11 +467,12 @@ bool ParseDouble(const std::string& str, double *out)
return false;
if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
return false;
- char *endp = NULL;
- errno = 0; // strtod will not set errno if valid
- double n = strtod(str.c_str(), &endp);
- if(out) *out = n;
- return endp && *endp == 0 && !errno;
+ std::istringstream text(str);
+ text.imbue(std::locale::classic());
+ double result;
+ text >> result;
+ if(out) *out = result;
+ return text.eof() && !text.fail();
}
std::string FormatParagraph(const std::string& in, size_t width, size_t indent)
diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h
index dcd56751f2..ce93e83497 100644
--- a/src/utilstrencodings.h
+++ b/src/utilstrencodings.h
@@ -22,7 +22,21 @@
/** This is needed because the foreach macro can't get over the comma in pair<t1, t2> */
#define PAIRTYPE(t1, t2) std::pair<t1, t2>
-std::string SanitizeString(const std::string& str);
+/** Used by SanitizeString() */
+enum SafeChars
+{
+ SAFE_CHARS_DEFAULT, //!< The full set of allowed chars
+ SAFE_CHARS_UA_COMMENT //!< BIP-0014 subset
+};
+
+/**
+* Remove unsafe chars. Safe chars chosen to allow simple messages/URLs/email
+* addresses, but avoid anything even possibly remotely dangerous like & or >
+* @param[in] str The string to sanitize
+* @param[in] rule The set of safe chars to choose (default: least restrictive)
+* @return A new string without unsafe chars
+*/
+std::string SanitizeString(const std::string& str, int rule = SAFE_CHARS_DEFAULT);
std::vector<unsigned char> ParseHex(const char* psz);
std::vector<unsigned char> ParseHex(const std::string& str);
signed char HexDigit(char c);
diff --git a/src/utiltime.cpp b/src/utiltime.cpp
index d316288999..3202c47f1d 100644
--- a/src/utiltime.cpp
+++ b/src/utiltime.cpp
@@ -40,6 +40,14 @@ int64_t GetTimeMicros()
boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds();
}
+/** 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..241b5211e9 100644
--- a/src/utiltime.h
+++ b/src/utiltime.h
@@ -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.cpp b/src/validationinterface.cpp
index d365f03008..81f3b775f4 100644
--- a/src/validationinterface.cpp
+++ b/src/validationinterface.cpp
@@ -13,6 +13,7 @@ CMainSignals& GetMainSignals()
}
void RegisterValidationInterface(CValidationInterface* pwalletIn) {
+ g_signals.UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1));
g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
@@ -32,6 +33,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
+ g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1));
}
void UnregisterAllValidationInterfaces() {
@@ -43,6 +45,7 @@ void UnregisterAllValidationInterfaces() {
g_signals.SetBestChain.disconnect_all_slots();
g_signals.UpdatedTransaction.disconnect_all_slots();
g_signals.SyncTransaction.disconnect_all_slots();
+ g_signals.UpdatedBlockTip.disconnect_all_slots();
}
void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) {
diff --git a/src/validationinterface.h b/src/validationinterface.h
index fb0ce0bdaa..ffb56d266b 100644
--- a/src/validationinterface.h
+++ b/src/validationinterface.h
@@ -11,6 +11,7 @@
class CBlock;
struct CBlockLocator;
+class CBlockIndex;
class CReserveScript;
class CTransaction;
class CValidationInterface;
@@ -30,6 +31,7 @@ void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL);
class CValidationInterface {
protected:
+ virtual void UpdatedBlockTip(const CBlockIndex *pindex) {}
virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {}
virtual void SetBestChain(const CBlockLocator &locator) {}
virtual void UpdatedTransaction(const uint256 &hash) {}
@@ -44,6 +46,8 @@ protected:
};
struct CMainSignals {
+ /** Notifies listeners of updated block chain tip */
+ boost::signals2::signal<void (const CBlockIndex *)> UpdatedBlockTip;
/** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */
boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction;
/** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
diff --git a/src/version.h b/src/version.h
index 38b3d2e734..6cdddf9255 100644
--- a/src/version.h
+++ b/src/version.h
@@ -9,7 +9,7 @@
* network protocol versioning
*/
-static const int PROTOCOL_VERSION = 70002;
+static const int PROTOCOL_VERSION = 70011;
//! initial proto version, to be increased after version/verack negotiation
static const int INIT_PROTO_VERSION = 209;
@@ -34,4 +34,7 @@ static const int BIP0031_VERSION = 60000;
//! "mempool" command, enhanced "getdata" behavior starts with this version
static const int MEMPOOL_GD_VERSION = 60002;
+//! "filter*" commands are disabled without NODE_BLOOM after and including this version
+static const int NO_BLOOM_VERSION = 70011;
+
#endif // BITCOIN_VERSION_H
diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp
index c7f7e21679..c86ad9758e 100644
--- a/src/wallet/crypter.cpp
+++ b/src/wallet/crypter.cpp
@@ -186,7 +186,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
}
if (keyPass && keyFail)
{
- LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.");
+ LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n");
assert(false);
}
if (keyFail || !keyPass)
@@ -255,7 +255,7 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co
{
LOCK(cs_KeyStore);
if (!IsCrypted())
- return CKeyStore::GetPubKey(address, vchPubKeyOut);
+ return CBasicKeyStore::GetPubKey(address, vchPubKeyOut);
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
if (mi != mapCryptedKeys.end())
@@ -263,6 +263,8 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co
vchPubKeyOut = (*mi).second.first;
return true;
}
+ // Check for watch-only pubkeys
+ return CBasicKeyStore::GetPubKey(address, vchPubKeyOut);
}
return false;
}
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index 5f800474a0..c431fc4013 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "base58.h"
+#include "chain.h"
#include "rpcserver.h"
#include "init.h"
#include "main.h"
@@ -19,7 +20,9 @@
#include <boost/algorithm/string.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
+
+#include <boost/foreach.hpp>
using namespace std;
@@ -94,8 +97,6 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
+ HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false")
);
- if (fPruneMode)
- throw JSONRPCError(RPC_WALLET_ERROR, "Importing keys is disabled in pruned mode");
LOCK2(cs_main, pwalletMain->cs_wallet);
@@ -111,6 +112,9 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
if (params.size() > 2)
fRescan = params[2].get_bool();
+ if (fRescan && fPruneMode)
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode");
+
CBitcoinSecret vchSecret;
bool fGood = vchSecret.SetString(strSecret);
@@ -146,46 +150,123 @@ UniValue importprivkey(const UniValue& params, bool fHelp)
return NullUniValue;
}
+void ImportAddress(const CBitcoinAddress& address, const string& strLabel);
+void ImportScript(const CScript& script, const string& strLabel, bool isRedeemScript)
+{
+ if (!isRedeemScript && ::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE)
+ throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
+
+ pwalletMain->MarkDirty();
+
+ if (!pwalletMain->HaveWatchOnly(script) && !pwalletMain->AddWatchOnly(script))
+ throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
+
+ if (isRedeemScript) {
+ if (!pwalletMain->HaveCScript(script) && !pwalletMain->AddCScript(script))
+ throw JSONRPCError(RPC_WALLET_ERROR, "Error adding p2sh redeemScript to wallet");
+ ImportAddress(CBitcoinAddress(CScriptID(script)), strLabel);
+ }
+}
+
+void ImportAddress(const CBitcoinAddress& address, const string& strLabel)
+{
+ CScript script = GetScriptForDestination(address.Get());
+ ImportScript(script, strLabel, false);
+ // add to address book or update label
+ if (address.IsValid())
+ pwalletMain->SetAddressBook(address.Get(), strLabel, "receive");
+}
+
UniValue importaddress(const UniValue& params, bool fHelp)
{
if (!EnsureWalletIsAvailable(fHelp))
return NullUniValue;
- if (fHelp || params.size() < 1 || params.size() > 3)
+ if (fHelp || params.size() < 1 || params.size() > 4)
throw runtime_error(
- "importaddress \"address\" ( \"label\" rescan )\n"
- "\nAdds an address or script (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n"
+ "importaddress \"address\" ( \"label\" rescan p2sh )\n"
+ "\nAdds a script (in hex) or address that can be watched as if it were in your wallet but cannot be used to spend.\n"
"\nArguments:\n"
- "1. \"address\" (string, required) The address\n"
+ "1. \"script\" (string, required) The hex-encoded script (or address)\n"
"2. \"label\" (string, optional, default=\"\") An optional label\n"
"3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n"
+ "4. p2sh (boolean, optional, default=false) Add the P2SH version of the script as well\n"
"\nNote: This call can take minutes to complete if rescan is true.\n"
+ "If you have the full public key, you should call importpublickey instead of this.\n"
"\nExamples:\n"
- "\nImport an address with rescan\n"
- + HelpExampleCli("importaddress", "\"myaddress\"") +
+ "\nImport a script with rescan\n"
+ + HelpExampleCli("importaddress", "\"myscript\"") +
"\nImport using a label without rescan\n"
- + HelpExampleCli("importaddress", "\"myaddress\" \"testing\" false") +
+ + HelpExampleCli("importaddress", "\"myscript\" \"testing\" false") +
"\nAs a JSON-RPC call\n"
- + HelpExampleRpc("importaddress", "\"myaddress\", \"testing\", false")
+ + HelpExampleRpc("importaddress", "\"myscript\", \"testing\", false")
);
- if (fPruneMode)
- throw JSONRPCError(RPC_WALLET_ERROR, "Importing addresses is disabled in pruned mode");
- LOCK2(cs_main, pwalletMain->cs_wallet);
+ string strLabel = "";
+ if (params.size() > 1)
+ strLabel = params[1].get_str();
+
+ // Whether to perform rescan after import
+ bool fRescan = true;
+ if (params.size() > 2)
+ fRescan = params[2].get_bool();
+
+ if (fRescan && fPruneMode)
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode");
- CScript script;
+ // Whether to import a p2sh version, too
+ bool fP2SH = false;
+ if (params.size() > 3)
+ fP2SH = params[3].get_bool();
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
CBitcoinAddress address(params[0].get_str());
if (address.IsValid()) {
- script = GetScriptForDestination(address.Get());
+ if (fP2SH)
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead");
+ ImportAddress(address, strLabel);
} else if (IsHex(params[0].get_str())) {
std::vector<unsigned char> data(ParseHex(params[0].get_str()));
- script = CScript(data.begin(), data.end());
+ ImportScript(CScript(data.begin(), data.end()), strLabel, fP2SH);
} else {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address or script");
}
+ if (fRescan)
+ {
+ pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
+ pwalletMain->ReacceptWalletTransactions();
+ }
+
+ return NullUniValue;
+}
+
+UniValue importpubkey(const UniValue& params, bool fHelp)
+{
+ if (!EnsureWalletIsAvailable(fHelp))
+ return NullUniValue;
+
+ if (fHelp || params.size() < 1 || params.size() > 4)
+ throw runtime_error(
+ "importpubkey \"pubkey\" ( \"label\" rescan )\n"
+ "\nAdds a public key (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n"
+ "\nArguments:\n"
+ "1. \"pubkey\" (string, required) The hex-encoded public key\n"
+ "2. \"label\" (string, optional, default=\"\") An optional label\n"
+ "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n"
+ "\nNote: This call can take minutes to complete if rescan is true.\n"
+ "\nExamples:\n"
+ "\nImport a public key with rescan\n"
+ + HelpExampleCli("importpubkey", "\"mypubkey\"") +
+ "\nImport using a label without rescan\n"
+ + HelpExampleCli("importpubkey", "\"mypubkey\" \"testing\" false") +
+ "\nAs a JSON-RPC call\n"
+ + HelpExampleRpc("importpubkey", "\"mypubkey\", \"testing\", false")
+ );
+
+
string strLabel = "";
if (params.size() > 1)
strLabel = params[1].get_str();
@@ -195,33 +276,31 @@ UniValue importaddress(const UniValue& params, bool fHelp)
if (params.size() > 2)
fRescan = params[2].get_bool();
- {
- if (::IsMine(*pwalletMain, script) == ISMINE_SPENDABLE)
- throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this address or script");
-
- // add to address book or update label
- if (address.IsValid())
- pwalletMain->SetAddressBook(address.Get(), strLabel, "receive");
+ if (fRescan && fPruneMode)
+ throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode");
- // Don't throw error in case an address is already there
- if (pwalletMain->HaveWatchOnly(script))
- return NullUniValue;
+ if (!IsHex(params[0].get_str()))
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey must be a hex string");
+ std::vector<unsigned char> data(ParseHex(params[0].get_str()));
+ CPubKey pubKey(data.begin(), data.end());
+ if (!pubKey.IsFullyValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key");
- pwalletMain->MarkDirty();
+ LOCK2(cs_main, pwalletMain->cs_wallet);
- if (!pwalletMain->AddWatchOnly(script))
- throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
+ ImportAddress(CBitcoinAddress(pubKey.GetID()), strLabel);
+ ImportScript(GetScriptForRawPubKey(pubKey), strLabel, false);
- if (fRescan)
- {
- pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
- pwalletMain->ReacceptWalletTransactions();
- }
+ if (fRescan)
+ {
+ pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
+ pwalletMain->ReacceptWalletTransactions();
}
return NullUniValue;
}
+
UniValue importwallet(const UniValue& params, bool fHelp)
{
if (!EnsureWalletIsAvailable(fHelp))
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 8d88933878..30b854477b 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -5,6 +5,7 @@
#include "amount.h"
#include "base58.h"
+#include "chain.h"
#include "core_io.h"
#include "init.h"
#include "main.h"
@@ -21,7 +22,7 @@
#include <boost/assign/list_of.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -389,7 +390,7 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp)
+ HelpRequiringPassphrase() +
"\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address to send to.\n"
- "2. \"amount\" (numeric, required) The amount in btc to send. eg 0.1\n"
+ "2. \"amount\" (numeric, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n"
"3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
" This is not part of the transaction, just kept in your wallet.\n"
"4. \"comment-to\" (string, optional) A comment to store the name of the person or organization \n"
@@ -451,7 +452,7 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp)
" [\n"
" [\n"
" \"bitcoinaddress\", (string) The bitcoin address\n"
- " amount, (numeric) The amount in btc\n"
+ " amount, (numeric) The amount in " + CURRENCY_UNIT + "\n"
" \"account\" (string, optional) The account (DEPRECATED)\n"
" ]\n"
" ,...\n"
@@ -476,7 +477,6 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp)
addressInfo.push_back(CBitcoinAddress(address).ToString());
addressInfo.push_back(ValueFromAmount(balances[address]));
{
- LOCK(pwalletMain->cs_wallet);
if (pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get()) != pwalletMain->mapAddressBook.end())
addressInfo.push_back(pwalletMain->mapAddressBook.find(CBitcoinAddress(address).Get())->second.name);
}
@@ -556,7 +556,7 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp)
"1. \"bitcoinaddress\" (string, required) The bitcoin address for transactions.\n"
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
"\nResult:\n"
- "amount (numeric) The total amount in btc received at this address.\n"
+ "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n"
"\nExamples:\n"
"\nThe amount from transactions with at least 1 confirmation\n"
+ HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") +
@@ -614,7 +614,7 @@ UniValue getreceivedbyaccount(const UniValue& params, bool fHelp)
"1. \"account\" (string, required) The selected account, may be the default account using \"\".\n"
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
"\nResult:\n"
- "amount (numeric) The total amount in btc received for this account.\n"
+ "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
"\nExamples:\n"
"\nAmount received by the default account with at least 1 confirmation\n"
+ HelpExampleCli("getreceivedbyaccount", "\"\"") +
@@ -707,7 +707,7 @@ UniValue getbalance(const UniValue& params, bool fHelp)
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
"3. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n"
"\nResult:\n"
- "amount (numeric) The total amount in btc received for this account.\n"
+ "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
"\nExamples:\n"
"\nThe total amount in the wallet\n"
+ HelpExampleCli("getbalance", "") +
@@ -793,14 +793,15 @@ UniValue movecmd(const UniValue& params, bool fHelp)
"\nArguments:\n"
"1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n"
"2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n"
- "3. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
- "4. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
+ "3. amount (numeric) Quantity of " + CURRENCY_UNIT + " to move between accounts.\n"
+ "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
+ "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
"\nResult:\n"
- "true|false (boolean) true if successfull.\n"
+ "true|false (boolean) true if successful.\n"
"\nExamples:\n"
- "\nMove 0.01 btc from the default account to the account named tabby\n"
+ "\nMove 0.01 " + CURRENCY_UNIT + " from the default account to the account named tabby\n"
+ HelpExampleCli("move", "\"\" \"tabby\" 0.01") +
- "\nMove 0.01 btc timotei to akiko with a comment and funds have 6 confirmations\n"
+ "\nMove 0.01 " + CURRENCY_UNIT + " timotei to akiko with a comment and funds have 6 confirmations\n"
+ HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") +
"\nAs a json rpc call\n"
+ HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
@@ -867,7 +868,7 @@ UniValue sendfrom(const UniValue& params, bool fHelp)
"\nArguments:\n"
"1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n"
"2. \"tobitcoinaddress\" (string, required) The bitcoin address to send funds to.\n"
- "3. amount (numeric, required) The amount in btc. (transaction fee is added on top).\n"
+ "3. amount (numeric, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n"
"4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
"5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
" This is not part of the transaction, just kept in your wallet.\n"
@@ -877,7 +878,7 @@ UniValue sendfrom(const UniValue& params, bool fHelp)
"\nResult:\n"
"\"transactionid\" (string) The transaction id.\n"
"\nExamples:\n"
- "\nSend 0.01 btc from the default account to the address, must have at least 1 confirmation\n"
+ "\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n"
+ HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") +
"\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n"
+ HelpExampleCli("sendfrom", "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") +
@@ -932,7 +933,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 btc is the value\n"
+ " \"address\":amount (numeric) The bitcoin address is the key, the numeric amount in " + CURRENCY_UNIT + " is the value\n"
" ,...\n"
" }\n"
"3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
@@ -1233,7 +1234,7 @@ UniValue listreceivedbyaddress(const UniValue& params, bool fHelp)
" \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
" \"address\" : \"receivingaddress\", (string) The receiving address\n"
" \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n"
- " \"amount\" : x.xxx, (numeric) The total amount in btc received by the address\n"
+ " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n"
" \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n"
" }\n"
" ,...\n"
@@ -1405,11 +1406,11 @@ UniValue listtransactions(const UniValue& params, bool fHelp)
" transaction between accounts, and not associated with an address,\n"
" transaction id or block. 'send' and 'receive' transactions are \n"
" associated with an address, transaction id and block details\n"
- " \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the\n"
+ " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n"
" 'move' category for moves outbound. It is positive for the 'receive' category,\n"
" and for the 'move' category for inbound funds.\n"
" \"vout\" : n, (numeric) the vout value\n"
- " \"fee\": x.xxx, (numeric) The amount of the fee in btc. This is negative and only available for the \n"
+ " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
" 'send' category of transactions.\n"
" \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n"
" 'receive' category of transactions.\n"
@@ -1600,10 +1601,10 @@ UniValue listsinceblock(const UniValue& params, bool fHelp)
" \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
" \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n"
" \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
- " \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the 'move' category for moves \n"
+ " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n"
" outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
" \"vout\" : n, (numeric) the vout value\n"
- " \"fee\": x.xxx, (numeric) The amount of the fee in btc. This is negative and only available for the 'send' category of transactions.\n"
+ " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the 'send' category of transactions.\n"
" \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
" \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
" \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
@@ -1686,7 +1687,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp)
"2. \"includeWatchonly\" (bool, optional, default=false) Whether to include watchonly addresses in balance calculation and details[]\n"
"\nResult:\n"
"{\n"
- " \"amount\" : x.xxx, (numeric) The transaction amount in btc\n"
+ " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n"
" \"confirmations\" : n, (numeric) The number of confirmations\n"
" \"blockhash\" : \"hash\", (string) The block hash\n"
" \"blockindex\" : xx, (numeric) The block index\n"
@@ -1699,7 +1700,7 @@ 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 btc\n"
+ " \"amount\" : x.xxx (numeric) The amount in " + CURRENCY_UNIT + "\n"
" \"vout\" : n, (numeric) the vout value\n"
" }\n"
" ,...\n"
@@ -2165,7 +2166,7 @@ UniValue settxfee(const UniValue& params, bool fHelp)
"settxfee amount\n"
"\nSet the transaction fee per kB.\n"
"\nArguments:\n"
- "1. amount (numeric, required) The transaction fee in BTC/kB rounded to the nearest 0.00000001\n"
+ "1. amount (numeric, required) The transaction fee in " + CURRENCY_UNIT + "/kB rounded to the nearest 0.00000001\n"
"\nResult\n"
"true|false (boolean) Returns true if successful\n"
"\nExamples:\n"
@@ -2194,14 +2195,14 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp)
"\nResult:\n"
"{\n"
" \"walletversion\": xxxxx, (numeric) the wallet version\n"
- " \"balance\": xxxxxxx, (numeric) the total confirmed bitcoin balance of the wallet\n"
- " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed bitcoin balance of the wallet\n"
- " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet\n"
+ " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
+ " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
+ " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n"
" \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n"
" \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
" \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
" \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n"
- " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in btc/kb\n"
+ " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("getwalletinfo", "")
@@ -2278,7 +2279,7 @@ UniValue listunspent(const UniValue& params, bool fHelp)
" \"address\" : \"address\", (string) the bitcoin address\n"
" \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
" \"scriptPubKey\" : \"key\", (string) the script key\n"
- " \"amount\" : x.xxx, (numeric) the transaction amount in btc\n"
+ " \"amount\" : x.xxx, (numeric) the transaction amount in " + CURRENCY_UNIT + "\n"
" \"confirmations\" : n (numeric) The number of confirmations\n"
" }\n"
" ,...\n"
@@ -2367,15 +2368,20 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
if (!EnsureWalletIsAvailable(fHelp))
return NullUniValue;
- if (fHelp || params.size() != 1)
+ if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
- "fundrawtransaction \"hexstring\"\n"
+ "fundrawtransaction \"hexstring\" includeWatching\n"
"\nAdd inputs to a transaction until it has enough in value to meet its out value.\n"
"This will not modify existing inputs, and will add one change output to the outputs.\n"
"Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
"The inputs added will not be signed, use signrawtransaction for that.\n"
+ "Note that all existing inputs must have their previous output transaction be in the wallet.\n"
+ "Note that all inputs selected must be of standard form and P2SH scripts must be"
+ "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n"
+ "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n"
"\nArguments:\n"
- "1. \"hexstring\" (string, required) The hex string of the raw transaction\n"
+ "1. \"hexstring\" (string, required) The hex string of the raw transaction\n"
+ "2. includeWatching (boolean, optional, default false) Also select inputs which are watch only\n"
"\nResult:\n"
"{\n"
" \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n"
@@ -2394,18 +2400,22 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
+ HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"")
);
- RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
+ RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL));
// parse hex string from parameter
CTransaction origTx;
if (!DecodeHexTx(origTx, params[0].get_str()))
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
+ bool includeWatching = false;
+ if (params.size() > 1)
+ includeWatching = true;
+
CMutableTransaction tx(origTx);
CAmount nFee;
string strFailReason;
int nChangePos = -1;
- if(!pwalletMain->FundTransaction(tx, nFee, nChangePos, strFailReason))
+ if(!pwalletMain->FundTransaction(tx, nFee, nChangePos, strFailReason, includeWatching))
throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
UniValue result(UniValue::VOBJ);
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 7b3cd9803b..3f2d5a05f6 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -7,15 +7,21 @@
#include "base58.h"
#include "checkpoints.h"
+#include "chain.h"
#include "coincontrol.h"
#include "consensus/consensus.h"
#include "consensus/validation.h"
+#include "key.h"
+#include "keystore.h"
#include "main.h"
#include "net.h"
#include "policy/policy.h"
+#include "primitives/block.h"
+#include "primitives/transaction.h"
#include "script/script.h"
#include "script/sign.h"
#include "timedata.h"
+#include "txmempool.h"
#include "util.h"
#include "utilmoneystr.h"
@@ -108,6 +114,9 @@ bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
script = GetScriptForDestination(pubkey.GetID());
if (HaveWatchOnly(script))
RemoveWatchOnly(script);
+ script = GetScriptForRawPubKey(pubkey);
+ if (HaveWatchOnly(script))
+ RemoveWatchOnly(script);
if (!fFileBacked)
return true;
@@ -693,9 +702,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD
wtx.hashBlock = wtxIn.hashBlock;
fUpdated = true;
}
- if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
+ if (wtxIn.nIndex != -1 && (wtxIn.nIndex != wtx.nIndex))
{
- wtx.vMerkleBranch = wtxIn.vMerkleBranch;
wtx.nIndex = wtxIn.nIndex;
fUpdated = true;
}
@@ -1521,7 +1529,9 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const
if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
!IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) &&
(!coinControl || !coinControl->HasSelected() || coinControl->fAllowOtherInputs || coinControl->IsSelected((*it).first, i)))
- vCoins.push_back(COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO));
+ vCoins.push_back(COutput(pcoin, i, nDepth,
+ ((mine & ISMINE_SPENDABLE) != ISMINE_NO) ||
+ (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO)));
}
}
}
@@ -1737,7 +1747,7 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*
return res;
}
-bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason)
+bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching)
{
vector<CRecipient> vecSend;
@@ -1750,6 +1760,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nC
CCoinControl coinControl;
coinControl.fAllowOtherInputs = true;
+ coinControl.fAllowWatchOnly = includeWatching;
BOOST_FOREACH(const CTxIn& txin, tx.vin)
coinControl.Select(txin.prevout);
@@ -1841,9 +1852,9 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
nChangePosRet = -1;
bool fFirst = true;
- CAmount nTotalValue = nValue;
+ CAmount nValueToSelect = nValue;
if (nSubtractFeeFromAmount == 0)
- nTotalValue += nFeeRet;
+ nValueToSelect += nFeeRet;
double dPriority = 0;
// vouts to the payees
BOOST_FOREACH (const CRecipient& recipient, vecSend)
@@ -1880,7 +1891,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
// Choose coins to use
set<pair<const CWalletTx*,unsigned int> > setCoins;
CAmount nValueIn = 0;
- if (!SelectCoins(nTotalValue, setCoins, nValueIn, coinControl))
+ if (!SelectCoins(nValueToSelect, setCoins, nValueIn, coinControl))
{
strFailReason = _("Insufficient funds");
return false;
@@ -1898,10 +1909,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
dPriority += (double)nCredit * age;
}
- CAmount nChange = nValueIn - nValue;
- if (nSubtractFeeFromAmount == 0)
- nChange -= nFeeRet;
-
+ const CAmount nChange = nValueIn - nValueToSelect;
if (nChange > 0)
{
// Fill a vout to ourself
@@ -2103,7 +2111,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
if (!wtxNew.AcceptToMemoryPool(false))
{
// This must not fail. The transaction has already been signed and recorded.
- LogPrintf("CommitTransaction(): Error: Transaction not valid");
+ LogPrintf("CommitTransaction(): Error: Transaction not valid\n");
return false;
}
wtxNew.RelayWalletTransaction();
@@ -2800,15 +2808,11 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block)
break;
if (nIndex == (int)block.vtx.size())
{
- vMerkleBranch.clear();
nIndex = -1;
LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n");
return 0;
}
- // Fill in merkle branch
- vMerkleBranch = block.GetMerkleBranch(nIndex);
-
// Is the tx in a block that's in the main chain
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
if (mi == mapBlockIndex.end())
@@ -2834,14 +2838,6 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
if (!pindex || !chainActive.Contains(pindex))
return 0;
- // Make sure the merkle branch connects to this block
- if (!fMerkleVerified)
- {
- if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
- return 0;
- fMerkleVerified = true;
- }
-
pindexRet = pindex;
return chainActive.Height() - pindex->nHeight + 1;
}
@@ -2867,6 +2863,6 @@ 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 003266ba19..34e98cfb81 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -7,10 +7,7 @@
#define BITCOIN_WALLET_WALLET_H
#include "amount.h"
-#include "key.h"
-#include "keystore.h"
-#include "primitives/block.h"
-#include "primitives/transaction.h"
+#include "streams.h"
#include "tinyformat.h"
#include "ui_interface.h"
#include "utilstrencodings.h"
@@ -154,13 +151,8 @@ private:
public:
uint256 hashBlock;
- std::vector<uint256> vMerkleBranch;
int nIndex;
- // memory only
- mutable bool fMerkleVerified;
-
-
CMerkleTx()
{
Init();
@@ -175,13 +167,13 @@ public:
{
hashBlock = uint256();
nIndex = -1;
- fMerkleVerified = false;
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ std::vector<uint256> vMerkleBranch; // For compatibility with older versions.
READWRITE(*(CTransaction*)this);
nVersion = this->nVersion;
READWRITE(hashBlock);
@@ -630,7 +622,7 @@ public:
CAmount GetWatchOnlyBalance() const;
CAmount GetUnconfirmedWatchOnlyBalance() const;
CAmount GetImmatureWatchOnlyBalance() const;
- bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason);
+ bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching);
bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet,
std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true);
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
diff --git a/src/wallet/wallet_ismine.cpp b/src/wallet/wallet_ismine.cpp
index 5482348e35..d27b1531e3 100644
--- a/src/wallet/wallet_ismine.cpp
+++ b/src/wallet/wallet_ismine.cpp
@@ -9,6 +9,7 @@
#include "keystore.h"
#include "script/script.h"
#include "script/standard.h"
+#include "script/sign.h"
#include <boost/foreach.hpp>
@@ -40,7 +41,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
txnouttype whichType;
if (!Solver(scriptPubKey, whichType, vSolutions)) {
if (keystore.HaveWatchOnly(scriptPubKey))
- return ISMINE_WATCH_ONLY;
+ return ISMINE_WATCH_UNSOLVABLE;
return ISMINE_NO;
}
@@ -85,7 +86,10 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
}
}
- if (keystore.HaveWatchOnly(scriptPubKey))
- return ISMINE_WATCH_ONLY;
+ if (keystore.HaveWatchOnly(scriptPubKey)) {
+ // TODO: This could be optimized some by doing some work after the above solver
+ CScript scriptSig;
+ return ProduceSignature(DummySignatureCreator(&keystore), scriptPubKey, scriptSig) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE;
+ }
return ISMINE_NO;
}
diff --git a/src/wallet/wallet_ismine.h b/src/wallet/wallet_ismine.h
index 5b9b0e0841..9f45f76c6b 100644
--- a/src/wallet/wallet_ismine.h
+++ b/src/wallet/wallet_ismine.h
@@ -6,9 +6,10 @@
#ifndef BITCOIN_WALLET_WALLET_ISMINE_H
#define BITCOIN_WALLET_WALLET_ISMINE_H
-#include "key.h"
#include "script/standard.h"
+#include <stdint.h>
+
class CKeyStore;
class CScript;
@@ -16,8 +17,12 @@ class CScript;
enum isminetype
{
ISMINE_NO = 0,
- ISMINE_WATCH_ONLY = 1,
- ISMINE_SPENDABLE = 2,
+ //! Indicates that we dont know how to create a scriptSig that would solve this if we were given the appropriate private keys
+ ISMINE_WATCH_UNSOLVABLE = 1,
+ //! Indicates that we know how to create a scriptSig that would solve this if we were given the appropriate private keys
+ ISMINE_WATCH_SOLVABLE = 2,
+ ISMINE_WATCH_ONLY = ISMINE_WATCH_SOLVABLE | ISMINE_WATCH_UNSOLVABLE,
+ ISMINE_SPENDABLE = 4,
ISMINE_ALL = ISMINE_WATCH_ONLY | ISMINE_SPENDABLE
};
/** used for bitflags of isminetype */
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index f777926e72..0624e442d1 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -7,7 +7,7 @@
#include "base58.h"
#include "consensus/validation.h"
-#include "main.h"
+#include "main.h" // For CheckTransaction
#include "protocol.h"
#include "serialize.h"
#include "sync.h"
@@ -131,12 +131,14 @@ bool CWalletDB::EraseWatchOnly(const CScript &dest)
bool CWalletDB::WriteBestBlock(const CBlockLocator& locator)
{
nWalletDBUpdated++;
- return Write(std::string("bestblock"), locator);
+ Write(std::string("bestblock"), CBlockLocator()); // Write empty block locator so versions that require a merkle branch automatically rescan
+ return Write(std::string("bestblock_nomerkle"), locator);
}
bool CWalletDB::ReadBestBlock(CBlockLocator& locator)
{
- return Read(std::string("bestblock"), locator);
+ if (Read(std::string("bestblock"), locator) && !locator.vHave.empty()) return true;
+ return Read(std::string("bestblock_nomerkle"), locator);
}
bool CWalletDB::WriteOrderPosNext(int64_t nOrderPosNext)
diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h
index bc1a104b5b..270f826aed 100644
--- a/src/wallet/walletdb.h
+++ b/src/wallet/walletdb.h
@@ -9,7 +9,6 @@
#include "amount.h"
#include "wallet/db.h"
#include "key.h"
-#include "keystore.h"
#include <list>
#include <stdint.h>
diff --git a/src/zmq/zmqabstractnotifier.cpp b/src/zmq/zmqabstractnotifier.cpp
new file mode 100644
index 0000000000..9f5cb3ba67
--- /dev/null
+++ b/src/zmq/zmqabstractnotifier.cpp
@@ -0,0 +1,22 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "zmqabstractnotifier.h"
+#include "util.h"
+
+
+CZMQAbstractNotifier::~CZMQAbstractNotifier()
+{
+ assert(!psocket);
+}
+
+bool CZMQAbstractNotifier::NotifyBlock(const CBlockIndex * /*CBlockIndex*/)
+{
+ return true;
+}
+
+bool CZMQAbstractNotifier::NotifyTransaction(const CTransaction &/*transaction*/)
+{
+ return true;
+}
diff --git a/src/zmq/zmqabstractnotifier.h b/src/zmq/zmqabstractnotifier.h
new file mode 100644
index 0000000000..77cf5141e2
--- /dev/null
+++ b/src/zmq/zmqabstractnotifier.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H
+#define BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H
+
+#include "zmqconfig.h"
+
+class CBlockIndex;
+class CZMQAbstractNotifier;
+
+typedef CZMQAbstractNotifier* (*CZMQNotifierFactory)();
+
+class CZMQAbstractNotifier
+{
+public:
+ CZMQAbstractNotifier() : psocket(0) { }
+ virtual ~CZMQAbstractNotifier();
+
+ template <typename T>
+ static CZMQAbstractNotifier* Create()
+ {
+ return new T();
+ }
+
+ std::string GetType() const { return type; }
+ void SetType(const std::string &t) { type = t; }
+ std::string GetAddress() const { return address; }
+ void SetAddress(const std::string &a) { address = a; }
+
+ virtual bool Initialize(void *pcontext) = 0;
+ virtual void Shutdown() = 0;
+
+ virtual bool NotifyBlock(const CBlockIndex *pindex);
+ virtual bool NotifyTransaction(const CTransaction &transaction);
+
+protected:
+ void *psocket;
+ std::string type;
+ std::string address;
+};
+
+#endif // BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H
diff --git a/src/zmq/zmqconfig.h b/src/zmq/zmqconfig.h
new file mode 100644
index 0000000000..6057f5d1a0
--- /dev/null
+++ b/src/zmq/zmqconfig.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_ZMQ_ZMQCONFIG_H
+#define BITCOIN_ZMQ_ZMQCONFIG_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <stdarg.h>
+#include <string>
+
+#if ENABLE_ZMQ
+#include <zmq.h>
+#endif
+
+#include "primitives/block.h"
+#include "primitives/transaction.h"
+
+void zmqError(const char *str);
+
+#endif // BITCOIN_ZMQ_ZMQCONFIG_H
diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp
new file mode 100644
index 0000000000..388b86707b
--- /dev/null
+++ b/src/zmq/zmqnotificationinterface.cpp
@@ -0,0 +1,155 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "zmqnotificationinterface.h"
+#include "zmqpublishnotifier.h"
+
+#include "version.h"
+#include "main.h"
+#include "streams.h"
+#include "util.h"
+
+void zmqError(const char *str)
+{
+ LogPrint("zmq", "Error: %s, errno=%s\n", str, zmq_strerror(errno));
+}
+
+CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL)
+{
+}
+
+CZMQNotificationInterface::~CZMQNotificationInterface()
+{
+ // ensure Shutdown if Initialize is called
+ assert(!pcontext);
+
+ for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i)
+ {
+ delete *i;
+ }
+}
+
+CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const std::map<std::string, std::string> &args)
+{
+ CZMQNotificationInterface* notificationInterface = NULL;
+ std::map<std::string, CZMQNotifierFactory> factories;
+ std::list<CZMQAbstractNotifier*> notifiers;
+
+ factories["pubhashblock"] = CZMQAbstractNotifier::Create<CZMQPublishHashBlockNotifier>;
+ factories["pubhashtx"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionNotifier>;
+ factories["pubrawblock"] = CZMQAbstractNotifier::Create<CZMQPublishRawBlockNotifier>;
+ factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>;
+
+ for (std::map<std::string, CZMQNotifierFactory>::const_iterator i=factories.begin(); i!=factories.end(); ++i)
+ {
+ std::map<std::string, std::string>::const_iterator j = args.find("-zmq" + i->first);
+ if (j!=args.end())
+ {
+ CZMQNotifierFactory factory = i->second;
+ std::string address = j->second;
+ CZMQAbstractNotifier *notifier = factory();
+ notifier->SetType(i->first);
+ notifier->SetAddress(address);
+ notifiers.push_back(notifier);
+ }
+ }
+
+ if (!notifiers.empty())
+ {
+ notificationInterface = new CZMQNotificationInterface();
+ notificationInterface->notifiers = notifiers;
+ }
+
+ return notificationInterface;
+}
+
+// Called at startup to conditionally set up ZMQ socket(s)
+bool CZMQNotificationInterface::Initialize()
+{
+ LogPrint("zmq", "Initialize notification interface\n");
+ assert(!pcontext);
+
+ pcontext = zmq_init(1);
+
+ if (!pcontext)
+ {
+ zmqError("Unable to initialize context");
+ return false;
+ }
+
+ std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin();
+ for (; i!=notifiers.end(); ++i)
+ {
+ CZMQAbstractNotifier *notifier = *i;
+ if (notifier->Initialize(pcontext))
+ {
+ LogPrint("zmq", " Notifier %s ready (address = %s)\n", notifier->GetType(), notifier->GetAddress());
+ }
+ else
+ {
+ LogPrint("zmq", " Notifier %s failed (address = %s)\n", notifier->GetType(), notifier->GetAddress());
+ break;
+ }
+ }
+
+ if (i!=notifiers.end())
+ {
+ Shutdown();
+ return false;
+ }
+
+ return false;
+}
+
+// Called during shutdown sequence
+void CZMQNotificationInterface::Shutdown()
+{
+ LogPrint("zmq", "Shutdown notification interface\n");
+ if (pcontext)
+ {
+ for (std::list<CZMQAbstractNotifier*>::iterator i=notifiers.begin(); i!=notifiers.end(); ++i)
+ {
+ CZMQAbstractNotifier *notifier = *i;
+ LogPrint("zmq", " Shutdown notifier %s at %s\n", notifier->GetType(), notifier->GetAddress());
+ notifier->Shutdown();
+ }
+ zmq_ctx_destroy(pcontext);
+
+ pcontext = 0;
+ }
+}
+
+void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindex)
+{
+ for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )
+ {
+ CZMQAbstractNotifier *notifier = *i;
+ if (notifier->NotifyBlock(pindex))
+ {
+ i++;
+ }
+ else
+ {
+ notifier->Shutdown();
+ i = notifiers.erase(i);
+ }
+ }
+}
+
+void CZMQNotificationInterface::SyncTransaction(const CTransaction &tx, const CBlock *pblock)
+{
+ for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )
+ {
+ CZMQAbstractNotifier *notifier = *i;
+ if (notifier->NotifyTransaction(tx))
+ {
+ i++;
+ }
+ else
+ {
+ notifier->Shutdown();
+ i = notifiers.erase(i);
+ }
+ }
+}
diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h
new file mode 100644
index 0000000000..8eea15c068
--- /dev/null
+++ b/src/zmq/zmqnotificationinterface.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H
+#define BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H
+
+#include "validationinterface.h"
+#include <string>
+#include <map>
+
+class CBlockIndex;
+class CZMQAbstractNotifier;
+
+class CZMQNotificationInterface : public CValidationInterface
+{
+public:
+ virtual ~CZMQNotificationInterface();
+
+ static CZMQNotificationInterface* CreateWithArguments(const std::map<std::string, std::string> &args);
+
+ bool Initialize();
+ void Shutdown();
+
+protected: // CValidationInterface
+ void SyncTransaction(const CTransaction &tx, const CBlock *pblock);
+ void UpdatedBlockTip(const CBlockIndex *pindex);
+
+private:
+ CZMQNotificationInterface();
+
+ void *pcontext;
+ std::list<CZMQAbstractNotifier*> notifiers;
+};
+
+#endif // BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H
diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp
new file mode 100644
index 0000000000..4c3eb8f2d9
--- /dev/null
+++ b/src/zmq/zmqpublishnotifier.cpp
@@ -0,0 +1,170 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "zmqpublishnotifier.h"
+#include "main.h"
+#include "util.h"
+
+static std::multimap<std::string, CZMQAbstractPublishNotifier*> mapPublishNotifiers;
+
+// Internal function to send multipart message
+static int zmq_send_multipart(void *sock, const void* data, size_t size, ...)
+{
+ va_list args;
+ va_start(args, size);
+
+ while (1)
+ {
+ zmq_msg_t msg;
+
+ int rc = zmq_msg_init_size(&msg, size);
+ if (rc != 0)
+ {
+ zmqError("Unable to initialize ZMQ msg");
+ return -1;
+ }
+
+ void *buf = zmq_msg_data(&msg);
+ memcpy(buf, data, size);
+
+ data = va_arg(args, const void*);
+
+ rc = zmq_msg_send(&msg, sock, data ? ZMQ_SNDMORE : 0);
+ if (rc == -1)
+ {
+ zmqError("Unable to send ZMQ msg");
+ zmq_msg_close(&msg);
+ return -1;
+ }
+
+ zmq_msg_close(&msg);
+
+ if (!data)
+ break;
+
+ size = va_arg(args, size_t);
+ }
+ return 0;
+}
+
+bool CZMQAbstractPublishNotifier::Initialize(void *pcontext)
+{
+ assert(!psocket);
+
+ // check if address is being used by other publish notifier
+ std::multimap<std::string, CZMQAbstractPublishNotifier*>::iterator i = mapPublishNotifiers.find(address);
+
+ if (i==mapPublishNotifiers.end())
+ {
+ psocket = zmq_socket(pcontext, ZMQ_PUB);
+ if (!psocket)
+ {
+ zmqError("Failed to create socket");
+ return false;
+ }
+
+ int rc = zmq_bind(psocket, address.c_str());
+ if (rc!=0)
+ {
+ zmqError("Failed to bind address");
+ return false;
+ }
+
+ // register this notifier for the address, so it can be reused for other publish notifier
+ mapPublishNotifiers.insert(std::make_pair(address, this));
+ return true;
+ }
+ else
+ {
+ LogPrint("zmq", " Reuse socket for address %s\n", address);
+
+ psocket = i->second->psocket;
+ mapPublishNotifiers.insert(std::make_pair(address, this));
+
+ return true;
+ }
+}
+
+void CZMQAbstractPublishNotifier::Shutdown()
+{
+ assert(psocket);
+
+ int count = mapPublishNotifiers.count(address);
+
+ // remove this notifier from the list of publishers using this address
+ typedef std::multimap<std::string, CZMQAbstractPublishNotifier*>::iterator iterator;
+ std::pair<iterator, iterator> iterpair = mapPublishNotifiers.equal_range(address);
+
+ for (iterator it = iterpair.first; it != iterpair.second; ++it)
+ {
+ if (it->second==this)
+ {
+ mapPublishNotifiers.erase(it);
+ break;
+ }
+ }
+
+ if (count == 1)
+ {
+ LogPrint("zmq", "Close socket at address %s\n", address);
+ int linger = 0;
+ zmq_setsockopt(psocket, ZMQ_LINGER, &linger, sizeof(linger));
+ zmq_close(psocket);
+ }
+
+ psocket = 0;
+}
+
+bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
+{
+ uint256 hash = pindex->GetBlockHash();
+ LogPrint("zmq", "Publish hash block %s\n", hash.GetHex());
+ char data[32];
+ for (unsigned int i = 0; i < 32; i++)
+ data[31 - i] = hash.begin()[i];
+ int rc = zmq_send_multipart(psocket, "hashblock", 9, data, 32, 0);
+ return rc == 0;
+}
+
+bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction)
+{
+ uint256 hash = transaction.GetHash();
+ LogPrint("zmq", "Publish hash transaction %s\n", hash.GetHex());
+ char data[32];
+ for (unsigned int i = 0; i < 32; i++)
+ data[31 - i] = hash.begin()[i];
+ int rc = zmq_send_multipart(psocket, "hashtx", 6, data, 32, 0);
+ return rc == 0;
+}
+
+bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
+{
+ LogPrint("zmq", "Publish raw block %s\n", pindex->GetBlockHash().GetHex());
+
+ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
+ {
+ LOCK(cs_main);
+ CBlock block;
+ if(!ReadBlockFromDisk(block, pindex))
+ {
+ zmqError("Can't read block from disk");
+ return false;
+ }
+
+ ss << block;
+ }
+
+ int rc = zmq_send_multipart(psocket, "rawblock", 8, &(*ss.begin()), ss.size(), 0);
+ return rc == 0;
+}
+
+bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction)
+{
+ uint256 hash = transaction.GetHash();
+ LogPrint("zmq", "Publish raw transaction %s\n", hash.GetHex());
+ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
+ ss << transaction;
+ int rc = zmq_send_multipart(psocket, "rawtx", 5, &(*ss.begin()), ss.size(), 0);
+ return rc == 0;
+}
diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h
new file mode 100644
index 0000000000..44d5cbea67
--- /dev/null
+++ b/src/zmq/zmqpublishnotifier.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H
+#define BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H
+
+#include "zmqabstractnotifier.h"
+
+class CBlockIndex;
+
+class CZMQAbstractPublishNotifier : public CZMQAbstractNotifier
+{
+public:
+ bool Initialize(void *pcontext);
+ void Shutdown();
+};
+
+class CZMQPublishHashBlockNotifier : public CZMQAbstractPublishNotifier
+{
+public:
+ bool NotifyBlock(const CBlockIndex *pindex);
+};
+
+class CZMQPublishHashTransactionNotifier : public CZMQAbstractPublishNotifier
+{
+public:
+ bool NotifyTransaction(const CTransaction &transaction);
+};
+
+class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier
+{
+public:
+ bool NotifyBlock(const CBlockIndex *pindex);
+};
+
+class CZMQPublishRawTransactionNotifier : public CZMQAbstractPublishNotifier
+{
+public:
+ bool NotifyTransaction(const CTransaction &transaction);
+};
+
+#endif // BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H